Email Transmissions API
Overview
The Transmissions endpoint sends email directly — to a single recipient or to thousands — using either a stored email template or inline HTML content. It is independent of the Marketing Campaigns email flow: use it for transactional sends, one-off broadcasts, or any case where you want to control recipients and content directly through the API rather than building a campaign.
Authentication
All endpoints require API key authentication:
X-API-Key: your-api-key-here
Send a transmission
POST /api/transmissions
Request body
| Field | Type | Required | Description |
|---|---|---|---|
options | object | Yes | Delivery options. transactional (boolean) is required; see Options below. |
recipients | array | Yes | 0–5000 recipient objects. |
content | object | Yes | Either { template_id, attachments? } (stored template) or { from, subject, html, reply_to?, attachments? } (inline content). |
campaign_id / campaign_code | string | No | Free-form label, max 64 bytes, used for grouping in analytics. |
description | string | No | Max 1024 bytes. |
metadata | object | No | Key/value pairs available in webhook events and to the template engine. Max 10KB. |
substitution_data | object | No | Key/value pairs passed to the template engine. Max 100KB. |
return_path | string | No | Envelope-From address; domain must be a CNAME-verified sending domain. |
Options
| Field | Type | Description |
|---|---|---|
transactional | boolean | Required. Distinguishes transactional from marketing messages for unsubscribe/suppression handling. |
scheduled_time | object | { date, timezone } — schedule delivery instead of sending immediately. timezone is one of America/Sao_Paulo, Australia/Brisbane, Australia/Sydney, UTC. |
open_tracking / click_tracking / initial_open | boolean | Override tracking defaults. |
sandbox | boolean | Send from the sandbox sending domain. |
skip_suppression | boolean | Bypass suppression rules — use with care. |
ip_pool | string | Dedicated IP pool ID. |
inline_css | boolean | Inline <style> CSS into the rendered HTML. |
perform_substitutions | boolean | Disable substitutions (only valid with inline content). |
Example request — stored template
curl -X POST \
https://apis.app.stack9.co/api/transmissions \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"options": { "transactional": true },
"recipients": [
{ "address": { "email": "customer@example.com", "name": "Jane Customer" } }
],
"content": { "template_id": "tmpl_password_reset" },
"substitution_data": { "reset_link": "https://app.example.com/reset/abc123" }
}'
Example request — inline content
{
"options": { "transactional": false },
"recipients": [
{ "address": "visitor@example.com", "tags": ["newsletter"] }
],
"content": {
"from": { "name": "Acme Co", "email": "news@acme.example.com" },
"subject": "This week at Acme",
"html": "<h1>This week</h1><p>Hello!</p>"
}
}
Example response
{ "transactionId": "txn_9kL3mP5n" }
Not implemented
The spec's content field documents A/B test content and RFC822 content as conceptual options in addition to stored template and inline content, but both are explicitly marked NOT IMPLEMENTED in the current contract. Use a stored template or inline content only.
Recipients
Each recipient object supports:
| Field | Type | Description |
|---|---|---|
address | string or object | A plain email string, or { email, name?, header_to? }. |
tags | string[] | Up to 10 tags per recipient (100 tenant-wide); surfaced in webhook events. |
metadata | object | Key/value pairs, max 10KB per recipient; recipient metadata overrides transmission-level metadata on conflict. |
substitution_data | object | Key/value pairs for the template engine, max 100KB per recipient; overrides transmission-level substitution data on conflict. Not included in webhook events. |
Related
- Email Templates API — manage the
template_idvalues you can reference here. - Email Settings API — sending domains, suppressions, and the SparkPost-backed email event webhooks (a different mechanism from the Webhooks API).