Point an MX record at Sendara and every email to that domain is received, scanned, parsed into structured fields (from, to, subject, text, HTML, attachments) and delivered to you two ways: a real-time email.received webhook, and a GET /v1/inbound pull API.
Enable a domain
Receiving is enabled on a verified domain. Enabling returns the MX record to publish at your DNS provider.
inbound.yourdomain.com instead so your existing mail is untouched.curl -X POST https://api.sendara.dev/v1/domains/dom_abc123/inbound \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'{ "enabled": true, "mx_record": { "type": "MX", "priority": "10", "value": "inbound-smtp.us-east-1.amazonaws.com" } }Prefer zero setup? Every account also has a hosted test inbox at <account_id>@inbound.sendara.dev — email it from anywhere to see receiving work with no DNS changes.
The email.received webhook
Subscribe a webhook to the email.received event. Each received message is delivered as a signed POST (verified exactly like every other Sendara webhook). Like every event, it arrives wrapped in the standard envelope — top-level keys are event_id / event_type, and the inbound email lives under payload (abbreviated below; the full payload also carries cc, headers, size_bytes, thread_id, rfc_message_id, in_reply_to, references_ids, normalized_subject, and an s3_key on each attachment):
{
"event_id": "evt_inb_9f21",
"event_type": "email.received",
"message_id": "inb_9f21",
"account_id": "acct_abc123",
"payload": {
"id": "inb_9f21",
"domain": "inbound.yourdomain.com",
"recipient": "[email protected]",
"from": "Alice <[email protected]>",
"to": ["[email protected]"],
"cc": [],
"subject": "Need help with my order",
"text": "Hi, my order hasn't arrived…",
"html": "<p>Hi, my order hasn't arrived…</p>",
"spf_verdict": "PASS",
"dkim_verdict": "PASS",
"dmarc_verdict": "PASS",
"spam_verdict": "PASS",
"virus_verdict": "PASS",
"size_bytes": 84992,
"thread_id": "thr_5c10",
"attachments": [{ "filename": "receipt.pdf", "content_type": "application/pdf", "size": 84211, "s3_key": "inbound/acct_abc123/inb_9f21/receipt.pdf" }],
"received_at": "2026-06-17T10:02:00Z"
},
"occurred_at": "2026-06-17T10:02:00Z",
"created_at": "2026-06-17T10:02:01Z"
}Pull API
List and fetch received mail over the API — useful for backfill or if you'd rather poll than run a webhook.
# list recent inbound emails (bodies omitted)
curl https://api.sendara.dev/v1/inbound \
-H "Authorization: Bearer sk_live_xxx"
# fetch one with full body + attachments metadata
curl https://api.sendara.dev/v1/inbound/inb_9f21 \
-H "Authorization: Bearer sk_live_xxx"
# download an attachment by index
curl https://api.sendara.dev/v1/inbound/inb_9f21/attachments/0 \
-H "Authorization: Bearer sk_live_xxx" -o receipt.pdfRouting rules
By default every received message fires email.received to your subscribed webhooks. Routing rules let you also forward specific addresses to a dedicated endpoint — e.g. support@ to your ticketing system and billing@ elsewhere.
curl https://api.sendara.dev/v1/inbound/routes \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"domain": "inbound.yourdomain.com",
"match_prefix": "support",
"forward_url": "https://app.yourcompany.com/hooks/inbound"
}'The response includes a signing_secret (shown once). Each forwarded POST carries a combined Sendara-Signature: t=<ts>,v1=<hmac> header (Stripe-style): split on ,, take the t= timestamp and v1= signature, then recompute an HMAC-SHA256 over "<t>.<rawBody>" with the route's signing_secret and compare in constant time.
Sendara-Signature plus a separate Sendara-Timestamp header — so the SDK verifyWebhook helpers apply to those, not to route forwards. Verify route forwards with the combined-header steps above.