Sending

Testing & sandbox

Build and verify your entire send-and-webhook flow before a single real email goes out — then smoke-test production for free.

Sendara gives you two ways to test. The sandbox uses a test key to simulate every outcome — delivered, bounced, complained — without sending real mail or being billed, while still firing your webhooks. Verified test recipients go one step further: they send real email to a handful of your own addresses, for free, so you can validate production against a real verified domain before launch.

Test keys

Every account has live and test API keys. A test key (sk_test_…) runs the full pipeline — idempotency, suppression, templates, events, webhooks — but stops short of handing the message to a real provider. Nothing is sent and nothing is billed. Live keys (sk_live_…) send real mail and are billed.

Swapping a single environment variable from sk_test_… to sk_live_… is all it takes to go from sandbox to production — the request shape is identical.

Wire your test suite and local dev against a test key. Because webhooks still fire, you can exercise your event handlers end to end long before you publish a sending domain.

Simulated outcomes

In the sandbox, the recipient address drives the simulated outcome — specifically the local-part (the bit before the @), so the domain can be anything. Send to bounced@ to drive a bounce, complained@ to drive a complaint, or anything else to get a clean delivery.

Recipient local-partFinal statusEvents fired
delivered@deliveredaccepted → delivered
bounced@ / bounce@bouncedbounced (recipient suppressed)
complained@ / complaint@complainedcomplained (recipient suppressed)
anything elsedeliveredaccepted → delivered

The example below drives a simulated bounce. Swap the local-part to steer the outcome — the rest of the request stays the same.

A simulated bounced or complained outcome suppresses that recipient on the account, exactly as in production. If a later send to the same address returns recipient_suppressed(409), that's expected — remove the suppression to send again.

Webhooks in the sandbox

Sandbox sends fire the same webhook events as production, so you can test your handler against a real signed payload. Each event is delivered as a POST with a JSON body and these headers:

  • Sendara-Event-Id — unique per event; reused across retries of the same event, so use it to dedupe.
  • Sendara-Event-Type — e.g. delivered, bounced, complained.
  • Sendara-Timestamp — Unix epoch seconds when the signature was computed.
  • Sendara-Signature — the HMAC signature (see below).
{
  "id": "ev_2",
  "type": "delivered",
  "message_id": "msg_a1b2c3",
  "channel": "email",
  "occurred_at": "2026-06-14T10:00:12Z"
}

Verifying the signature

Verify every webhook before trusting it. The signature is HMAC-SHA256(secret, "{timestamp}.{raw_body}"), hex-encoded. Build the signed string by concatenating the Sendara-Timestamp header, a literal ., and the exact raw request body — then compare in constant time.

Sign the raw bytes of the body, before any JSON parsing or re-serialization. Re-encoding changes whitespace and key order, which breaks the signature.

Treat handlers as idempotent — an event may be delivered more than once, and retries reuse the same Sendara-Event-Id. Failed deliveries are retried with backoff. Respond 2xx to acknowledge.

Verified test recipients

The sandbox simulates; it never puts a real email in a real inbox. When you need to confirm rendering, deliverability, and your verified domain in production — without spending money or risking your live list — register verified test recipients. These are your own addresses, verified by email, that you can send real mail to for free.

The guardrails:

  • Up to 3 test recipients per account.
  • Each verified address accepts at most 10 test sends per day (per UTC day).
  • Sends use a live key with test_send: true and are never billed.

Register & verify

Register an address with POST /v1/test-recipients (requires the admin scope). Sendara emails that address a verification link; once the recipient clicks it, the address flips to verified and is eligible for test sends.

curl https://api.sendara.dev/v1/test-recipients \
  -H "Authorization: Bearer sk_live_admin_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "email": "you@yourcompany.com" }'
{
  "id": "tr_4f1a8c2d9e",
  "email": "you@yourcompany.com",
  "status": "pending",
  "created_at": "2026-06-14T10:00:00Z"
}
emailstringRequired
One of your own addresses to validate against. Up to 3 per account; a verification email is sent on creation.

List your recipients with GET /v1/test-recipients (requires read) to check verification status. You can re-send the verification email with POST /v1/test-recipients/{id}/resend, or remove an address with DELETE /v1/test-recipients/{id} (both require admin).

{
  "recipients": [
    { "id": "tr_4f1a8c2d9e", "email": "you@yourcompany.com",
      "status": "verified", "verified_at": "2026-06-14T10:02:30Z",
      "created_at": "2026-06-14T10:00:00Z" }
  ]
}

Sending a real test email

Once an address is verified, send to it with a normal POST /v1/send using a live key and test_send: true. The destination must be a verified test recipient on your account, the per-day cap applies, and — because the send is free — the spend cap is skipped entirely.

This is the right tool for production smoke tests, UAT sign-off, and confirming a freshly verified domain actually lands in the inbox — all before you point your app at real customers.

Errors

Two error codes are specific to this flow:

  • recipient_not_verified(403) — the destination isn't a verified test recipient on your account. Register and verify it first, or drop test_send to send normally.
  • test_send_daily_limit (429) — this address has used its 10 free test sends for the current UTC day. Wait for the next day or use a different verified address.

Registering a fourth address returns too_many_test_recipients (422) — delete one first.

From sandbox to production

A reliable path to your first real production send:

  • Build against sk_test_… and drive delivered@, bounced@, and complained@ to exercise every branch and your webhook handler.
  • Verify your sending domain (see Domains & deliverability).
  • Register a verified test recipient and send a real test_send: true email to confirm rendering and inbox placement on your verified domain — for free.
  • Swap to sk_live_… and ship.