Error codes
Every API error is a JSON body with code, error, hint and retryable. Codes are stable; a client may switch on them. This page lists the ones an integration is most likely to meet.
Request and auth
bad_json- the body is not valid JSON. Fix the body.validation- a field is missing or invalid. Thehintnames the field.bad_id- a path or body identifier is not a UUID.token_expired- the API key passed itsexpires_at. Create a new key.forbidden- the key or member lacks the scope named inhint.not_found- the resource does not exist in this workspace.
Sending
suppressed- the recipient is on the suppression list. Remove it only with the recipient's consent.newsletter_consent_missing- a newsletter send needs a newsletter channel grant. Import the address as active or complete double opt-in.consent_withdrawn- the recipient opted out. Do not send again.impressum_incomplete- a marketing send needs the legal sender fields (street and city).route_kind_mismatch- a newsletter must use thebroadcastroute, transactional mail usesoutgoing.safe_mode- the workspace or project is in the sandbox and the recipient is not a simulator or allowlisted address.content_blocked- the content gate refused the message. The response carries the reasons.scanner_unavailable- the spam filter is unreachable, so marketing is refused; retry later. Transactional mail keeps running.send_failed- the provider did not accept the message; the hint says whether a retry helps.
Agent keys
recipient_not_allowed- the recipient is outside the key's allowlist.approval_required- the recipient count is above the key's threshold. A human must approve, and theapproval.requiredevent fires.token_daily_cap_reached- the key reached its daily cap. It resets at midnight UTC.
Idempotency
idempotency_key_reuse- the same key was used with a different body. Use a new key for a new request.idempotency_in_progress- the first request with this key is still running. Retry afterRetry-After.
Inbound and forwarding
attachments_not_supported- attachments are not accepted; the sender gets a notice.inbound_message_truncated- reserved for setups with raw storage; the message was larger than the receiving path can read.
retryable: true means the same request may succeed later. retryable: false means retrying unchanged will fail again.