Message API - Insert
Use this endpoint to create a new draft message in your account. To create a message and send it in one request, see Create and send.
Endpoint
Section titled “Endpoint”POST https://e1.envoke.com/v2/messagesAuthentication is via HTTP Basic Auth using your API ID and API Key. The request body must be a single JSON object.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
html |
string | One of html or template_id |
The message HTML. Max 200 kB. |
template_id |
integer | One of html or template_id |
ID of a template or message to copy the HTML from. Ignored when html is also sent. |
replace |
object | No | Placeholder text to replace in the HTML before it is saved. |
name |
string | No | Internal name. At least 3 characters. |
group |
string | No | Name or ID of an existing message group. |
subject |
string | No | Subject line. At least 6 characters. Required to send. |
sender |
string | No | Identity ID, Name <email>, or email address. Defaults to the account’s default sender. |
reply_to |
string | No | Identity ID, Name <email>, or email address. |
language |
string | No | en or fr. Defaults to en. |
recipient_subscription |
string | No | Name or ID of a subscription. |
recipient_tag |
string | No | Name or ID of a tag. Not with recipient_segment. |
recipient_segment |
string | No | Name or ID of a segment. Not with recipient_tag. |
recipient_language |
string | No | en or fr: send only to contacts with that language. |
publish_archive |
boolean | No | Publish the message to the web archive. Defaults to false. |
utm_tag_links |
boolean | No | Add UTM parameters to links. Defaults to your account’s link analytics setting. |
send_time |
string | No | A future account-local time, e.g. 2026-10-20 09:00:00. Stored only; it does not schedule the message. |
Only html or template_id is required. A message can be created without a subject, sender, or recipients; they are checked when it is sent.
id, external_id, preview_url, create_time, modified_time, and status are read-only and silently ignored. 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.
Defaults
Section titled “Defaults”| Field | Value when not sent |
|---|---|
name |
API Message {Y-m-d H:i:s}, from the time of the request in Envoke’s server time |
status |
Draft |
group |
"" (no group) |
sender |
The account’s default sender identity |
reply_to |
Not set (null) |
subject |
"" |
language |
en |
recipient_subscription, recipient_tag, recipient_segment, recipient_language |
"" |
publish_archive |
false |
utm_tag_links |
true if link analytics is on in your account preferences, otherwise false |
send_time |
"" |
A message created with send_time stays a Draft. The stored time is used when the message is later sent without a new send_time.
Response
Section titled “Response”On success, the API returns the new message in full, in the same shape as a read:
{ "success": true, "result_text": "Created", "result_data": { "id": "2001", "external_id": "3e8b1f6c9a2d4e7b0c5f8a1d3e6b9c2f", "preview_url": "https://engage.envoke.com/m/a7c3e9f1b5d2/m/3e8b1f6c9a2d4e7b0c5f8a1d3e6b9c2f", "create_time": "2026-10-06 10:15:42", "modified_time": "2026-10-06 10:15:42", "name": "Spring Season Announcement", "group": "Productions", "status": "Draft", "send_time": "", "sender": "Box Office <boxoffice@example.org>", "reply_to": "Front of House <frontofhouse@example.org>", "subject": "Our spring season is here", "language": "en", "recipient_subscription": "Season News", "recipient_tag": "", "recipient_segment": "", "recipient_language": "", "publish_archive": true, "utm_tag_links": true }}result_data.id is the Envoke message ID, as a string. Store it to update, send, cancel, or delete the message later. The HTML is not included; use GET /v2/messages/{id}?include_html=1 to read it back.
Validation Errors
Section titled “Validation Errors”{ "success": false, "result_text": "Validation failed, see 'result_data' -> 'errors'", "result_data": { "errors": [ "One of the fields 'template_id' or 'html' must be provided in order to create a message" ] }}The checks run in the order below. The first six each return on their own, with a single error. The field checks after them are collected and returned together.
| Order | Error | Cause |
|---|---|---|
| 1 | Request body may not be empty |
No body, an empty body, or {}. |
| 2 | The field 'html' may not be longer than 200kB |
html is over 204,800 bytes. |
| 3 | Nothing found for 'template_id': 1999 |
No template or message with that ID is available to your account. |
| 4 | One of the fields 'template_id' or 'html' must be provided in order to create a message |
Neither field was sent, or html is "". |
| 5 | Only one of the fields 'recipient_tag' or 'recipient_segment' may be provided |
Both were sent. |
| 6 | Invalid 'replace' data |
replace is not an object of strings whose keys are wrapped in { }, or a key targets a preference or consent link. |
| 7 | 'headline' is not a valid field |
The body has a key that is not a message field. |
| 7 | The field 'name' must be at least 3 characters long |
name is too short. |
| 7 | The field 'subject' must be at least 6 characters long |
subject is too short. |
| 7 | Invalid 'group': 'Playbills' |
No message group has that name or ID. Includes allowed_values. |
| 7 | Invalid 'sender': 'Box Office' |
Not an identity ID, Name <email>, or email address. reply_to gives Invalid 'reply_to': .... Includes allowed_values. |
| 7 | No sender identity found for email: 'tickets@example.org' |
No identity has that exact address. reply_to gives No reply_to identity found for email: .... Includes allowed_values. |
| 7 | Invalid 'language': 'de' |
Not en, fr, 1, or 3. Also for recipient_language. Includes allowed_values. |
| 7 | Invalid 'recipient_tag': 'Cast List' |
No tag with that name or ID. Also for recipient_subscription and recipient_segment. Includes allowed_values. |
| 7 | The field 'send_time' must be in the future |
send_time is in the past. |
| 7 | Invalid 'send_time': 'next Friday evening' |
send_time could not be read as a date. |
allowed_values lists the valid options for the field, keyed by ID, when your account has 50 or fewer of them (see Error Responses).
Two server-side failures use the plain envelope (result_data: []) instead: Message content error when the content could not be saved, and insert error: followed by the database error when the message could not be saved. A body that is not valid JSON returns Invalid JSON in the same shape.
Examples
Section titled “Examples”Create a message from HTML
Section titled “Create a message from HTML”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<html><body><h1>Auditions Open</h1><p>Auditions for our spring production start Monday.</p></body></html>"}' \ "https://e1.envoke.com/v2/messages"The message is created as a Draft named API Message 2026-10-06 10:12:05, with the account’s default sender, no subject, and no recipients.
Create a complete message
Section titled “Create a complete message”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Spring Season Announcement", "group": "Productions", "subject": "Our spring season is here", "sender": "boxoffice@example.org", "reply_to": 413, "language": "en", "recipient_subscription": "Season News", "publish_archive": true, "utm_tag_links": true, "html": "<html><body><h1>Spring Season</h1><p>Four shows, one season pass.</p></body></html>"}' \ "https://e1.envoke.com/v2/messages"sender is matched by email address and reply_to by identity ID; both are returned as Name <email> (see Response). The message is ready to send.
Create a message from a template
Section titled “Create a message from a template”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Auditions Reminder", "template_id": 1901, "subject": "Auditions start Monday", "recipient_tag": "Cast Call"}' \ "https://e1.envoke.com/v2/messages"Only the template’s HTML is copied. The subject and recipients come from this request.
Fill in a template’s placeholders
Section titled “Fill in a template’s placeholders”The template Playbill Template (ID 1901) contains the placeholders {SHOW_TITLE} and {CURTAIN_TIME}:
curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Pirates of Penzance - Opening Night", "template_id": 1901, "subject": "Opening night is almost here", "replace": {"{SHOW_TITLE}": "The Pirates of Penzance", "{CURTAIN_TIME}": "7:30 p.m."}}' \ "https://e1.envoke.com/v2/messages"The message HTML is saved with the placeholders already replaced. The template itself is unchanged.
Fill in your own HTML
Section titled “Fill in your own HTML”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Opening Date Notice", "html": "<html><body><p>Dear patron, {SHOW_TITLE} opens on {OPENING_DATE}.</p></body></html>", "replace": {"{SHOW_TITLE}": "The Pirates of Penzance", "{OPENING_DATE}": "Friday, October 23"}}' \ "https://e1.envoke.com/v2/messages"Send to a subscription, narrowed by a tag
Section titled “Send to a subscription, narrowed by a tag”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Cast Party Invitation", "subject": "You are invited to the cast party", "recipient_subscription": "Season News", "recipient_tag": "Cast Call", "html": "<html><body><p>Join us after the final show.</p></body></html>"}' \ "https://e1.envoke.com/v2/messages"When sent, the message goes only to contacts who have the Cast Call tag and are subscribed to Season News.
Create a draft with a send time
Section titled “Create a draft with a send time”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Subscriber Presale", "subject": "Presale opens Tuesday at 9", "recipient_subscription": "Season News", "send_time": "2026-10-20 09:00:00", "html": "<html><body><p>Subscribers get first pick of seats.</p></body></html>"}' \ "https://e1.envoke.com/v2/messages"The message is a Draft with send_time "2026-10-20 09:00:00" (9:00 a.m. in the account time zone). It is not scheduled until it is sent.
Missing content
Section titled “Missing content”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Spring Season Announcement"}' \ "https://e1.envoke.com/v2/messages"Returns the validation error shown under Validation Errors.
Tag and segment together
Section titled “Tag and segment together”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<html><body><p>Hello</p></body></html>", "recipient_tag": "Cast Call", "recipient_segment": "Lapsed Subscribers"}' \ "https://e1.envoke.com/v2/messages"{ "success": false, "result_text": "Validation failed, see 'result_data' -> 'errors'", "result_data": { "errors": ["Only one of the fields 'recipient_tag' or 'recipient_segment' may be provided"] }}Unknown group
Section titled “Unknown group”curl -X POST -gs \ -u "$API_ID:$API_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<html><body><p>Hello</p></body></html>", "group": "Playbills"}' \ "https://e1.envoke.com/v2/messages"{ "success": false, "result_text": "Validation failed, see 'result_data' -> 'errors'", "result_data": { "errors": ["Invalid 'group': 'Playbills'"], "allowed_values": { "group": { "31": "Productions", "32": "Newsletters" } } }}No message is created. Create the group first with the Group API, or use one of the listed names or IDs.
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.

