V2 is now available. If you are planning to integrate with Insider's transactional email API, use the newer v2 endpoint.
The following are available in v2:
- Liquid syntax for personalization
- Conditional content and item lists (loops)
- View in Browser
- Analytics categories, for reporting by email type
- Template validation before sending
- Delivery-status tracking
V1 remains supported until summer 2027.
This API enables you to send targeted ecommerce and personalized one-to-one emails to your users. You can trigger these emails once a user takes a specific action on your platform, for cases such as:
- Post-purchase emails with purchase or booking details
- Password reset confirmations
- Order confirmations
- Delivery tracking notifications
Domain authorization is required. The domains from which you send transactional emails must be authorized. If you have questions about domain authorization, or want to authenticate more domains, create a ticket for the Insider One's Operational Excellence Team. If you try to send from an unauthorized domain, you will receive an error and your emails cannot be sent.
Supported transactional email events and their parameters
| Event | 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.
Endpoint and headers
Visit our Postman collection to test this request.
Headers
| Header | Sample Value | Description |
|---|---|---|
| X-INS-AUTH-KEY | 1a2b3c4d5e6f | This key is required to authorize your request. Refer to API Authentication Tokens to generate your token. |
| Content-Type | application/json | This header specifies the media type of the resource. |
| cache-control | no-cache | This header specifies browser caching in requests and responses. |
Body parameters
The table below lists the parameters of the request body.
| Parameter | Description | Data Type | Required |
|---|---|---|---|
| subject | Subject line that is sent to the recipient | String | Yes |
| tos | Email address(es) to send the email to | Array | Yes |
tos.name | User name | String | No |
tos.email | Email address of the recipient | String | No |
| tos.uuid | UUID of the recipient | String | No |
| from | Sender information object | Object | Yes |
from.name | Sender name | String | No |
from.email | Sender email | String | No |
| content | Email content array | Array | Yes |
content.type | Type of your email content | String | No |
content.value | Email content | String | Yes |
| cc | Carbon-copy recipients | Array | No |
| bcc | Blind carbon-copy recipients | Array | No |
| reply_to | Reply-to address and name | Object | No |
| attachments | Any attachments in the email | Array | No |
attachments.content | Base64 encoded content of the attachment | String | No |
attachments.file_name | Attached file name | String | No |
| attachments.disposition | Set to inline to embed an image | String | No |
| attachments.content_id | Embedded image ID | String | No |
| dynamic_fields | Personalization fields, e.g., first_name or product_name1. | Object | No |
| unique_args | Tracking arguments for transactional emails. | Object | No |
| callback | Webhook event endpoint object. | Object | No |
callback.url | Callback endpoint URL | String | No |
callback.secret | Secret key used to sign the webhook body | String | No |
| template_id | ID of a transactional email template | String | No |
If the UUID is the identifier and you want to log transactional email events in the Unified Customer Database (UCD), you need to use a different parameter in the Transactional Email API payload.
- Insider has recently added the UUID parameter as a body parameter for the Transactional Email API.
- After you send the request via the Transactional Email API, the Insider Email Team will query the UCD for the profile associated with that UUID using the Profile API. Since each UUID needs to be fetched from the Profile API, the email will be sent to the recipients one by one unlike the current structure that is written under the "to" body parameter.
- If a profile with the UUID exists in the UCD, the email address ("em") of that profile will be retrieved from the UCD. The Transactional Email will be sent to that profile’s email address, and the event will be recorded in the UCD based on the UUID.
- If a profile with the given UUID does not exist in UCD, the transactional email will still be sent to the email address provided in the request. However, the event will not be recorded in UCD for that email address because no profile matching the UUID was found.
- If you are using email as an identifier, you don’t need to utilize the UUID parameter.
Sample Request
Send the following JSON body with a POST request to the endpoint above, including the listed headers.
{
"subject": "Hello",
"tos": [
{
"name": "John Doe",
"email": "sample@useinsider.com",
"uuid": "1234567"
}
],
"from": {
"name": "Posh Street",
"email": "posh@street.com"
},
"content": [
{
"type": "text/html",
"value": "<p>I am {{first_name}}.</p>"
}
],
"reply_to": {
"name": "Reply to",
"email": "sample.reply@useinsider.com"
},
"dynamic_fields": {
"first_name": "John",
"last_name": "Doe",
"product_name1": "Laptop",
"price1": "$1000"
},
"unique_args": {
"category": "Confirmation Email",
"purchase_channel": "App"
},
"attachments": [
{
"content": "aW5zaWRlciB0ZXN0",
"file_name": "file.txt"
}
],
"callback": {
"url": "yourcallbackurl",
"secret": "yoursecret"
}
}Requests with a template
Reference a saved template by template_id. Templates are managed in the Email Template Library.
{
"subject": "Hello",
"tos": [
{
"name": "John Doe",
"email": "sample@useinsider.com"
}
],
"from": {
"name": "Posh Street",
"email": "posh@street.com"
},
"template_id": "275",
"dynamic_fields": {
"first_name": "John",
"last_name": "Doe"
}
}Sample responses
For all sample responses and error codes, refer to the Error Codes.
202 Accepted
This response indicates that your request was successfully completed.
{
"message_id": "8e664ecd-352d-4dbd-9786-ceb78b5b173b",
"status_message": "accepted"
}400 Bad Request
This response indicates that your request is missing the email address in the 'to' parameter.
{
"errors": [
"Missing 'email' on 'tos' parameter"
],
"status_message": "failed to validate request"
}400 Bad Request
This response indicates that the request has an invalid callback URL.
{
"errors": [
"Invalid callback URL in 'url' on 'callback'"
],
"status_message": "failed to validate request"
}This error is triggered for cases like the following:
"url": "domain path"
"url": "htp:/domain"
"url": "example .com"
"url": ""
You need to review and correct the URL. The correct usage can be as follows:
"callback": {
"url": "https://insiderone.com"
}There must be only one URL, and it must be valid and properly formatted.
400
This response indicates that the bytes in dynamic fields exceed the maximum allowed limit.
{
"status_message": "dynamic fields total byte size exceeds the limit of 49300 bytes"
}400 Missing Content Type
This response indicates that the content type header of the request is incorrect.
{
"message": "content type must be application/json",
"status": 400
}400 Missing Subject Line
This response indicates that the request is missing the 'subject' parameter.
{
"errors": [
"Missing 'subject' parameter"
],
"message": "bad-request",
"status": 400
}400 Missing Content
This response indicates that the request is missing the 'content' parameter.
{
"errors": [
"Missing 'content' parameter"
],
"message": "bad-request",
"status": 400
}400 Missing 'from' Parameter
This response indicates that the request is missing the 'from' parameter.
{
"errors": [
"Missing 'from' parameter"
],
"message": "bad-request",
"status": 400
}400 Missing 'to' Parameter
This response indicates that the request is missing the 'to' parameter.
{
"errors": [
"Missing 'to' parameter"
],
"message": "bad-request",
"status": 400
}400 Bad Request
This response indicates that your request contains too many dynamic fields. SendGrid has a limit of 150 dynamic fields per email.
{
"status_message": "parameter 'dynamic_fields' can have size of '150' at most"
}400
This response indicates that customer uses more bytes in dynamic fields body parameter.
{
"status_message": "dynamic fields total byte size exceeds the limit of 49300 bytes"
}400
This response indicates that the total payload limit including HTML and attachments exceeds 30 MB.
{
"status_message": ""
}401 Invalid API Key
This response indicates that the API key provided in the request is invalid, expired, or revoked.
{
"message": "The provided API key is invalid, expired or revoked",
"status": 401
}You need to first check the request headers. The key may have been deleted by another user. You need to verify in the panel that the API key is still active (including whitelist checks if applicable). If the key no longer exists, a new API key must be generated. If a newly generated key still does not work, you should contact the Insider One team.
401 Unauthenticated Domain
This response indicates that your domain is not authenticated.
{
"message": "The domain you are trying to use is not authenticated. Please create a support ticket for the Insider Support Team to authenticate it.",
"status": 401
}If the Insider One team has enabled the Transactional Email Domain Authentication for your account, you can send only from the specific authorized domains. During onboarding, customers must register their sending domains via Add More Domains. This reduces security risks related to unauthorized domain usage.
Before opening a support ticket, you need to verify that the sender domain is properly verified. During onboarding, you must ensure the domain has been authenticated and verified in SendGrid. Otherwise, you might risk spam or block issues.
413 Payload Limit Exceeded
This response indicates that the email payload size exceeds the maximum allowed limit.
{
"status_message": "Email payload limit exceeded"
}500 Internal Server Error
This response indicates that an internal error occurred on the server side and the request could not be processed.
502 Bad Gateway
This response indicates a temporary server-side or network-level issue that prevented the request from being processed.
{
"status_message": "Temporary gateway failure. The request was not processed.",
"timestamp": 1726944657
}503 Service Unavailable
This response indicates that the service is temporarily unavailable due to server overload or maintenance.
In this case, you should check whether other recent requests show similar patterns. As the system may temporarily require scaling, you must retry requests within a 15-minute window (503 can occur at any moment). If 503 errors continue for longer than 15 minutes, you should contact the Insider One team with sample requests.
504 Server Timeout
This response indicates that the server did not receive a timely response from an upstream server.
If a request with the same content is sent for the same user within 15 minutes, the system will return the following message:
"status_message": "This request has already been received and is being processed. Any duplicate content from the user will be ignored for the next 15 minutes."
The cause of this response is typically the system load, but upstream service latency may also trigger it. In this case, you should check the overall 504 ratio across other requests. To avoid message loss, retries should be performed within 15 minutes. The duplicate-prevention mechanisms ensure users won’t receive the same message twice. If 504 errors continue for longer than 15 minutes, you should contact the Insider One team with sample request details.
520 Cloudflare Network Error
This response indicates an unexpected error on the Cloudflare network side, preventing the request from being processed.
Suggested Retry Mechanism: If any of the above errors are encountered (502, 503, 504, 520), the request was not processed successfully on the server side. A retry mechanism is recommended, distributing retries randomly within a 5-minute interval to allow server resources to recover and to prevent accidental duplicate sends
- 202 Accepted → treated as a new valid request, or
- 208 Already Processed → recognized as a duplicate of a request that is already being handled
208 – Already Processed
This status code indicates that the request has already been handled, and repeating it will not trigger a new send.
{
"message_id": "dce90e71-6786-4d69-93eb-5162a2508e15",
"status_message": "This request has already been received and is being processed. Any duplicate content from the user will be ignored for the next 15 minutes.",
"timestamp": 1762942657
}This response does not indicate that the message was dropped, does not relate to suppression logic (unsubscribes, bounces, or spam complaints), or does not prevent message_id creation for valid sends; each successfully processed send still receives its own message_id.
When this response returns, you can try out the following handlings:
- Duplicate requests within 15 minutes
If the same transactional email payload is sent twice within a 15-minute deduplication window, the second request is excluded and returns a 208 response with a body such as the following:
{
"status_message": "This request has already been received and is being processed. Any duplicate content from the user will be ignored for the next 15 minutes"
}- Retry after temporary Gateway Failure (502 → 208)
If the initial request fails with a temporary 502 Bad Gateway, the retry may return 208. In this case:
> The first request was not queued or processed.
> The retry request was successfully accepted and queued.
> 208 indicates that the request was ultimately handled (idempotent acceptance), avoiding duplicate delivery.
- General idempotency handling (Same payload handling)
Even if two requests fail or succeed differently, 208 may be used to prevent the same payload from being processed twice. The API uses idempotency logic so that identical requests do not create multiple sends.
Limitations
- All functions must be executed with a simple HTTPS POST request.
- Only new emails can be sent via this API. No data can be retrieved.
- The API Key should be provided as the authorization key in the request header. If the key is incorrect, the operation will not be executed, and an authorization error will return in the response.
- The total size limit for dynamic fields is 49300 bytes.
- This API is designed exclusively for transactional use cases and must not be used for bulk or promotional emailing.
- The default rate limit is 9000 requests per second per Inone account. Higher limits can be configured on demand by contacting Insider.
The default limit shown here is a standard baseline. If your use case requires higher capacity, feel free to reach out to the Insider One team — we can adjust it to fit your needs.