eusend
Emails

Send an Email

Send a single transactional email. Returns immediately with an email ID; delivery is asynchronous.

POST/emails

Request body

ParameterTypeDescription
fromrequiredstringSender address. Accepts a bare email or a display name, e.g. "Acme <hello@yourdomain.com>". Must be from a verified domain.
torequiredstring | string[]Recipient email address(es). Maximum 50.
subjectstringEmail subject line. Required unless using a template that defines one.
htmlstringHTML body of the email.
textstringPlain-text body. Used as fallback when HTML is not supported.
template_idstring (UUID)ID of a saved React Email template. Overrides html/text/subject from the template.
variablesobjectTemplate variables to interpolate. Used with template_id.
ccstring | string[]CC recipients. Maximum 50.
bccstring | string[]BCC recipients. Maximum 50.
reply_tostring | string[]Reply-To address(es). Maximum 50.
headersobjectCustom email headers as key-value pairs.
track_opensbooleanOpen tracking via a 1×1 pixel. Default: true — set false to opt out.
track_clicksbooleanClick tracking by rewriting links. Default: true — set false to opt out.
attachmentsobject[]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_atstring (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

request
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
  }'
response — 201 Created
{
  "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:...">.

request
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.

ParameterTypeDescription
Idempotency-Keystring (header)Any unique string up to 255 characters. A UUID per send is a good default. Omit the header to skip idempotency checks.
request
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

request
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"
    }
  }'