Documentation / API reference

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.

REST + JSONOAuth 2.0 or API keyBase URL: api.darwa.co/api/v1

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.

request header
Authorization: Bearer <access_token>
Content-Type: application/json

The Zapier integration requests only the scopes needed by its selected operations:

FieldTypeRequiredDescription
workspace.readOAuth scopeFor connectionRead the connected workspace identity and verified sending domains.
email.sendOAuth scopeFor actionsSend direct and template-based transactional email.
templates.readOAuth scopeFor templatesList and render published templates.
events.readOAuth scopeFor triggersRead recent delivery events for trigger samples and polling.
webhooks.manageOAuth scopeFor instant triggersCreate and remove Zapier delivery-event subscriptions.

Send a transactional email

POST/transactional-email/sendQueue a message from a verified Darwa sending domain.

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.

FieldTypeRequiredDescription
fromstringYesFull sender address on a verified domain.
tostring[]YesOne or more recipient addresses. Across to, cc, and bcc, at most 100 unique recipients are allowed.
subjectstringYesMessage subject, up to 255 characters with no line breaks.
textstringOne body requiredPlain-text body, up to 100,000 characters.
htmlstringOne body requiredHTML body, up to 500,000 characters.
ccstring[]NoCarbon-copy recipients.
bccstring[]NoBlind-carbon-copy recipients.
from_namestringNoDisplay name, up to 100 characters.
reply_tostringNoReply-to address.
request
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."
  }'
202 response
{
  "id": "message_01J...",
  "status": "queued"
}

Send a published template

POST/transactional-email/send-templateRender and queue a published Darwa template.

Required scopes: email.send and templates.read. The sender and recipient limits are the same as the direct-send endpoint.

FieldTypeRequiredDescription
templatestringYesSlug of a published template.
fromstringYesFull sender address on a verified domain.
tostring[]YesRecipient addresses.
variablesobjectNoString, number, boolean, or null values used by the template.
ccstring[]NoCarbon-copy recipients.
bccstring[]NoBlind-carbon-copy recipients.
from_namestringNoDisplay name.
reply_tostringNoReply-to address.
request body
{
  "template": "order-confirmation",
  "from": "receipts@example.com",
  "to": ["customer@example.net"],
  "variables": { "name": "Ada", "order_id": "1842" }
}

Read the connected account

GET/transactional-email/integrations/zapier/accountReturn the identity shown for a Zapier app connection.

Required scope: workspace.read.

200 response
{
  "id": "<workspace_uuid>",
  "workspace_id": "<workspace_uuid>",
  "workspace_name": "Example workspace",
  "user_email": "owner@example.com",
  "credential_name": "Zapier"
}

List verified sending domains

GET/transactional-email/integrations/zapier/domainsList verified domains available to a Zapier email action.

Required scope: workspace.read. The Zapier app uses this endpoint to populate its Sending Domain field.

200 response
[
  {
    "id": "example.com",
    "name": "example.com",
    "status": "ready",
    "ready": "true"
  }
]

List published templates

GET/transactional-email/templatesList templates available to the connected workspace.

Required scope: templates.read. Draft templates are not returned.

200 response
[
  {
    "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

POST/transactional-email/integrations/zapier/hooksSubscribe a Zapier target URL to selected event types.

Required scope: webhooks.manage. The target must be a public HTTPS URL that passes Darwa's webhook destination checks.

FieldTypeRequiredDescription
target_urlstringYesZapier-provided HTTPS hook URL.
event_typesstring[]YesOne or more supported delivery-event names.
request body
{
  "target_url": "https://hooks.zapier.com/hooks/standard/123/example",
  "event_types": ["delivery", "bounce", "complaint"]
}
201 response
{ "id": "<hook_uuid>" }
DELETE/transactional-email/integrations/zapier/hooks/{hook_id}Remove a Zapier-owned delivery-event subscription.

A successful deletion returns 204 No Content. Repeating the deletion is safe and also returns 204.

List recent delivery events

GET/transactional-email/integrations/zapier/eventsReturn up to 20 recent events for trigger samples and polling.

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.

request
curl 'https://api.darwa.co/api/v1/transactional-email/integrations/zapier/events?event_type=delivery' \
  -H 'Authorization: Bearer <access_token>'
200 response
[
  {
    "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

StatusMeaningCaller behavior
401Missing, expired, revoked, or invalid credential.Reconnect or replace the credential; do not retry unchanged.
402A paid allowance is required for the requested operation.Review the workspace plan.
403The token lacks a required scope or workspace access.Reconnect with the required permissions.
404The workspace resource, template, or connection was not found.Refresh dynamic fields and verify the selected resource.
409An idempotency key is already processing or was reused with different content.Honor Retry-After or use the stable key with the original request.
422The request body, event type, sender, template variables, or hook destination is invalid.Correct the request; do not retry it unchanged.
429A rate or sending allowance was exceeded.Honor Retry-After and use bounded backoff.
5xxTemporary Darwa or provider failure.Retry with bounded backoff and an idempotency key.
error response
{ "detail": "Human-readable error description" }