Skip to content

Transactional and test emails

One email to one address: receipts and resets from your app, and tests to your own inbox.

View as Markdown

Send a transactional email

POST/projects/{project_id}/transactional-emails

One email to one address, queued at once (201). Sending the same idempotency_key again returns the first email with 200 and sends nothing. Unsubscribes do not stop it; a blocked address does (422 recipient_blocked).

Parameters

NameInTypeNotes
project_idpathstringRequired

Body

Send JSON with every field; use null for a value you do not set.

FieldTypeNotes
tostringRequired
template_idstring | nullRequired
subjectstring | nullRequired
preview_textstring | nullRequired
htmlstring | nullRequired
markdownstring | nullRequired
variablesobject of stringRequired
reply_tostring | nullRequired
idempotency_keystring | nullRequired
Request
curl -X POST "https://sendocado.com/api/v1/projects/$PROJECT_ID/transactional-emails" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "maya@example.com",
  "template_id": "29be2u66mr26846p7q9m2i0hz2uep1en",
  "subject": null,
  "preview_text": null,
  "html": null,
  "markdown": null,
  "variables": {
    "order_number": "A-1042",
    "total": "$49.00"
  },
  "reply_to": "billing@acme.example",
  "idempotency_key": "order-A-1042-receipt"
}'
Response 201
{
  "id": "qfoeqh3av90ric7phkqdlmtt7ns26lrw",
  "project_id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "send_id": "v7s6ehogfqrclri1qzj865ufrdl1erbf",
  "to": "maya@example.com",
  "subject": "Your Acme receipt for A-1042",
  "preview_text": null,
  "html": "<p>Thanks for your order, {{ first_name | there }}.</p>\n<p>Order {{ variables.order_number }}: {{ variables.total }}</p>\n",
  "text": "Thanks for your order, {{ first_name | there }}.\n\nOrder {{ variables.order_number }}: {{ variables.total }}",
  "merge_tags": ["first_name", "variables.order_number", "variables.total"],
  "variables": {
    "order_number": "A-1042",
    "total": "$49.00"
  },
  "reply_to": "billing@acme.example",
  "source_template_id": "29be2u66mr26846p7q9m2i0hz2uep1en",
  "idempotency_key": "order-A-1042-receipt",
  "status": "queued",
  "created_at": 1790432000000
}

Errors

StatusTypeExample message
400invalid_dataSend a JSON request body.
401unauthorizedSend a valid API key as "Authorization: Bearer sc_…", or sign in.
402plan_limit_reachedYour plan allows 5,000 contacts. Upgrade the plan to add more.
404project_not_foundProject not found.
422recipient_blockedmaya@example.com is blocked in this project: it bounced.
422sender_not_readyVerify the domain of your from address before you send email.
422invalid_referenceNo template with that id in this project.
429rate_limitedToo many requests. Try again in 12 seconds.

List transactional emails

GET/projects/{project_id}/transactional-emails

Newest first, without each email’s body. Kept for 30 days.

Parameters

NameInTypeNotes
project_idpathstringRequired
cursorquerystring | nullOptional
limitqueryintegerOptional, default 50
Request
curl "https://sendocado.com/api/v1/projects/$PROJECT_ID/transactional-emails" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
Response 200
{
  "transactional_emails": [
    {
      "id": "qfoeqh3av90ric7phkqdlmtt7ns26lrw",
      "project_id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
      "send_id": "v7s6ehogfqrclri1qzj865ufrdl1erbf",
      "to": "maya@example.com",
      "subject": "Your Acme receipt for A-1042",
      "preview_text": null,
      "variables": {
        "order_number": "A-1042",
        "total": "$49.00"
      },
      "reply_to": "billing@acme.example",
      "source_template_id": "29be2u66mr26846p7q9m2i0hz2uep1en",
      "idempotency_key": "order-A-1042-receipt",
      "status": "delivered",
      "created_at": 1790432000000
    }
  ],
  "next_cursor": null
}

Errors

StatusTypeExample message
400invalid_datalimit: Too big: expected number to be <=200
401unauthorizedSend a valid API key as "Authorization: Bearer sc_…", or sign in.
404project_not_foundProject not found.
429rate_limitedToo many requests. Try again in 12 seconds.

Get a transactional email

GET/transactional-emails/{transactional_email_id}

status follows the email: queued, sent, then what the provider reported. Get the send for its events and failures.

Parameters

NameInTypeNotes
transactional_email_idpathstringRequired
Request
curl "https://sendocado.com/api/v1/transactional-emails/$TRANSACTIONAL_EMAIL_ID" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
Response 200
{
  "id": "qfoeqh3av90ric7phkqdlmtt7ns26lrw",
  "project_id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "send_id": "v7s6ehogfqrclri1qzj865ufrdl1erbf",
  "to": "maya@example.com",
  "subject": "Your Acme receipt for A-1042",
  "preview_text": null,
  "html": "<p>Thanks for your order, {{ first_name | there }}.</p>\n<p>Order {{ variables.order_number }}: {{ variables.total }}</p>\n",
  "text": "Thanks for your order, {{ first_name | there }}.\n\nOrder {{ variables.order_number }}: {{ variables.total }}",
  "merge_tags": ["first_name", "variables.order_number", "variables.total"],
  "variables": {
    "order_number": "A-1042",
    "total": "$49.00"
  },
  "reply_to": "billing@acme.example",
  "source_template_id": "29be2u66mr26846p7q9m2i0hz2uep1en",
  "idempotency_key": "order-A-1042-receipt",
  "status": "delivered",
  "created_at": 1790432000000
}

Errors

StatusTypeExample message
401unauthorizedSend a valid API key as "Authorization: Bearer sc_…", or sign in.
404transactional_email_not_foundTransactional email not found.
429rate_limitedToo many requests. Try again in 12 seconds.

Send a test email

POST/projects/{project_id}/test-emails

A preview in a real inbox before anyone else gets the email. Merge tags take contact_id’s values when it is set. Test emails are never tracked and have a tighter rate limit.

Limited to 30 requests every 60 minutes, on top of the API limit.

Parameters

NameInTypeNotes
project_idpathstringRequired

Body

Send JSON with every field; use null for a value you do not set.

FieldTypeNotes
tostringRequired
template_idstring | nullRequired
subjectstring | nullRequired
preview_textstring | nullRequired
htmlstring | nullRequired
markdownstring | nullRequired
contact_idstring | nullRequired
Request
curl -X POST "https://sendocado.com/api/v1/projects/$PROJECT_ID/test-emails" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "founder@acme.example",
  "template_id": null,
  "subject": "Welcome to Acme, {{ first_name | there }}",
  "preview_text": null,
  "html": "<p>Hi {{ first_name | there }},</p>\n<p>Thanks for trying Acme. Start with the <a href=\"https://acme.example/setup\">two-minute setup</a>.</p>\n",
  "markdown": null,
  "contact_id": "j8ht9lgmxg9edn581u33xtplpft75v2s"
}'
Response 201
{
  "id": "bqcab69m64p2g158z6tnovmizwdiaeq1",
  "project_id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "send_id": "v7s6ehogfqrclri1qzj865ufrdl1erbf",
  "to": "founder@acme.example",
  "subject": "Welcome to Acme, Maya",
  "status": "queued",
  "created_at": 1790000000000
}

Errors

StatusTypeExample message
400invalid_dataSend a JSON request body.
401unauthorizedSend a valid API key as "Authorization: Bearer sc_…", or sign in.
402plan_limit_reachedYour plan allows 5,000 contacts. Upgrade the plan to add more.
404project_not_foundProject not found.
422recipient_blockedmaya@example.com is blocked in this project: it bounced.
422sender_not_readyVerify the domain of your from address before you send email.
422invalid_referenceNo template with that id in this project.
429rate_limitedToo many requests. Try again in 12 seconds.

Get a test email

GET/test-emails/{test_email_id}

status follows the email, like a transactional email’s.

Parameters

NameInTypeNotes
test_email_idpathstringRequired
Request
curl "https://sendocado.com/api/v1/test-emails/$TEST_EMAIL_ID" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
Response 200
{
  "id": "bqcab69m64p2g158z6tnovmizwdiaeq1",
  "project_id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "send_id": "v7s6ehogfqrclri1qzj865ufrdl1erbf",
  "to": "founder@acme.example",
  "subject": "Welcome to Acme, Maya",
  "status": "delivered",
  "created_at": 1790000000000
}

Errors

StatusTypeExample message
401unauthorizedSend a valid API key as "Authorization: Bearer sc_…", or sign in.
404test_email_not_foundTest email not found.
429rate_limitedToo many requests. Try again in 12 seconds.