# Message API - Fields Reference

This article describes all fields available through the Message API. Use this as a reference when reading, creating, updating, or sending messages.

---

## Overview

The Message API lets you read, create, update, delete, send, and cancel the email messages in your Envoke account. A message is one email campaign: its settings (name, sender, subject, recipients, send time) and its HTML content. Messages are created as drafts; only a `Draft` message can be changed, and sending moves it through the statuses described under [`status`](#status).

The Message API answers on `/v2` only. Related resources have their own APIs: templates whose HTML a new message can copy through [`template_id`](#html-template_id-and-replace) are managed with the [Template API](https://envoke-developers.pages.dev/v2/templates/fields/), message groups (folders) with the [Group API](https://envoke-developers.pages.dev/v2/groups/fields/), the tags and subscriptions a message is sent to with the [Tag API](https://envoke-developers.pages.dev/v2/tags/fields/) and [Subscription API](https://envoke-developers.pages.dev/v2/subscriptions/fields/), and sender identities with the [Sender API](https://envoke-developers.pages.dev/v1/senders/fields/). Sending and cancelling are covered in [Sending](https://envoke-developers.pages.dev/v2/messages/sending/).

The API returns no delivery, open, or click statistics; the only counts it gives are the recipient estimate in a send response.

All endpoints require [HTTP Basic Auth](https://envoke-developers.pages.dev/guides/authentication/) using your API ID and API Key.

---

## Fields

| Field | Type | Read-only | Required on Create | Description |
|---|---|---|---|---|
| `id` | string | Yes | — | Envoke message ID, assigned on creation. |
| `external_id` | string | Yes | — | Externally visible identifier used in the preview URL. |
| `preview_url` | string | Yes | — | Public URL to view the message in a browser. |
| `create_time` | string | Yes | — | When the message was created, in the account time zone. |
| `modified_time` | string | Yes | — | When the message was last changed, in the account time zone. |
| `name` | string | No | No | Internal name. Generated if omitted. |
| `group` | string | No | No | Name of the message group (folder), or `""`. |
| `status` | string | Yes | — | Current status, e.g. `Draft` or `Sent`. Changed only by sending and cancelling. |
| `send_time` | string | No | No | Scheduled send time in the account time zone, or `""`. |
| `sender` | string | No | No | Sender identity as `Name <email>`. Defaults to the account's default sender. |
| `reply_to` | string | No | No | Reply-to identity as `Name <email>`. No default. |
| `subject` | string | No | No | Subject line. Required to send. |
| `language` | string | No | No | Language of the message, `en` or `fr`. Defaults to `en`. |
| `recipient_subscription` | string | No | No | Subscription the message is sent to, or `""`. |
| `recipient_tag` | string | No | No | Tag the message is sent to, or `""`. |
| `recipient_segment` | string | No | No | Segment the message is sent to, or `""`. |
| `recipient_language` | string | No | No | Send only to contacts with this language, `en` or `fr`, or `""` for all. |
| `publish_archive` | boolean | No | No | Whether the message is published to the account's web archive. |
| `utm_tag_links` | boolean | No | No | Whether UTM tracking parameters are added to links. |
| `html` | string | Write-only | One of `html` or `template_id` | The message HTML. Returned only on a single GET with `include_html`. |
| `template_id` | integer | Write-only | One of `html` or `template_id` | ID of a template or message to copy HTML from. Create only. Never returned. |
| `replace` | object | Write-only | No | Placeholder text to replace in the HTML when it is saved. Never returned. |

---

## Field Details

Every readable field is present in a read response unless `fields` is used to select some. An unset text value is returned as `""`, except `sender` and `reply_to`, which are returned as `null` when no identity is set (see [sender and reply_to](#sender-and-reply_to)). Read-only fields sent on create or update are silently ignored. A message object returned by a GET cannot always be sent back as is: a `null` `sender` or `reply_to` fails as `Invalid 'reply_to': ''`, a `send_time` of `""` fails as not in the future, and a `subject` of `""` fails as shorter than 6 characters, so remove those values first.

### `id`

- **Type:** String
- **Read-only:** Yes — assigned automatically on creation.
- **Returned value (read):** The message ID as a string.
- **Example:** `"2001"`

Identifies the message in the URL of single GET, update, delete, send, and cancel requests. The one exception to the string type is the response of `POST /v2/messages/send` (create and send), whose `result_data.id` is an integer (see [Sending](https://envoke-developers.pages.dev/v2/messages/sending/#create-and-send)).

---

### `external_id`

- **Type:** String (32 characters)
- **Read-only:** Yes — assigned automatically on creation.
- **Example:** `"3e8b1f6c9a2d4e7b0c5f8a1d3e6b9c2f"`

An externally visible identifier used to build `preview_url`. Not the same as `id`.

---

### `preview_url`

- **Type:** String
- **Read-only:** Yes — built from your account's external ID and the message's `external_id`.
- **Format:** `https://{domain}/m/{account_external_id}/m/{external_id}`
- **Example:** `"https://engage.envoke.com/m/a7c3e9f1b5d2/m/3e8b1f6c9a2d4e7b0c5f8a1d3e6b9c2f"`

A public URL that shows the message in a browser without logging in. `{domain}` is your account's custom domain if it has one, and otherwise Envoke's message domain; it is not the API host. Use the URL as returned rather than building it yourself.

---

### `create_time`

- **Type:** String
- **Read-only:** Yes — set automatically on creation.
- **Returned value (read):** `Y-m-d H:i:s` in the account time zone, with no offset.
- **Example:** `"2026-10-06 10:15:42"`

See [Dates and time zones](#dates-and-time-zones).

---

### `modified_time`

- **Type:** String
- **Read-only:** Yes — updated automatically.
- **Returned value (read):** `Y-m-d H:i:s` in the account time zone, with no offset.
- **Example:** `"2026-10-06 11:02:08"`

Changes on every successful update, even one that changes no value, and when a message is sent or cancelled. The list is sorted by this field, newest first, by default.

---

### `name`

- **Type:** String, at least 3 characters
- **Read-only:** No
- **Required on create:** No — if omitted, the message is named `API Message {Y-m-d H:i:s}` from the time of the request.
- **Example:** `"Spring Season Announcement"`

The internal name shown in the Envoke message list; recipients do not see it. Too short: `The field 'name' must be at least 3 characters long`. The API sets no maximum; a longer name is cut to its first 300 characters without an error.

The generated name uses Envoke's server clock, which can differ from the account time zone used by `create_time`.

---

### `group`

- **Type:** String
- **Read-only:** No
- **Required on create:** No
- **Accepted values (write):** The name or ID of an existing message group. Names are matched ignoring case, and a space and an underscore are treated as the same. `""` or `"0"` removes the message from its group.
- **Returned value (read):** The group name, or `""` when the message has no group.
- **Example:** `"Productions"`

Only message groups can be used; template groups and contact groups are not accepted. A group is not created automatically: an unknown value fails with `Invalid 'group': 'Playbills'` and the list of valid groups in `allowed_values` (see [Error Responses](#error-responses)). Create groups with the [Group API](https://envoke-developers.pages.dev/v2/groups/fields/). A message created through this API has no group unless `group` is set.

---

### `send_time`

- **Type:** String
- **Read-only:** No
- **Required on create:** No
- **Accepted values (write):** A future date and time, read as account-local time, e.g. `"2026-10-20 09:00:00"`.
- **Returned value (read):** `Y-m-d H:i:s` in the account time zone, or `""` when no time is set.
- **Example:** `"2026-10-20 09:00:00"`

Setting `send_time` on a draft does not schedule it; the message is scheduled only when it is [sent](https://envoke-developers.pages.dev/v2/messages/sending/). See [Dates and time zones](#dates-and-time-zones) for how the value is read and why it cannot be cleared.

---

### `subject`

- **Type:** String, at least 6 characters
- **Read-only:** No
- **Required on create:** No — but a message cannot be sent without one.
- **Example:** `"Our spring season is here"`

Defaults to `""`. Too short: `The field 'subject' must be at least 6 characters long`. The API sets no maximum; a longer subject is cut to its first 360 characters without an error.

---

### `language`

- **Type:** String
- **Read-only:** No
- **Required on create:** No — defaults to `en`.
- **Accepted values (write):** `en` or `fr` (case-insensitive), or the IDs `1` (English) or `3` (French). `""` or `"0"` sets `en`.
- **Returned value (read):** `"en"` or `"fr"`.
- **Example:** `"fr"`

The language the message is written in. Any other value fails with `Invalid 'language': 'de'` and `allowed_values` `{"1":"en","3":"fr"}`. To choose which contacts receive the message by language, use [`recipient_language`](#recipients).

---

### `publish_archive`

- **Type:** Boolean
- **Read-only:** No
- **Required on create:** No — defaults to `false`.
- **Accepted values (write):** `true`, `"true"`, `1`, `"1"`, `"yes"`, or `"on"` publishes. Anything else is treated as `false`.
- **Returned value (read):** `true` or `false`.
- **Example:** `true`

When `true`, the message is published to your account's public message archive.

---

### `utm_tag_links`

- **Type:** Boolean
- **Read-only:** No
- **Required on create:** No — defaults to your account's link analytics setting.
- **Accepted values (write):** As for `publish_archive`.
- **Returned value (read):** `true` or `false`.
- **Example:** `true`

When `true`, Envoke adds UTM tracking parameters to the links in the message. On create, the default is `true` if link analytics is turned on in your account preferences and `false` otherwise.

---

### `status`

- **Type:** String
- **Read-only:** Yes — changed only by [sending and cancelling](https://envoke-developers.pages.dev/v2/messages/sending/).
- **Returned value (read):** One of the status names below.
- **Example:** `"Draft"`

| Code | Name | How a message gets there | What the API allows |
|---|---|---|---|
| `0` | `Draft` | Created through the API or in Envoke; a cancelled send; a scheduled message that is deleted. | Update, send, delete. |
| `1` | `Scheduled` | [Sent](https://envoke-developers.pages.dev/v2/messages/sending/) through the API or launched in Envoke, before its send time. | Cancel (back to `Draft`), delete (also unschedules it). |
| `2` | `AB test in progress` | An A/B test launched in Envoke. A/B tests cannot be set up through the API. | Cancel, delete. |
| `4` | `Queuing` | The send has started: Envoke is selecting the recipients. | Cancel is accepted but does not stop delivery (see [Cancel](https://envoke-developers.pages.dev/v2/messages/sending/#cancel)); delete. |
| `5` | `Sending` | Recipients are queued and emails are going out. | Cancel is accepted but does not stop delivery. Cannot be deleted. |
| `7` | `Transactional` | A transactional message set up in Envoke. | Delete. |
| `8` | `Nurture` | A message in a nurture campaign (autoresponder). | Delete, unless it is part of a nurture series. |
| `9` | `Sent` | Every email has been handed off for delivery. | Delete. |

- A message in any status other than `Draft` cannot be updated or sent: `Only 'Draft' messages can be updated, this message has the status: 'Sent'`.
- `status` is read-only. Sending it in a request body has no effect.
- Status names are returned exactly as shown. In filters, a name or a code can be used (see [Read](https://envoke-developers.pages.dev/v2/messages/read/#filter-by-status)).
- The list includes messages in every status, including `Nurture` and `Transactional` messages created in Envoke.

---

### `html`, `template_id`, and `replace`

These three write-only fields set the message's content.

#### `html`

- **Type:** String, at most 200 kB (204,800 bytes)
- **Read-only:** Write-only — returned only by `GET /v2/messages/{id}?include_html=1`.
- **Required on create:** One of `html` or `template_id`.
- **Example:** `"<html><body><h1>Spring Season</h1><p>Curtain up on {SHOW_TITLE}.</p></body></html>"`

The complete HTML of the message, stored as sent. Envoke does not check or clean it. If it contains the `<meta name="TEMPLATE_VERSION"` tag that Envoke's drag-and-drop editor writes, the message opens in that editor in Envoke; otherwise it opens in the HTML editor.

| Rule | Behaviour |
|---|---|
| Size | Over 200 kB fails with `The field 'html' may not be longer than 200kB`. The size is checked on the HTML you send, before `replace` is applied. |
| Empty value | `""` counts as not sent. On update, the content cannot be blanked. |
| Returned | Never in list, create, update, send, or cancel responses. Only on a single GET with `include_html` (see [Read](https://envoke-developers.pages.dev/v2/messages/read/#get-a-single-message)). |
| With `template_id` | When both are sent on create, `html` is used and `template_id` is ignored, with no error. |
| On update | Replaces the whole content of the message. |

#### `template_id`

- **Type:** Integer (a numeric string such as `"1901"` is also accepted)
- **Read-only:** Write-only — never returned.
- **Required on create:** One of `html` or `template_id`.
- **Example:** `1901`

The ID of a template, or of another message in your account, whose HTML the new message copies. Templates shared with your account can be used as well as your own. An ID that matches nothing fails with `Nothing found for 'template_id': 1999`.

Only the HTML (and which editor the content opens in) is copied. The source's subject, sender, reply-to, language, group, and recipients are not; set them in the same request. The copy is independent: later changes to the template do not change the message.

`template_id` is accepted on create only. On update it fails with `The field 'template_id' is not valid for updating a message`; send new `html` instead.

#### `replace`

- **Type:** Object of strings
- **Read-only:** Write-only — never returned.
- **Required on create:** No
- **Format:** `{ "{PLACEHOLDER}": "replacement text" }`
- **Example:** `{ "{SHOW_TITLE}": "The Pirates of Penzance", "{CURTAIN_TIME}": "7:30 p.m." }`

Replaces placeholder text in the message HTML once, when the message is saved. The HTML is stored with the replacements already made; nothing is replaced later at send time, and the replacement is the same for every recipient. For per-recipient content, use Envoke merge tags in the HTML instead.

| Rule | Behaviour |
|---|---|
| On create | Applied to `html`, or to the HTML copied through `template_id`. |
| On update | Applied only to the `html` sent in the same request. Without `html`: `The field 'html' is required for content 'replace' data`. You cannot run a replacement over the HTML a message already has. |
| Keys | Every key must start with `{` and end with `}`, e.g. `{SHOW_TITLE}`. |
| Values | Every value must be a string. It is inserted as is, without escaping, so it can contain HTML. |
| Unmatched keys | A key that does not appear in the HTML is ignored. |
| Order | Keys are applied in the order sent, so a later key can match text inserted by an earlier value. |
| Protected links | A key may not contain `{@pref-`, `{@consent-url`, or `{@consent-prefpage-url`, so the preference and consent links in your footer cannot be replaced. |
| Empty | `{}` is ignored. |

Any other shape (a list, a non-string value, a key without braces, a protected key) fails with `Invalid 'replace' data`, which does not say which entry is wrong.

The size limit on `html` is checked before the replacement, so the saved HTML can be larger than 200 kB if the values are long.

**Use case 1: Fill in a template designed in Envoke.** Build the template once in Envoke with placeholder text, then create each message from it with `template_id` and fill in the details:

```json
{
  "name": "Pirates of Penzance - Opening Night",
  "template_id": 1901,
  "replace": { "{SHOW_TITLE}": "The Pirates of Penzance", "{CURTAIN_TIME}": "7:30 p.m." }
}
```

**Use case 2: Insert a block of HTML from your own system into a master template.** The template holds your design, header, and footer, with one placeholder where the content goes. Your system builds the content and sends it as the value:

```json
{
  "name": "Weekly Show Listings",
  "template_id": 1902,
  "replace": { "{SHOW_LISTINGS}": "<h2>This week</h2><p>Fri 7:30 p.m. - The Pirates of Penzance</p><p>Sat 2:00 p.m. - Matinee</p>" }
}
```

**Use case 3: Fill in your own HTML.** When your system already produces the HTML, send it with placeholders and the values in the same request:

```json
{
  "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" }
}
```

Envoke merge tags such as `{@first_name}` are not protected keys. Avoid using them as `replace` keys, or the merge tag is replaced for every recipient.

---

### `sender` and `reply_to`

- **Type:** String
- **Read-only:** No
- **Required on create:** No. `sender` defaults to the account's default sender; `reply_to` has no default.
- **Accepted values (write):** An identity ID, the identity as `Name <email>`, or the email address alone. `""` or `"0"` clears the field.
- **Returned value (read):** `"Name <email>"`, or `null` when no identity is set.
- **Example:** `"Box Office <boxoffice@example.org>"`

Both fields take one of the sender identities (From addresses) set up in your account; list them with the [Sender API](https://envoke-developers.pages.dev/v1/senders/fields/). A value is resolved in this order:

| Step | Value | Result |
|---|---|---|
| 1 | Digits that match an identity ID, e.g. `"412"` or `412` | That identity. |
| 2 | `Name <email>` matching an identity, ignoring case and treating a space and an underscore as the same, e.g. `"box office <boxoffice@example.org>"` | That identity. |
| 3 | `""` or `"0"` | The field is cleared. |
| 4 | A valid email address, e.g. `"boxoffice@example.org"` | The first identity with that address. The address must match exactly, including case. If none matches: `No sender identity found for email: 'tickets@example.org'` (or `No reply_to identity found for email: ...`). |
| 5 | Anything else | `Invalid 'sender': 'Box Office'` (or `Invalid 'reply_to': ...`). |

Errors from steps 4 and 5 include the account's identities in `allowed_values`, keyed by ID, as `Name <email>`.

When `sender` is omitted on create (or sent as `""`), the message uses the identity marked as the account default. On update, `""` clears the sender without falling back to the default, and a message with no sender cannot be sent: `The field 'sender' must be set`. `reply_to` is optional; when it is not set, replies go to the sender address.

---

### Recipients

Three fields choose who a message is sent to, and a fourth narrows the choice by language.

| Field | Accepted values (write) | Returned value (read) |
|---|---|---|
| `recipient_subscription` | The name or ID of a subscription, including your account's mandatory consent subscription. | The subscription name, or `""`. |
| `recipient_tag` | The name or ID of a tag. | The tag name, or `""`. |
| `recipient_segment` | The name or ID of a segment. | The segment name, or `""`. |
| `recipient_language` | `en`, `fr`, `1`, or `3`. `""` or `"0"` clears it. | `"en"`, `"fr"`, or `""` (all languages). |

Names are matched ignoring case, with a space and an underscore treated as the same. An unknown name or ID fails with `Invalid 'recipient_tag': 'Cast List'` (and similarly for the other fields) with the valid values in `allowed_values` when the account has 50 or fewer of them. `""` or `"0"` clears a field. Example values: `"Season News"`, `"Cast Call"`, `"Lapsed Subscribers"`.

Tags and subscriptions can be created with the [Tag API](https://envoke-developers.pages.dev/v2/tags/fields/) and [Subscription API](https://envoke-developers.pages.dev/v2/subscriptions/fields/). Segments cannot be created through any API; create them in Envoke first.

| Rule | Behaviour |
|---|---|
| Tag or segment, not both | `recipient_tag` and `recipient_segment` cannot both be set in one request: `Only one of the fields 'recipient_tag' or 'recipient_segment' may be provided`. |
| Subscription alone | The message goes to the contacts subscribed to it. |
| Tag or segment alone | The message goes to the contacts with the tag, or in the segment. |
| Subscription and a tag or segment | The subscription narrows the tag or segment: the message goes only to contacts who are in the tag or segment **and** subscribed. |
| Mandatory consent | When `recipient_subscription` is your account's mandatory consent subscription, the message is sent as a mandatory (consent-exempt) message, with the subscription's description as the stated reason. |
| `recipient_language` | Only contacts whose language matches are sent the message. When it matches your account's default language, contacts with no language set are included too. |
| Sending | At least one of `recipient_subscription`, `recipient_tag`, or `recipient_segment` must be set to send: `At least one of the fields 'recipient_subscription', 'recipient_tag', or 'recipient_segment' must be set`. |

**On update, the recipient fields are replaced as a set.** If a request includes any one of `recipient_subscription`, `recipient_tag`, or `recipient_segment`, the other two are cleared unless they are in the same request. For example, `{"recipient_tag": "Cast Call"}` on a message sent to the `Season News` subscription leaves it sent to the tag only. To keep a subscription and change the tag, send both. `{"recipient_subscription": ""}` clears all three. `recipient_language` is not affected.

On read, `recipient_tag` is `""` when the message is sent to a subscription alone.

Contacts are selected when the send starts, not when the fields are set, and only those whose consent allows sending are emailed (see [Recipient counts](https://envoke-developers.pages.dev/v2/messages/sending/#recipient-counts)).

---

### Dates and time zones

| Field | On write | On read |
|---|---|---|
| `create_time` | Ignored | `Y-m-d H:i:s` in the account time zone |
| `modified_time` | Ignored | `Y-m-d H:i:s` in the account time zone |
| `send_time` | A future date and time, read as account-local time | `Y-m-d H:i:s` in the account time zone, or `""` |

The account time zone is the one set in your Envoke account preferences, for example `America/Toronto`. Returned times carry no offset or `Z`; they are wall-clock times in that zone. Daylight saving time applies.

**Send `send_time` as account-local time without an offset**, for example `"2026-10-20 09:00:00"` for 9:00 a.m. in the account's zone. An offset or `Z` in the value is dropped, and the remaining wall-clock time is still read in the account time zone: `"2026-10-20T09:00:00Z"` and `"2026-10-20T09:00:00-07:00"` both mean 9:00 a.m. account time, not 9:00 UTC or 9:00 Pacific.

| `send_time` value | Result |
|---|---|
| A future time | Stored, and shown in later responses. |
| A time in the past | `The field 'send_time' must be in the future` |
| A value that is not a date | `Invalid 'send_time': 'next Friday evening'` |
| `""` or `null` | Read as the current time, which fails as not in the future. |

**`send_time` cannot be cleared.** Once a message has a send time, no value returns it to `""`. A send time also survives a cancel: a cancelled message goes back to `Draft` with its old `send_time`, and sending it again without a new `send_time` reuses the stored time (see [Send a draft](https://envoke-developers.pages.dev/v2/messages/sending/#send-a-draft)).

---

## Error Responses

**Validation errors** (missing or invalid fields, rule violations, bad filters):

```json
{
  "success": false,
  "result_text": "Validation failed, see 'result_data' -> 'errors'",
  "result_data": {
    "errors": [
      "The field 'name' must be at least 3 characters long",
      "'headline' is not a valid field"
    ]
  }
}
```

When a lookup field (`group`, `sender`, `reply_to`, `language`, `recipient_language`, `recipient_subscription`, `recipient_tag`, `recipient_segment`) has an unknown value, `result_data` also carries `allowed_values`, an object of the valid options keyed by ID. It is included only when the account has 50 or fewer options for that field:

```json
{
  "success": false,
  "result_text": "Validation failed, see 'result_data' -> 'errors'",
  "result_data": {
    "errors": ["Invalid 'group': 'Playbills'"],
    "allowed_values": {
      "group": { "31": "Productions", "32": "Newsletters" }
    }
  }
}
```

**Plain errors.** Some errors use `result_data: []` with the message in `result_text` instead of the validation envelope: `Invalid JSON`, `Invalid request`, the ID mismatch on update, send, and cancel, `Message content error`, the delete errors, and the zero-recipient send result (which carries data; see [Sending](https://envoke-developers.pages.dev/v2/messages/sending/#errors)).

```json
{
  "success": false,
  "result_data": [],
  "result_text": "Item with id '2099' not found"
}
```

**Empty or unreadable body.** `POST /v2/messages`, `PATCH /v2/messages/{id}`, and `POST /v2/messages/send` with no body, an empty body, or `{}` return the validation envelope with `Request body may not be empty`. The send-by-ID and cancel endpoints accept an empty body. A body that is not valid JSON returns the plain envelope with `Invalid JSON`.

All error responses above use HTTP status `400`. An invalid API ID or key returns `401` with the body `{"success":false,"result_data":[],"result_text":"Invalid credentials"}`. A valid key on a closed or inactive account returns `403` with the JSON body `{"success":false,"result_data":[],"result_text":"This account has been closed."}` (or `"This account is not active."`) Exceeding your account's API limit returns `429` with `success: false` and a `result_text` naming the limit.

### Not found

**Not-found behaviour varies by method:**

- **GET** `/messages/{id}` — when the ID is not found, returns an empty array (`[]`). Deleted messages and templates are not found.
- **PATCH** `/messages/{id}` — returns a validation error:

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

- **POST** `/messages/{id}/send` — the same validation error as PATCH.
- **POST** `/messages/{id}/cancel` — returns the validation error for a status that cannot be cancelled, with the status left blank: `Sending cannot be cancelled for a message with 'status': `.
- **DELETE** `/messages/{id}` — returns the plain envelope: `{"success":false,"result_data":[],"result_text":"Item with id '2099' not found"}`.

---

*Full reference, OpenAPI description, and Postman collection: [developers.envoke.com](https://developers.envoke.com).*
