Zerokit

Errors

Status code + error code catalog across every endpoint.

All error responses share the same shape:

{
  "error": {
    "code": "domain_not_verified",
    "message": "The sender domain has not been verified yet."
  }
}

code is stable — branch on it. message is for humans (logs, dashboards) and may change over time.

Status code semantics

StatusMeaning
200OK. Resource returned.
201Created. New resource returned with its ID.
202Accepted. Work is queued — used for POST /emails.
400Bad request. Body failed validation or required state is missing.
401Unauthorized. Missing / invalid Authorization header.
403Forbidden. Token doesn't have the required scope.
404Not found. Resource doesn't exist (or belongs to another workspace).
409Conflict. Resource already exists (e.g. duplicate domain).
422Unprocessable. Semantically valid but can't be applied (e.g. domain not yet verified).
429Rate limited. Retry-After header indicates how long to wait.
5xxServer-side problem. Retry with exponential backoff.

Common error codes

Auth

CodeStatusCause
unauthorized401Missing/invalid token.
forbidden403Token lacks required scope.
key_revoked401Key was revoked — issue a new one.

Emails

CodeStatusCause
domain_not_verified422from domain not yet verified for this workspace.
body_required400Both html and text missing.
invalid_recipient400to/cc/bcc parse failed or address rejected by validator.
template_not_found404templateId doesn't exist (or was deleted).

Domains

CodeStatusCause
domain_already_exists409Domain is already added to this workspace.
domain_taken_elsewhere409Domain registered against another SES identity in our account.
dns_lookup_failed422DoH lookups for DKIM/SPF/MX records didn't return matching values.

Webhooks

CodeStatusCause
url_must_be_https400Webhook URL uses http://.
events_required400Empty events array.
delivery_not_found404Redeliver target doesn't exist.

Rate limiting

CodeStatusCause
rate_limited429Per-workspace plan limit. Retry-After in seconds.

Provider upstream

CodeStatusCause
provider_unavailable503AWS SES upstream returned 5xx. We retry on send-path; surfaced here so you know.

Don't pattern-match on message strings — they're for humans and can change. Use the stable code field for any programmatic branching.

On this page