Skip to main content
Every error is JSON with at least an error field, optionally a details object with structured context.
{ "error": "identity not found in org", "details": { "handle": "alice.acme@inboxbase.ai" } }

Status codes

StatusMeaning
400Validation error: bad body shape, mutually-exclusive fields, malformed Idempotency-Key.
401Missing or invalid API key.
404Identity or conversation not in this org.
409Idempotency-Key reused with a different body.
429Daily cap exhausted, or all backing mailboxes capped/unhealthy.
5xxServer error. Retry with backoff + Idempotency-Key.

Send rejection reasons

When POST /send returns 200 with rejected recipients, each rejected entry includes a reason. These are the values you may see:
reasonWhat happened
cap_exceededThe identity’s daily cap is exhausted. Wait until midnight UTC, or move the lead to another identity.
no_accountsAll backing mailboxes are at their per-mailbox cap or below the health threshold.
inactiveThe identity is not currently in active state. Most often “still provisioning.”
suspendedThe identity is administratively suspended. Contact support.
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

StatusRetry?How
400NoFix the body shape and try again.
401NoFix the auth header.
404NoVerify the identity handle / convId.
409NoEither reuse the original Idempotency-Key with the original body, or send with a new key.
429LaterDon’t tight-loop. Reschedule the send for after midnight UTC, or to a different identity.
5xxYesExponential backoff. Use the same Idempotency-Key so the retry is safe even if the original succeeded.

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.