Emails
Send an Email
Send a single transactional email. Returns immediately with an email ID; delivery is asynchronous.
POST
/emailsRequest body
| Parameter | Type | Description |
|---|---|---|
fromrequired | string | Sender address. Accepts a bare email or a display name, e.g. "Acme <hello@yourdomain.com>". Must be from a verified domain. |
torequired | string | string[] | Recipient email address(es). Maximum 50. |
subject | string | Email subject line. Required unless using a template that defines one. |
html | string | HTML body of the email. |
text | string | Plain-text body. Used as fallback when HTML is not supported. |
template_id | string (UUID) | ID of a saved React Email template. Overrides html/text/subject from the template. |
variables | object | Template variables to interpolate. Used with template_id. |
cc | string | string[] | CC recipients. Maximum 50. |
bcc | string | string[] | BCC recipients. Maximum 50. |
reply_to | string | string[] | Reply-To address(es). Maximum 50. |
headers | object | Custom email headers as key-value pairs. |
track_opens | boolean | Open tracking via a 1×1 pixel. Default: true — set false to opt out. |
track_clicks | boolean | Click tracking by rewriting links. Default: true — set false to opt out. |
attachments | object[] | File attachments. Up to 20 per message, 10 MB combined. Each item: filename (string) plus exactly one of content (base64-encoded file bytes) or path (a public URL we fetch at send time), optional content_type (inferred from the filename or the fetched response when omitted), and optional content_id to embed the file inline via cid:<content_id>. |
scheduled_at | string (ISO 8601 or natural language) | Schedule the send for a future time, at most 30 days out. Accepts an ISO 8601 timestamp or a natural-language time like "in 1 hour" or "tomorrow at 9am" (parsed server-side). The email is created with status "scheduled" and sends at that time. Reschedule with PATCH /emails/:id or cancel with POST /emails/:id/cancel — see Scheduling. |
ℹ
At least one of html, text, or template_id is required.
Example — plain HTML
curl -X POST https://api.eusend.dev/emails \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@acme.com",
"to": ["alice@example.com", "bob@example.com"],
"subject": "Your order has shipped",
"html": "<p>Your order #1234 is on its way!</p>",
"text": "Your order #1234 is on its way!",
"track_opens": true,
"track_clicks": true
}'{
"id": "9a8b7c6d-5e4f-4a3b-8c1d-0e9f8a7b6c5d"
}Example — with an attachment
Attach a file by passing its bytes base64-encoded as content, or point path
at a public URL and we fetch it at send time. Set content_id to embed an image
inline and reference it from your HTML with <img src="cid:...">.
curl -X POST https://api.eusend.dev/emails \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "billing@acme.com",
"to": "alice@example.com",
"subject": "Your invoice",
"html": "<p>Thanks! Your invoice is attached.</p>",
"attachments": [
{
"filename": "invoice.pdf",
"content": "JVBERi0xLjQKJ...base64...",
"content_type": "application/pdf"
},
{
"filename": "logo.png",
"path": "https://cdn.acme.com/logo.png"
}
]
}'Idempotency
Pass an Idempotency-Key request header to make retries safe. If a request with
the same key has already been accepted for your organisation, the original email
ID is returned immediately and no second send is queued — regardless of how many
times you retry.
| Parameter | Type | Description |
|---|---|---|
Idempotency-Key | string (header) | Any unique string up to 255 characters. A UUID per send is a good default. Omit the header to skip idempotency checks. |
curl -X POST https://api.eusend.dev/emails \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Idempotency-Key: a4f3c2b1-dead-beef-0000-000000000001" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@acme.com",
"to": "alice@example.com",
"subject": "Your receipt",
"html": "<p>Thanks for your order!</p>"
}'ℹ
A duplicate key returns HTTP 200 with the original email ID. The first
successful send always returns HTTP 201.
Example — with a template
curl -X POST https://api.eusend.dev/emails \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@acme.com",
"to": "alice@example.com",
"template_id": "550e8400-e29b-41d4-a716-446655440000",
"variables": {
"first_name": "Alice",
"order_id": "1234",
"tracking_url": "https://track.example.com/1234"
}
}'