# Sendara
> Sendara is an email API for developers and AI agents: send transactional and marketing email from your own domain with inbox-grade deliverability, signed webhooks, audiences, templates, and SDKs in every language. Email-first and built for emerging markets — SMS one-time-passcodes are coming next. No free tier; start on a paid plan.
Base URL: `https://api.sendara.dev`
Docs: https://sendara.dev/docs · OpenAPI: https://sendara.dev/openapi.yaml · Postman collection: https://sendara.dev/sendara.postman_collection.json
## Authentication
Every API request uses a Bearer key: `Authorization: Bearer sk_live_...`.
Manage keys in the dashboard or via the API. Keys are scoped: `send`, `read`, `admin`.
Test-mode keys (`sk_test_...`) simulate delivery — no real email, never billed — and still fire your webhooks. Send to `delivered@`, `bounced@`, or `complained@` (any domain) to drive that simulated outcome and exercise your handlers.
## Sending model: sandbox vs your own domain
Check your state any time: `GET /v1/account/verification` → `{ sandbox_mode, shared_email_sender, channels:[{channel,status,verified,details}] }`.
- Sandbox (new accounts, before you verify a domain you own): you may send only FROM Sendara's shared address (`shared_email_sender`, e.g. `onboarding@sendara.dev`) TO your own account email or an inbox you've verified as a test recipient. `metadata.from_email` is ignored in this mode. This lets you try the full flow before DNS is configured.
- Verified domain (paid plans): once you verify a domain you own, set `metadata.from_email` to an address on it and send to anyone.
## Send email
`POST /v1/send` — `idempotency_key` is required; retries with the same key return the original result.
```
curl https://api.sendara.dev/v1/send \
-H "Authorization: Bearer sk_live_xxx" -H "Content-Type: application/json" \
-d '{"channel":"email","idempotency_key":"evt_1","message_type":"transactional",
"destination":{"email":"user@example.com"},
"payload":{"subject":"Welcome","body_html":"
Welcome
","body_text":"Welcome"},
"metadata":{"from_email":"hello@yourdomain.com"}}'
```
Response 201: `{"id":"msg_...","status":"queued","channel":"email","idempotency_key":"evt_1","created_at":"..."}`.
`message_type` is `transactional` (default) or `marketing`. Render a stored template instead of inline content with `template_id` + `template_vars`. `metadata.test_send:true` sends a real but free, capped email to a verified test recipient.
`POST /v1/send/batch` — a JSON array of send objects; returns per-item success/error in request order.
## Bulk email & broadcasts
`POST /v1/send/bulk` — one email to many in a single call: `audience_list_id` (a contact list) or inline `recipients:[{email,data}]`, plus inline content or a `template_id` rendered per recipient. Returns a broadcast (`bc_...`). Suppressed/unsubscribed recipients are skipped; each recipient send is idempotent.
Campaigns: `POST /v1/broadcasts` (`send_now:true` or `scheduled_at`), `GET /v1/broadcasts`, `GET /v1/broadcasts/{id}` (delivery stats), `POST /v1/broadcasts/{id}/send`, `POST /v1/broadcasts/{id}/cancel`.
## Templates
`POST /v1/templates` `{name,subject,body_html,body_text,variables}` — mustache `{{variables}}` with name/sample/default/required. `GET /v1/templates`, `GET|PUT|DELETE /v1/templates/{id}`, `POST /v1/templates/{id}/render` (preview with vars). Send with `template_id` + `template_vars`.
## Audiences (contacts & lists)
Contacts: `POST /v1/contacts` `{email,first_name,last_name,attributes,tags,email_consent}`, `GET /v1/contacts`, `GET|PUT|DELETE /v1/contacts/{id}`, `POST /v1/contacts/import` (CSV/JSON).
Lists: `POST /v1/contacts/lists`, `GET /v1/contacts/lists`, `GET|PUT|DELETE /v1/contacts/lists/{id}`, `GET /v1/contacts/lists/{id}/members`, `POST /v1/contacts/lists/{id}/members`, `DELETE /v1/contacts/lists/{id}/members/{contactId}`.
## Domains & deliverability
`POST /v1/domains` `{domain}` returns the exact DKIM, SPF, DMARC and custom MAIL FROM records to publish. `GET /v1/domains`, `GET /v1/domains/{domain}`, `POST /v1/domains/{domain}/verify` (re-check; we also re-verify in the background and email you when it lands). Hard bounces and complaints are auto-suppressed to protect your reputation.
BIMI (your logo in the inbox): `GET|PUT /v1/domains/{domain}/bimi` `{logo_url}`, `POST /v1/domains/{domain}/bimi/logo` (upload a square SVG Tiny PS).
## Test recipients (sandbox receiving)
`GET /v1/test-recipients`, `POST /v1/test-recipients` `{email}` (sends a verification link; up to 3), `POST /v1/test-recipients/{id}/resend`, `DELETE /v1/test-recipients/{id}`. Verified test recipients are the only addresses a sandbox account can send to; these test sends deliver for real, are capped per inbox per day, and are never billed.
## Messages & events
`GET /v1/messages?channel=&status=&limit=&cursor=` → `{messages,next_cursor}` (cursor pagination). `GET /v1/messages/{id}` returns the message with its full event timeline.
Event types: `delivered`, `opened`, `bounced`, `complained`.
## Webhooks (signed)
`POST /v1/webhooks` `{endpoint_url,event_types}` returns a signing secret; `GET /v1/webhooks`, reveal/rotate the secret, and delete a subscription.
Every delivery is signed: headers `Sendara-Timestamp` and `Sendara-Signature`. The signature is the lowercase-hex HMAC-SHA256 of `"{Sendara-Timestamp}.{raw_request_body}"` keyed by your signing secret. Reject timestamps older than 5 minutes (replay protection). All SDKs ship a webhook-verify helper.
## Suppressions
`GET /v1/suppressions`, `POST /v1/suppressions` `{email,reason}`, `DELETE /v1/suppressions?email=`. Manage the addresses you never want to re-send to.
## API keys, usage & billing
Keys: `GET /v1/keys`, `POST /v1/keys` `{name,scopes}` (admin scope; the secret is shown once), rotate, and revoke.
Usage: `GET /v1/usage?period=YYYY-MM` (counts + cost in micro-dollars).
Billing: `GET /v1/billing`, `POST /v1/billing/checkout` `{plan:"starter"|"pro"|"scale",period:"month"|"year"}`, `POST /v1/billing/portal`.
Plans (no free tier): Starter $5.99/mo (10,000 emails), Pro $20/mo (50,000), Scale $79/mo (150,000); overage $0.75 per 1,000 emails ($0.45 on Scale). Pay yearly for two months free. Unlimited verified domains on every plan.
## Errors
`{"error":{"code":"...","message":"...","status":N}}`. Common codes: `unauthorized` (401), `forbidden` (403, wrong scope), `invalid_request` (400/422), `from_not_verified` (422), `domain_not_verified` (422), `recipient_suppressed` (409), `rate_limit_exceeded` (429), `spend_cap_exceeded` (402).
## Rate limits
Per-key sliding window. `429` responses carry `Retry-After`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`. SDKs retry automatically, honoring `Retry-After`.
## SDKs
- Node / TypeScript: `npm i sendara` — `new Sendara(key).emails.send({ from, to, subject, html, text })`
- Python: `pip install sendara` — `Sendara(key).emails.send(to=..., subject=..., html=...)` (sync + async)
- Go: `go get github.com/sendaramail/sendara-go` — `client.Emails.Send(ctx, sendara.EmailSendParams{ From, To, Subject, HTML })`
- React Email: `npm i @sendaramail/react-email` — author emails as JSX and `renderEmail()` to `{ html, text }`
All SDKs include idempotent retries, auto-pagination, typed errors, and a webhook-verify helper.
## Links
Docs: https://sendara.dev/docs · SDKs: https://sendara.dev/docs/sdks · AI agents guide: https://sendara.dev/docs/agents · OpenAPI: https://sendara.dev/openapi.yaml · Postman: https://sendara.dev/sendara.postman_collection.json