Skip to content

Message API - Update

Use this endpoint to change a draft message: its settings, its recipients, or its HTML.


PATCH https://e1.envoke.com/v2/messages/{ID}

Replace {ID} with the Envoke message ID. Authentication is via HTTP Basic Auth using your API ID and API Key. The request body must be a single JSON object. There is no endpoint for updating several messages in one request.


Send only the fields you want to change. Fields you leave out keep their current values, with one exception: the recipient fields are replaced as a set (see Recipients).

Field Type Description
name string Internal name. At least 3 characters.
group string Name or ID of an existing message group. "" removes the group.
subject string Subject line. At least 6 characters.
sender string Identity ID, Name <email>, or email address. "" clears it.
reply_to string Identity ID, Name <email>, or email address. "" clears it.
language string en or fr. "" sets en.
recipient_subscription string Name or ID of a subscription. "" clears it.
recipient_tag string Name or ID of a tag. Not with recipient_segment. "" clears it.
recipient_segment string Name or ID of a segment. Not with recipient_tag. "" clears it.
recipient_language string en or fr. "" clears it (all languages).
publish_archive boolean Publish the message to the web archive.
utm_tag_links boolean Add UTM parameters to links.
send_time string A future account-local time. Stored only; it does not schedule the message.
html string New HTML for the message, replacing all of its content. Max 200 kB.
replace object Placeholder text to replace in the html sent in the same request.
id string or integer Optional. If sent, it must match {ID} (see ID Mismatch).

external_id, preview_url, create_time, modified_time, and status are read-only and silently ignored. A message object returned by a GET can be edited and sent back only after removing a null sender or reply_to, an empty send_time, and an empty subject, which would otherwise fail validation (see the Fields reference). template_id cannot be used on update. Any other key fails with 'headline' is not a valid field. See the Fields reference for accepted values and the full rules for each field.

Every successful update sets modified_time, even when no value changed.


A message can be updated only while its status is Draft. Any other status fails with:

{
"success": false,
"result_text": "Validation failed, see 'result_data' -> 'errors'",
"result_data": {
"errors": ["Only 'Draft' messages can be updated, this message has the status: 'Scheduled'"]
}
}

To change a scheduled message, cancel it first, which returns it to Draft, then update it and send it again. Sent, nurture, and transactional messages cannot be changed through the API.


recipient_subscription, recipient_tag, and recipient_segment are treated as one setting. When a request includes any one of them, the other two are cleared unless they are also in the request.

Current recipients Request Result
Subscription Season News {"recipient_tag": "Cast Call"} Tag Cast Call only; the subscription is removed.
Subscription Season News {"recipient_subscription": "Season News", "recipient_tag": "Cast Call"} Contacts with Cast Call who are subscribed to Season News.
Subscription and tag {"recipient_subscription": ""} No recipients.
Tag Cast Call {"recipient_segment": "Lapsed Subscribers"} Segment Lapsed Subscribers only.
Any {"subject": "New subject line"} Unchanged.

recipient_tag and recipient_segment cannot both be set: Only one of the fields 'recipient_tag' or 'recipient_segment' may be provided. recipient_language is a separate setting and is never cleared by this rule. See Recipients for how the fields combine when the message is sent.


Sending html replaces the whole content of the message. There is no way to change part of the HTML in place; read the current HTML with GET /v2/messages/{ID}?include_html=1, change it, and send it back.

replace works on update only together with html in the same request. The replacements are made in the HTML you send, and the result is saved. Without html, the request fails with The field 'html' is required for content 'replace' data; a replacement cannot be run over the HTML the message already has.

{
"html": "<html><body><h1>{SHOW_TITLE}</h1><p>Curtain at {CURTAIN_TIME}.</p></body></html>",
"replace": { "{SHOW_TITLE}": "The Pirates of Penzance", "{CURTAIN_TIME}": "8:00 p.m." }
}

template_id is not accepted: The field 'template_id' is not valid for updating a message. To switch a draft to a template’s HTML, read the template with the Template API and send its HTML as html.


Field To clear Notes
group "" or "0" The message has no group.
sender "" or "0" No fallback to the default sender. The message cannot be sent until a sender is set again.
reply_to "" or "0"
recipient_subscription, recipient_tag, recipient_segment "" or "0" Clearing one clears all three (see Recipients).
recipient_language "" or "0" Sends to all languages.
language — "" or "0" sets en.
name, subject — Cannot be cleared; "" fails the minimum-length check.
html — Cannot be cleared; "" is ignored.
send_time — Cannot be cleared once set (see Dates and time zones).

Use the string "0", not the number 0: a JSON number 0 fails as an invalid value, e.g. Invalid 'group': '0'.


If the body includes id and it differs from {ID}, the request fails with a plain envelope, not the validation envelope:

{
"success": false,
"result_data": [],
"result_text": "Provided 'id': 2001 does not match 'id' in request body (2002)"
}

"2001" and 2001 count as the same. The same rule and message apply to POST /v2/messages/{ID}/send and POST /v2/messages/{ID}/cancel.


On success, the API returns the updated message in full, in the same shape as a read:

{
"success": true,
"result_text": "Updated",
"result_data": {
"id": "2002",
"name": "Auditions Open",
"status": "Draft",
"subject": "Auditions start Monday at 7",
"recipient_subscription": "",
"recipient_tag": "Cast Call",
"recipient_segment": "",
"modified_time": "2026-10-06 11:30:17"
}
}

(result_data shortened; the response contains every field.)

result_data.id is a string. The HTML is not included.


{
"success": false,
"result_text": "Validation failed, see 'result_data' -> 'errors'",
"result_data": {
"errors": [
"No message found for 'id': 2099"
]
}
}

The checks run in the order below. Each of the first six returns on its own; the field checks are then collected and returned together, before the replace checks.

Error Cause
Request body may not be empty No body, an empty body, or {}.
No message found for 'id': 2099 No message with that ID in your account. Deleted messages and templates are not found.
Only 'Draft' messages can be updated, this message has the status: 'Sent' The message is not a draft.
The field 'template_id' is not valid for updating a message template_id was sent.
The field 'html' may not be longer than 200kB html is over 204,800 bytes.
Only one of the fields 'recipient_tag' or 'recipient_segment' may be provided Both were sent with values.
Field errors 'headline' is not a valid field, the name and subject length errors, unknown lookup values with allowed_values, and the send_time errors, as listed for create.
The field 'html' is required for content 'replace' data replace was sent without html.
Invalid 'replace' data replace is not an object of strings with {...} keys, or a key targets a preference or consent link.

Invalid JSON and the ID mismatch use the plain envelope with result_data: [].


Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": "Auditions start Monday at 7", "html": "<html><body><h1>Auditions Open</h1><p>Monday at 7 p.m. in the rehearsal hall.</p></body></html>"}' \
"https://e1.envoke.com/v2/messages/2002"
Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"recipient_tag": "Cast Call"}' \
"https://e1.envoke.com/v2/messages/2002"

If the message was going to the Season News subscription, it now goes to the Cast Call tag only.

Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"reply_to": ""}' \
"https://e1.envoke.com/v2/messages/2001"

reply_to is then returned as null.

Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"send_time": "2026-10-20 09:00:00"}' \
"https://e1.envoke.com/v2/messages/2002"

The message stays a Draft. The time is used when it is sent.

Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<html><body><h1>{SHOW_TITLE}</h1><p>Curtain at {CURTAIN_TIME}.</p></body></html>", "replace": {"{SHOW_TITLE}": "The Pirates of Penzance", "{CURTAIN_TIME}": "8:00 p.m."}}' \
"https://e1.envoke.com/v2/messages/2003"
Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": "Last chance for presale seats"}' \
"https://e1.envoke.com/v2/messages/2001"

Message 2001 is Scheduled, so the request fails with Only 'Draft' messages can be updated, this message has the status: 'Scheduled' (see Only drafts can be updated).

Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"template_id": 1901}' \
"https://e1.envoke.com/v2/messages/2002"
{
"success": false,
"result_text": "Validation failed, see 'result_data' -> 'errors'",
"result_data": {
"errors": ["The field 'template_id' is not valid for updating a message"]
}
}
Terminal window
curl -X PATCH -gs \
-u "$API_ID:$API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": "Auditions start Monday at 7"}' \
"https://e1.envoke.com/v2/messages/2099"

Returns the validation error shown under Validation Errors.


Note: The curl examples above are formatted for readability. All requests must use properly encoded URLs.

Full reference, OpenAPI description, and Postman collection: developers.envoke.com.