Transactional Email API
Send application email, load verified domains and templates, and subscribe to delivery events. These are the production endpoints used by the official Darwa integration for Zapier.
Authentication
Send an OAuth 2.0 access token or a Darwa transactional-email API credential as a Bearer token. Tokens are workspace-scoped. Never place one in browser code or a public repository.
Authorization: Bearer <access_token> Content-Type: application/json
The Zapier integration requests only the scopes needed by its selected operations:
| Field | Type | Required | Description |
|---|---|---|---|
workspace.read | OAuth scope | For connection | Read the connected workspace identity and verified sending domains. |
email.send | OAuth scope | For actions | Send direct and template-based transactional email. |
templates.read | OAuth scope | For templates | List and render published templates. |
events.read | OAuth scope | For triggers | Read recent delivery events for trigger samples and polling. |
webhooks.manage | OAuth scope | For instant triggers | Create and remove Zapier delivery-event subscriptions. |
Send a transactional email
Required scope: email.send. Supply an optional Idempotency-Key header containing a stable event or order identifier to make a retry return the original result instead of sending a duplicate.
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Full sender address on a verified domain. |
to | string[] | Yes | One or more recipient addresses. Across to, cc, and bcc, at most 100 unique recipients are allowed. |
subject | string | Yes | Message subject, up to 255 characters with no line breaks. |
text | string | One body required | Plain-text body, up to 100,000 characters. |
html | string | One body required | HTML body, up to 500,000 characters. |
cc | string[] | No | Carbon-copy recipients. |
bcc | string[] | No | Blind-carbon-copy recipients. |
from_name | string | No | Display name, up to 100 characters. |
reply_to | string | No | Reply-to address. |
curl -X POST 'https://api.darwa.co/api/v1/transactional-email/send' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order_1842_receipt' \
-d '{
"from": "receipts@example.com",
"to": ["customer@example.net"],
"subject": "Your receipt",
"text": "Thank you for your order."
}'{
"id": "message_01J...",
"status": "queued"
}Send a published template
Required scopes: email.send and templates.read. The sender and recipient limits are the same as the direct-send endpoint.
| Field | Type | Required | Description |
|---|---|---|---|
template | string | Yes | Slug of a published template. |
from | string | Yes | Full sender address on a verified domain. |
to | string[] | Yes | Recipient addresses. |
variables | object | No | String, number, boolean, or null values used by the template. |
cc | string[] | No | Carbon-copy recipients. |
bcc | string[] | No | Blind-carbon-copy recipients. |
from_name | string | No | Display name. |
reply_to | string | No | Reply-to address. |
{
"template": "order-confirmation",
"from": "receipts@example.com",
"to": ["customer@example.net"],
"variables": { "name": "Ada", "order_id": "1842" }
}Read the connected account
Required scope: workspace.read.
{
"id": "<workspace_uuid>",
"workspace_id": "<workspace_uuid>",
"workspace_name": "Example workspace",
"user_email": "owner@example.com",
"credential_name": "Zapier"
}List verified sending domains
Required scope: workspace.read. The Zapier app uses this endpoint to populate its Sending Domain field.
[
{
"id": "example.com",
"name": "example.com",
"status": "ready",
"ready": "true"
}
]List published templates
Required scope: templates.read. Draft templates are not returned.
[
{
"id": "order-confirmation",
"name": "Order confirmation",
"slug": "order-confirmation",
"subject": "Order {{order_id}} confirmed",
"variables": ["order_id", "name"],
"version": 3
}
]Manage instant delivery-event hooks
Required scope: webhooks.manage. The target must be a public HTTPS URL that passes Darwa's webhook destination checks.
| Field | Type | Required | Description |
|---|---|---|---|
target_url | string | Yes | Zapier-provided HTTPS hook URL. |
event_types | string[] | Yes | One or more supported delivery-event names. |
{
"target_url": "https://hooks.zapier.com/hooks/standard/123/example",
"event_types": ["delivery", "bounce", "complaint"]
}{ "id": "<hook_uuid>" }A successful deletion returns 204 No Content. Repeating the deletion is safe and also returns 204.
List recent delivery events
Required scope: events.read. Pass an optional event_type query parameter or omit it to return every supported type.
Supported values are queued, delivery, deferred, bounce, complaint, suppression, open, click, reject, and rendering_failure.
curl 'https://api.darwa.co/api/v1/transactional-email/integrations/zapier/events?event_type=delivery' \ -H 'Authorization: Bearer <access_token>'
[
{
"id": "<event_uuid>",
"type": "delivery",
"created_at": "2026-09-27T00:00:00+00:00",
"data": {
"message_id": "message_01J...",
"recipient": "customer@example.net",
"sender": "receipts@example.com",
"subject": "Your receipt",
"occurred_at": "2026-09-27T00:00:00+00:00"
}
}
]Errors and retry behavior
| Status | Meaning | Caller behavior |
|---|---|---|
401 | Missing, expired, revoked, or invalid credential. | Reconnect or replace the credential; do not retry unchanged. |
402 | A paid allowance is required for the requested operation. | Review the workspace plan. |
403 | The token lacks a required scope or workspace access. | Reconnect with the required permissions. |
404 | The workspace resource, template, or connection was not found. | Refresh dynamic fields and verify the selected resource. |
409 | An idempotency key is already processing or was reused with different content. | Honor Retry-After or use the stable key with the original request. |
422 | The request body, event type, sender, template variables, or hook destination is invalid. | Correct the request; do not retry it unchanged. |
429 | A rate or sending allowance was exceeded. | Honor Retry-After and use bounded backoff. |
5xx | Temporary Darwa or provider failure. | Retry with bounded backoff and an idempotency key. |
{ "detail": "Human-readable error description" }