The Transactional Email API lets you send personalized, event-triggered emails, such as order confirmations, password resets, and shipping updates, to every user in a batch. Each recipient receives a message built from their own data, their actual order items, amounts, dates, and tracking details, rather than one identical template where only the name changes.
V2 offers the following feature set:
Per-recipient personalization with Liquid, using structured data (nested objects and lists)
Conditional content that shows or hides within a template based on each recipient's data
View in Browser support
Analytics categories, for reporting by email type
Template validation before a send goes live
Delivery-status tracking, per recipient
V1 is (legacy transactional api) will remain supported until summer 2027.
Before you start
Channel setup
Complete the Transactional Email Channel Setup first. The sender domain you use in the from email must be authenticated; unauthenticated domains are rejected.
Authentication
You authenticate with a single API token in the X-INS-AUTH-KEY header (in the INS.{id}.{secret} format), or with OAuth 2.0 access through the Insider Gateway API. The client is always implicit from your credentials.
API key
One key covers every endpoint on this page. Generate it once and reuse the same X-INS-AUTH-KEY across send, validate, delivery status, and all category endpoints. You do not generate a separate key per endpoint, nor do you need to regenerate it to call a different endpoint.
OAuth 2.0
The auth flow is the same for every endpoint, but each endpoint requires its own scope. Request all the scopes you need when you generate the token, and that one token then works across those endpoints:
Endpoint | OAuth scope |
|---|---|
em-tx-v2-send | |
em-tx-v2-validate | |
em-tx-v2-status-get | |
em-tx-v2-categ-create | |
em-tx-v2-categ-list | |
em-tx-v2-categ-get |
Endpoints and authentication
Each path below links to its own page with headers, parameters, examples, and responses.
Method | Path | Purpose |
|---|---|---|
POST | /mail/V2/send | Send a transactional email to up to 100 recipients |
POST | /mail/V2/validate | Check a template's Liquid syntax, and optionally render it, without sending |
GET | /mail/V2/messages/{message_id} | Read the delivery status for a previously accepted message |
POST | /mail/V2/categories | Create a category for analytics tracking purposes |
GET | /mail/V2/categories | List existing categories |
GET | /mail/V2/categories/{id} | Read a single category |
Authenticate directly with the X-INS-AUTH-KEY header, or through the Insider Gateway API using OAuth 2.0 (authenticate to the Gateway with Authorization: Bearer {token}, and it proxies your request to the internal endpoint). The request and response bodies are identical for both.
Sample request and response
Below is a minimal personalized send. For the full parameter list and more examples, refer to POST /mail/v2/send.
{
"subject": "Order {{ order.id }} confirmed",
"from": { "email": "no-reply@acme.com", "name": "Acme Store" },
"recipients": [
{ "email": "alice@example.com", "fields": { "first_name": "Alice", "order": { "id": "A-1024" } } }
],
"content": [
{ "type": "text/html", "value": "<p>Hi {{ first_name }}, order {{ order.id }} is confirmed.</p>" }
]
}A successful send returns 202 Accepted with a message_id:
{ "status": "accepted", "message_id": "550e8400-e29b-41d4-a716-446655440000" }Templating and personalization
The subject and the HTML body are rendered for each recipient using Liquid, with values from that recipient's fields. Insider One's Liquid supports the full set of Liquid tags and filters; the table below lists the capabilities most templates use. For the complete reference, refer to Liquid tags.
Capability | Example |
|---|---|
Variables | {{ first_name }} |
Nested values with dot-notation | {{ order.total }}, {{ address.city }} |
Conditions | {% if order.total > 100 %} ... {% endif %} |
Loops over lists | {% for item in order.items %}{{ item.name }}{% endfor %} |
Before a template goes live, confirm it is well-formed with the validation endpoint POST /mail/v2/validate.
Analytics categories
Categories group transactional emails so you can report on performance by email type, e.g., order confirmations versus password resets. Register a category, then reference it by its integer ID in the category field of a send. Manage categories with the Create, List, and Read category endpoints. Reporting by category is shown in Transactional Email Analytics.
Delivery events and webhooks
V2 emits delivery, open, click, bounce, blocked, and dropped events to your webhook. When UCD event logging is enabled for your account, these events are also recorded on the user's profile in Insider One's Unified Customer Database (UCD).
Event | Parameters |
|---|---|
txn_email_delivered | ip_address, src, subject, message_id |
txn_email_open | ip_address, src, subject, user_agent, message_id |
txn_email_click | ip_address, src, subject, user_agent, url, url_offset_index (number), url_offset_type, message_id |
txn_email_bounce | ip_address, reason, src, subject, type, message_id |
txn_email_blocked | ip_address, reason, src, subject, type |
txn_email_dropped | reason, src, subject, message_id |
Unless otherwise noted, a parameter's type is string; any exception is marked next to the parameter.
Callbacks
Unlike V1, the callback URL and secret are not part of the send payload. You configure them once in the panel, under Settings > Email Settings > Webhook Integration for Transactional Email. After enabling it there and entering your Callback URL and Secret, V2 sends the events above to that URL. For payload and signature details, see Email Webhooks for Transactional Emails.
Sample responses and error codes
A successful send returns 202; a duplicate within the 15-minute window returns 409; every error uses one envelope with status, message, and an optional errors array. Each endpoint page shows its own responses. For the full list of codes across all endpoints, refer to the Error Codes.
Limitations
Constraint | Value |
|---|---|
Recipients per request | 100 |
Top-level fields keys per recipient | 150 |
fields nesting depth | 5 |
Serialized fields per recipient | 256 KB |
unique_args | 10 keys / 1 KB |
Content blocks | 2 (one HTML, one plain text) |
Request body | 25 MB (about 18 MB decoded attachments) |
Deduplication window | 15 minutes |
Delivery-status retention | 2 days |
Categories per customer | 100 |
Send Rate Limit* | 10,000 requests per second per customer |
* Rate limiting is fail-closed: if the limiter is unreachable, requests receive 429 with a retry_after value.