Message API - Update
Use this endpoint to change a draft message: its settings, its recipients, or its HTML.
Endpoint
Section titled “Endpoint”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.
Request Body
Section titled “Request Body”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.
Only drafts can be updated
Section titled “Only drafts can be updated”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.
Recipients
Section titled “Recipients”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.
Replacing the HTML
Section titled “Replacing the HTML”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.
Clearing Values
Section titled “Clearing Values”| 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'.
ID Mismatch
Section titled “ID Mismatch”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.
Response
Section titled “Response”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.
Validation Errors
Section titled “Validation Errors”{ "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: [].
Examples
Section titled “Examples”Change the subject and HTML
Section titled “Change the subject and HTML”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"Send to a tag instead of a subscription
Section titled “Send to a tag instead of a subscription”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.
Clear the reply-to address
Section titled “Clear the reply-to address”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.
Set a send time
Section titled “Set a send time”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.
New HTML with placeholders
Section titled “New HTML with placeholders”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"Update a message that is not a draft
Section titled “Update a message that is not a draft”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).
Use template_id on update
Section titled “Use template_id on update”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"] }}Message not found
Section titled “Message not found”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.

