Skip to main content
Every error is JSON with at least an error field, optionally a details object with structured context.

Status codes

Send rejection reasons

When POST /send returns 200 with rejected recipients, each rejected entry includes a reason. These are the values you may see: When the whole request is rejected (not just one recipient), status is 429 and the body has the same shape with accepted: 0.

Retry guidance

Common errors and fixes

Most often a typo in the handle, or the request was made with a key from a different org. Confirm the handle in Dashboard → Identities and that the key prefix matches an active key in the same org.
The same key was used with a different body. Either you actually meant to send a different message — in which case use a new key — or the retry that triggered this is using a slightly different body (often a reformatted timestamp or a re-rendered template). Make the body deterministic for retries.
Daily caps are per-identity, set by tier, and reset at midnight UTC. A Starter tier identity is capped at 150/day. Check Dashboard → Identities → the identity detail page shows current usage on a rolling graph.
Every backing mailbox is either at its per-mailbox daily cap or has dropped below the health threshold. This usually means the identity is pulling more than its tier supports — bumping tier provisions more mailboxes. If health is the issue, the dashboard will surface it on the identity detail page.
Three possibilities:
  1. Endpoint paused. Your URL returned 410 Gone, or three consecutive failed deliveries triggered an automatic pause. Re-enable from the dashboard.
  2. Secret rotated. Your verifier is using the old secret and rejecting deliveries. Update your secret env var.
  3. DNS / TLS. The endpoint URL stopped resolving or its TLS certificate expired. Test with curl from outside your network.
In all three cases your recovery path is the same: walk the events stream from the last seq you persisted to backfill missed events, then fix the underlying issue.