# Which API do I use?

Envoke's REST API is a set of small APIs, one per resource. This article explains which APIs answer on `/v1` and which on `/v2`, how tags, subscriptions, and mandatory consent relate to each other, when to send with the Send API or the Message API, how the Reports API relates to the reports in Envoke, and what your account needs before its first send.

---

## The APIs and Their Versions

Every API is on the same host, `https://e1.envoke.com`, and uses the same API ID and API Key (see [Authentication](https://envoke-developers.pages.dev/guides/authentication/)). Each API answers on one version only, so the version is part of the API's address rather than a choice:

| API | Path | What it does |
|---|---|---|
| [Contacts](https://envoke-developers.pages.dev/v1/contacts/fields/) | `/v1/contacts` | Read, create, upsert, update, and delete contacts, including their consent, custom field values, tags, and subscriptions. |
| [Send API](https://envoke-developers.pages.dev/v1/send/fields/) | `/v1/send` | Send one message immediately to up to 1,000 listed recipients per request. |
| [Senders](https://envoke-developers.pages.dev/v1/senders/fields/) | `/v1/senders` | Manage sender identities, the From name and address of your messages. |
| [Hooks](https://envoke-developers.pages.dev/v1/hooks/fields/) | `/v1/hooks.json` | Manage webhook subscriptions. |
| [Tags](https://envoke-developers.pages.dev/v2/tags/fields/) | `/v2/tags` | Manage tags, and add or remove contacts in bulk. |
| [Subscriptions](https://envoke-developers.pages.dev/v2/subscriptions/fields/) | `/v2/subscriptions` | Manage subscriptions, and add or remove contacts in bulk. |
| [Custom fields](https://envoke-developers.pages.dev/v2/customfields/fields/) | `/v2/customfields` | Define custom fields. Values are written to contacts through the Contact API. |
| [Groups](https://envoke-developers.pages.dev/v2/groups/fields/) | `/v2/groups/tags`, `/v2/groups/subscriptions`, `/v2/groups/messages`, `/v2/groups/templates` | Manage the groups (folders) that organise tags, subscriptions, messages, and templates. |
| [Templates](https://envoke-developers.pages.dev/v2/templates/fields/) | `/v2/templates` | Manage email templates. |
| [Messages](https://envoke-developers.pages.dev/v2/messages/fields/) | `/v2/messages` | Create, schedule, send, and cancel messages to a tag, subscription, or segment, and read or delete messages. |
| [Reports](https://envoke-developers.pages.dev/v2/reports/fields/) | `/v2/reports/messages`, `/v2/reports/contacts` | Read the email activity counts of messages and contacts. |

The conventions differ from one API to another rather than by version:

- **IDs.** Most APIs return IDs as strings, such as `"42"`. The Send API's response and the Message API's create-and-send response return the message `id` as an integer, as does the `PATCH /v1/contacts/{id}` response for the contact `id`. Webhook subscription IDs are 32-character hexadecimal strings.
- **Errors.** Every API uses the validation envelope `Validation failed, see 'result_data' -> 'errors'` for most errors, but the empty-body error and the response for an ID that is not found differ between APIs. Each is listed under Error Responses at the end of the API's fields reference, for example [Contact API errors](https://envoke-developers.pages.dev/v1/contacts/fields/#error-responses).
- **Hooks.** The Hooks API's documented paths end in `.json`, and creating a subscription returns HTTP `201` with a body of `{"id": "..."}` instead of the success envelope (see [Hooks API - Create](https://envoke-developers.pages.dev/v1/hooks/insert/#response)).

The Contact API's error for an unknown tag or subscription name suggests the endpoint `/interests`. That endpoint is not part of this reference; list names with the Tag and Subscription APIs instead.

---

## Tags, Subscriptions, and Mandatory Consent

A contact can hold three kinds of list membership. They are separate resources in Envoke but share one field on the Contact API.

| Kind | What it is for | Seen by contacts | Managed with |
|---|---|---|---|
| Tag | Segmenting contacts by topic, preference, or area of interest. Also called an interest: tag groups have the type `interest`. | Where tags are displayed publicly, such as website subscription forms, under their `display_names`. | [Tag API](https://envoke-developers.pages.dev/v2/tags/fields/) |
| Subscription | A type of communication contacts opt in to or out of, such as a weekly newsletter. | On your public preference page, unless its [`prefpage_access`](https://envoke-developers.pages.dev/v2/subscriptions/fields/#prefpage_access) is `"private"`. | [Subscription API](https://envoke-developers.pages.dev/v2/subscriptions/fields/) |
| Mandatory consent subscription | Your account's one subscription for mandatory (consent-exempt) messages. Only contacts who hold it are sent a mandatory message. | Its description is given in each mandatory message as the reason it was sent. | Not returned by the Subscription API. Contacts are given it through the Contact API's `interests`, or when a mandatory Send API request creates them. |

On the Contact API, the single field [`interests`](https://envoke-developers.pages.dev/v1/contacts/fields/#interests) holds the names of all three kinds; there are no separate `tags` or `subscriptions` fields.

### How Each API Identifies Them

The Contact API writes a contact's tags, subscriptions, and mandatory consent through one field, so it identifies each item by its name. The Tag and Subscription APIs each manage one kind of item and identify it by its `id` in the URL. Both refer to the same items: a tag's `name` from the Tag API is what goes in `interests`, and its `id` is the numeric ID the Contact API accepts as an object key.

| API | How an item is identified |
|---|---|
| Contact API, create and update | By name in `interests`. Matching ignores case and treats a space and an underscore as the same. In the object form (`{ "Volunteer": "Set" }`), a key can also be the item's numeric ID. |
| Contact API, read filters | `filter[interests]` takes the exact name, case-sensitive. IDs are not accepted (see [Filterable and sortable fields](https://envoke-developers.pages.dev/v1/contacts/read/#filterable-and-sortable-fields)). |
| Tag and Subscription APIs | By `id` in the URL, for example `POST https://e1.envoke.com/v2/tags/{ID}/contacts`, which adds up to 1,000 contacts by `contact_ids` or `contact_emails` in one request ([Tag API - Add and Remove Contacts](https://envoke-developers.pages.dev/v2/tags/contacts/)). |
| Message API | `recipient_tag` and `recipient_subscription` take a name or an ID. `recipient_subscription` also accepts the mandatory consent subscription. |

Use the Contact API's `interests` to set the tags and subscriptions of one contact as you create or update it. A list of names only adds; to remove an item, use the object form with `"Unset"`. Use the Tag and Subscription APIs to add or remove many contacts for one tag or subscription.

### Consent Is Separate

A contact's `consent_status` decides whether Envoke may send them email at all; tags and subscriptions decide which messages they are in the audience for. Adding a contact to a subscription through the Contact API does not check their consent: a contact whose consent is `Not Provided` is added to the subscription like any other contact, and is then excluded when a message is sent to that subscription. See [Consent fields](https://envoke-developers.pages.dev/v1/contacts/fields/#consent-fields) for the consent types and when a change takes effect.

---

## Send API or Message API

Both APIs send email, with different models.

The **Send API** (`POST https://e1.envoke.com/v1/send`) creates a message and sends it in the same request to recipients you list one by one. An address that matches no contact becomes a new contact and is sent the message. There is no draft, schedule, review, or cancel step.

The **Message API** (`https://e1.envoke.com/v2/messages`) creates a message as a `Draft` addressed to an audience Envoke already holds: a tag, a subscription, or a segment. Sending it, now or at a scheduled time, is a separate request that returns an estimate of the recipients, and a scheduled message can be cancelled.

| | Send API | Message API |
|---|---|---|
| Recipients | Up to 1,000 email addresses or contact IDs per request, listed one by one. Further batches can be sent to the same message. | A tag, subscription, or segment, optionally narrowed by a subscription and by language. |
| Addresses that are not contacts | Created as contacts with your Transactional API consent, and sent the message. | Not applicable: only contacts in the audience are sent the message. |
| When it sends | Immediately. | Immediately, or at a `send_time` in your account's time zone. |
| Review and cancel | None. A sent message cannot be changed or cancelled. | A `Draft` can be read, previewed at its `preview_url`, changed, or deleted. A `Scheduled` message can be cancelled back to `Draft`. |
| Counts in the response | The outcome for each recipient, decided when the request is made. | An estimate taken when the request is made; recipients are selected again when the send starts. |
| Personalisation | Per-recipient `replace` values, applied as each email is delivered. Envoke merge fields when `enable_merge_fields` is `true`. | `replace` values applied once when the message is saved, the same for every recipient. Envoke merge tags in the HTML for per-recipient content. |
| Tracking defaults | No open or click tracking unless `track_recipient_activity` is `true`. UTM parameters are never added. | `utm_tag_links` follows your account's link analytics setting. |
| Needs before sending | The Transactional API preference (see [Before Your First Send](#before-your-first-send)). | A subject, a sender, and at least one of `recipient_subscription`, `recipient_tag`, or `recipient_segment`. |

**Use the Send API** when your system decides who receives a message, one person or a list of addresses, and the email goes out now: for example a confirmation or a notice to the people named in a request. Read the full rules in [Send API - Fields Reference](https://envoke-developers.pages.dev/v1/send/fields/) and [Send API - Send](https://envoke-developers.pages.dev/v1/send/send/).

**Use the Message API** when the audience is a tag, subscription, or segment in Envoke, or when the message needs a schedule, a review, or a cancel before it goes out. Sending with a future `send_time` returns the estimate and leaves the message `Scheduled` until then; see [Message API - Sending](https://envoke-developers.pages.dev/v2/messages/sending/).

Points that apply when you choose:

- **Neither API accepts an idempotency key.** Each Send API request and each `POST https://e1.envoke.com/v2/messages/send` (create and send) request creates a new message, so repeating one after a timeout can send the email twice. Sending an existing draft with `POST https://e1.envoke.com/v2/messages/{ID}/send` cannot send it twice: once sent, the message is no longer a `Draft` and a second request fails with `Only 'Draft' messages can be updated, this message has the status: 'Scheduled'` (or the message's current status).
- **Create and send can leave a draft behind.** When `POST https://e1.envoke.com/v2/messages/send` creates the draft but the send step fails, the draft is kept and its ID is not returned. Give each message a unique `name` so the draft can be found with a name filter (see [Create and send](https://envoke-developers.pages.dev/v2/messages/sending/#create-and-send)).
- **Send API messages are also messages.** A message sent through the Send API can be read, and deleted once its status is `Sent`, through the Message API, and its activity is in the Reports API under the `id` the Send API returned.

---

## The Reports API and the Reports in Envoke

The [Reports API](https://envoke-developers.pages.dev/v2/reports/fields/) returns the email activity counts behind the reports in Envoke as JSON. It is read-only, on `/v2`, and has no CSV format. The Message API returns no delivery, open, or click statistics; read them from the Reports API.

| In Envoke | In the Reports API |
|---|---|
| The Sent message report of one message | [Message Stats](https://envoke-developers.pages.dev/v2/reports/message-stats/): `GET https://e1.envoke.com/v2/reports/messages/{ID}` |
| The folder report | The [message activity list](https://envoke-developers.pages.dev/v2/reports/messages/) or the compare report with `group_id`, which includes subfolders at any depth |
| Clicking a count in the Sent message report to see its contacts | [Message Contacts](https://envoke-developers.pages.dev/v2/reports/message-contacts/): `GET https://e1.envoke.com/v2/reports/messages/{ID}/contacts` |
| A contact's Email sending history | [Contact Activity](https://envoke-developers.pages.dev/v2/reports/contacts/): `GET https://e1.envoke.com/v2/reports/contacts/{ID}` |

The numbers are not always the same as the Sent message report's rows:

- **Every metric counts distinct contacts.** The Sent message report's Opens and Bounced rows count one per contact per email client or bounce type, so they can be larger than the API's `opens` and `bounces` (see [How the counts work](https://envoke-developers.pages.dev/v2/reports/fields/#how-the-counts-work)).
- **A rate with nothing to divide by is `null`**, where the Sent message report shows `0` (see [Rates](https://envoke-developers.pages.dev/v2/reports/fields/#rates)).
- **Counts are read from a reporting copy of the database**, so activity from the last few moments may not appear yet.
- **Which messages are listed.** The message activity list includes sent campaigns and automated messages. Drafts, scheduled messages, and messages with the `Transactional` status are not included (see [Which messages are included](https://envoke-developers.pages.dev/v2/reports/messages/#which-messages-are-included)).
- **Times** are in your account's time zone, the zone the Envoke app and the Message API use.

On an account restricted from seeing contacts associated with email activity (the setting that hides a contact's Email sending history in Envoke), the Contact Activity and Message Contacts endpoints return HTTP `403` (see [Contact Activity errors](https://envoke-developers.pages.dev/v2/reports/contacts/#errors)), and the `email_open` and `email_click` webhook types cannot be subscribed to: they fail with `Invalid webhook type: 'email_open'`.

To receive each event as it happens instead of reading counts, subscribe to the email activity webhooks; see [Hooks API - Webhook Payloads](https://envoke-developers.pages.dev/v1/hooks/payloads/).

---

## Before Your First Send

A send can be refused, or reach no one, because of account settings that are made in Envoke rather than through the API. Check each of these before your first send.

1. **The API is enabled and your key works.** See [Before Your Key Works](https://envoke-developers.pages.dev/guides/authentication/#before-your-key-works).
2. **The Transactional API preference is set (Send API only).** In Envoke, go to **Account settings → Integrations → Transactional API** and choose a **Consent status** and enter a **Consent description**. They are given to the contacts the Send API creates. Until they are set, every Send API request fails with `A default consent status and description is required in order to use this API`. The Message API does not use this preference.
3. **A sender identity.** Both APIs send from the account's default sender identity unless the request names another one with `sender`. A Message API draft whose sender has been cleared cannot be sent: `The field 'sender' must be set`. Manage identities with the [Sender API](https://envoke-developers.pages.dev/v1/senders/fields/), which refuses addresses at free or personal email providers. Envoke does not check that an identity is verified before it sends; the Sender API's [`dkim_status`](https://envoke-developers.pages.dev/v1/senders/fields/#dkim_status) reports whether DKIM is configured for the identity's domain, which improves deliverability.
4. **Recipients whose consent allows sending.** Apart from mandatory messages, existing contacts are sent a message only when their consent allows sending (for example `Express`, not `Not Provided`, `Revoked`, or `Expired`), their address is valid and has not been marked undeliverable, and, when your account requires email confirmation, they have confirmed it. The responses count each excluded recipient by reason (see [Consent](https://envoke-developers.pages.dev/v1/send/fields/#consent) and [Recipient counts](https://envoke-developers.pages.dev/v2/messages/sending/#recipient-counts)).
5. **The mandatory consent subscription (mandatory messages only).** A mandatory message, sent with `is_mandatory: true` on the Send API or to the mandatory consent subscription as `recipient_subscription` on the Message API, reaches only contacts who hold that subscription, whatever their consent status, except contacts who have reported spam. Contacts who do not hold it are excluded as `excluded_mandatory_consent` on the Send API.
6. **Credits.** A prepaid account needs a credit balance at least as large as the number of emails to be sent; otherwise the Send API fails with `Message not sent, the account is out of credits` and the Message API with `Email can't be sent, the account is out of credits`. A monthly-billed account that is not yet on a paid plan, and has too few credits, gets `Message not sent, the account has not upgraded` or `Email can't be sent, the account has not upgraded`.

For a walkthrough that creates a contact, a template, and a webhook subscription and then sends, see [Your first integration](https://envoke-developers.pages.dev/guides/first-integration/).

---

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