Skip to content

Errors

Every error is application/problem+json (RFC 9457) with extra fields that make it easy for an agent to act on:

{
"type": "https://docs.simail.ai/errors#rate_limited",
"title": "RateLimitedError",
"status": 429,
"detail": "Too many requests.",
"instance": "/v0/inboxes",
"name": "RateLimitedError",
"code": "rate_limited",
"message": "Too many requests.",
"fix": "Wait for Retry-After seconds, then retry.",
"docs": "https://docs.simail.ai/errors#rate_limited",
"retryable": true,
"request_id": "req_…"
}
Field Meaning
code stable machine-readable code (below); branch on this, not on message
retryable true only when retrying the same request later can succeed
fix one-line hint for the caller
request_id also in the x-request-id response header; include it when you contact support
human_message when present, a message meant for the human behind the agent; forward it verbatim

Every 429 and retryable 503 includes Retry-After. Error bodies never contain message content, codes or secrets.

Code HTTP Retryable
validation_error 400 no
invalid_request 400 no
unauthorized 401 no
step_up_required 401 no
missing_permission 403 no
human_required 403 no
origin_mismatch 403 no
signup_closed 403 no
account_inactive 403 no
account_suspended 403 no
claim_required 403 no
invite_invalid 403 no
not_found 404 no
method_not_allowed 405 no
conflict 409 no
idempotency_conflict 409 no
duplicate_send 409 no
address_unavailable 409 no
gone 410 no
payload_too_large 413 no
message_too_large 413 no
unsupported_media_type 415 no
send_blocked 422 no
invalid_header 422 no
webhook_target_forbidden 422 no
thread_locked 423 no
rate_limited 429 yes
daily_limit_exceeded 429 yes
internal_error 500 yes
not_implemented 501 no
sending_paused 503 yes
upstream_unavailable 503 yes

HTTP 400 · retryable: no · ValidationError

A field is missing, has the wrong type or is out of range. The body has errors: [{ path, message }]. Also returned when a send has no Idempotency-Key, and when POST /v0/waitlist contains human_email or any other unknown field.

Fix: Correct the fields listed in errors and retry.

HTTP 400 · retryable: no · InvalidRequestError

The request is malformed in a way that is not about one field (for example an unparseable page_token, or a page token or events cursor used with another key scope or query).

Fix: Check the request format against the API reference.

HTTP 401 · retryable: no · UnauthorizedError

The API key is missing, malformed, expired or revoked. Also returned by /mcp without a key, with a human_message pointing to /v0/beta.

Fix: Send a valid API key as Authorization: Bearer <key>.

HTTP 401 · retryable: no · StepUpRequiredError

Console only: the action needs a passkey assertion or a fresh email code from the last 5 minutes.

Fix: Re-authenticate with a passkey or a fresh email code, then retry.

HTTP 403 · retryable: no · ForbiddenError

The object is in your key’s scope but the key lacks the permission. May carry reason, for example inbox_limit.

Fix: Use a key that has the required permission and scope.

HTTP 403 · retryable: no · HumanRequiredError

Only a human can do this, in the console: creating API keys or webhooks, loosening lists, releasing held mail, approving sends.

Fix: Only a human can do this, in the console at app.simail.ai.

HTTP 403 · retryable: no · ForbiddenError

Console only: a state-changing request did not come from https://app.simail.ai.

Fix: Console API calls must come from the console origin.

HTTP 403 · retryable: no · SignupClosedError

Sign-up without a valid directed code during the private beta. Carries waitlist_url and human_message (en, zh). Do not retry, do not try another username or email; forward human_message to your human. See Private beta.

Fix: Do not retry. Forward human_message to your human; join the waitlist at waitlist_url.

HTTP 403 · retryable: no · AccountInactiveError

Console only: the account is waitlisted, invited but not activated, or not accepted.

Fix: This account is not active yet. Check your status page.

HTTP 403 · retryable: no · AccountSuspendedError

Sending is paused for the organization (for example after a bounce or complaint spike). Receiving and reading still work. The console shows the reason.

Fix: Sending is suspended for this organization. See the console for the reason.

HTTP 403 · retryable: no · ClaimRequiredError

A restricted key from agent sign-up was used before a human claimed the agent. Only GET /v0/auth/me and GET /v0/beta work until then.

Fix: Ask your human to claim this inbox in the console; until then only /v0/auth/me and /v0/beta work.

HTTP 403 · retryable: no · InviteInvalidError

The invite code is wrong, used, expired, revoked or bound to another email. Repeated failures lock redemption for an hour.

Fix: Check the code. Codes are single-use, expire, and are bound to one email.

HTTP 404 · retryable: no · NotFoundError

The object does not exist or is outside your key’s scope. SiMail never reveals whether another organization’s object exists.

Fix: Check the resource ID and that your key’s scope includes it.

HTTP 405 · retryable: no · MethodNotAllowedError

The path exists but not with this HTTP method.

Fix: Use a supported HTTP method.

HTTP 409 · retryable: no · ConflictError

The object changed state. For cancel: reason is already_sending or already_final.

Fix: Reload the resource and retry with current state.

HTTP 409 · retryable: no · IdempotencyConflictError

The Idempotency-Key was already used with a different request body.

Fix: Reuse an Idempotency-Key only with an identical request body.

HTTP 409 · retryable: no · DuplicateSendError

An identical message (same sender, recipients, subject and body) was sent inside the de-duplication window. Do not resend.

Fix: An identical message was already sent recently; do not resend.

HTTP 409 · retryable: no · AddressUnavailableError

The username is taken, reserved, too similar to a reserved name, or retired. Addresses are never reassigned to another organization.

Fix: Choose another username; this address is reserved or retired.

HTTP 410 · retryable: no · GoneError

The resource expired or was deleted, for example an events cursor older than 30 days.

Fix: The resource expired or was deleted.

HTTP 413 · retryable: no · PayloadTooLargeError

The request body exceeds 1 MiB (5 MiB for sends with inline attachments).

Fix: Reduce message or attachment size.

HTTP 413 · retryable: no · MessageTooLargeError

The outbound message would exceed 5 MiB including encoding, or has more than 32 attachments. Carries limit_bytes and estimated_bytes.

Fix: Outbound mail is limited to about 5 MiB including attachments (at most 32). Remove or shrink attachments.

HTTP 415 · retryable: no · UnsupportedMediaTypeError

The body is not application/json.

Fix: Send application/json.

HTTP 422 · retryable: no · SendBlockedError

The pre-send check refused the message. reasons lists why (see Sending); flags may list risk flags.

Fix: The pre-send check rejected this message; see reasons.

HTTP 422 · retryable: no · InvalidHeaderError

A header field (subject, display name, address) contains CR, LF, NUL or another control character.

Fix: Remove CR, LF, NUL and non-printable characters from header fields.

HTTP 422 · retryable: no · WebhookTargetForbiddenError

The webhook URL is not a public https:// host on port 443, or points at a SiMail-owned domain.

Fix: Use a public https URL outside simail-owned zones.

HTTP 423 · retryable: no · ThreadLockedError

A human has taken over the thread. Wait for thread.unlocked.

Fix: A human has taken over this thread; wait until it is unlocked.

HTTP 429 · retryable: yes · RateLimitedError

Too many requests. Wait for Retry-After seconds.

Fix: Wait for Retry-After seconds, then retry.

HTTP 429 · retryable: yes · DailyLimitExceededError

A daily quota is used up. Retry after Retry-After.

Fix: The daily send limit is reached; retry after Retry-After.

HTTP 500 · retryable: yes · InternalServerError

Something failed on our side. Retry with backoff and report the request_id if it persists.

Fix: Retry with backoff; report the request_id if it persists.

HTTP 501 · retryable: no · NotImplementedError

The operation is not offered. reason is not_planned (for example custom domains, IMAP/SMTP) or phase_2 (calendar, files, connected accounts).

Fix: This operation is not available in simail yet.

HTTP 503 · retryable: yes · SendingPausedError

Platform-wide sending is paused. Already accepted messages wait and are sent after it resumes.

Fix: Platform sending is paused; retry later.

HTTP 503 · retryable: yes · UpstreamUnavailableError

A dependency is temporarily unavailable. Retry with backoff.

Fix: Retry with backoff.