Errors

The error envelope and every error name the Bytesms API returns.

Error shape

Every /api/v1 error is JSON with the HTTP status, a human-readable message and a machine-readable name. Branch on name (and the status), never on message.

422 Unprocessable Entity
{
  "statusCode": 422,
  "message": "`to` must contain at least one recipient.",
  "name": "validation_error"
}

Some errors add fields. Quota errors keep the internal code plus limit and current; plan-limit errors carry the specific code:

429 Too Many Requests
{
  "statusCode": 429,
  "message": "Daily email limit reached (100/100). Try again tomorrow or upgrade your plan.",
  "name": "daily_quota_exceeded",
  "code": "daily_limit_reached",
  "limit": 100,
  "current": 100
}

Request-body validation failures (wrong types, invalid email addresses, unknown enum values) are returned as 422 validation_error with the individual problems joined into message.

Error names

StatusnameWhen
401unauthorizedMissing, malformed, unknown or expired API key.
401restricted_api_keyA sending_access key called an endpoint other than sending.
403restricted_api_keyA domain-scoped key sent from another domain (or its domain was deleted).
403suspended_api_keyThe API key was suspended.
403invalid_from_addressThe from domain is not a verified domain of this workspace (the workspace has other verified domains).
403validation_errorNo verified domain yet, or [email protected]used to send to someone outside the workspace. Also returned when a domain's warm-up daily volume is used up.
403sending_pausedSending is paused for the workspace (e.g. high bounce/complaint rate).
403account_under_reviewThe workspace is under review.
403account_suspendedThe workspace is suspended.
403subscription_past_due_expired, subscription_unpaid, subscription_incomplete, subscription_paused, subscription_canceledThe paid subscription is not in good standing (past the payment grace period, unpaid, …).
403plan_limit_exceededA plan cap was hit; code says which: api_key_limit_reached, domain_limit_reached, segment_limit_reached, contact_limit_reached, contact_limit_exceeded, webhook_limit_reached, member_limit_reached.
404not_foundThe resource does not exist in this workspace (ids of other workspaces are 404 too).
409idempotency_key_conflictThe Idempotency-Key was already used with a different request body.
409domain_in_use, domain_pending_elsewhereThe domain is verified in another workspace, or claimed there within the last 72 hours.
409validation_errorDuplicate: a contact with this email already exists in the audience, a template alias is taken, a broadcast was already sent.
422validation_errorThe request is invalid (see message).
422invalid_idempotency_keyThe Idempotency-Key header is empty or longer than 256 characters.
422attachments_not_supportedThe request contained attachments (not supported yet).
422invalid_domain, reserved_domainNot a valid fully-qualified domain name, or a platform / consumer-mailbox domain that can't be added.
429rate_limit_exceededToo many requests per second — see Rate limits.
429daily_quota_exceededThe plan's daily email limit (recipients per UTC day) is used up.
429monthly_quota_exceededThe plan's monthly quota is used up and pay-as-you-go can't cover more.
429overage_cap_reachedPay-as-you-go overage reached its safety cap for the billing period.
429spend_limit_reachedThe pay-as-you-go spend limit you set for the workspace was reached.
5xxapplication_errorSomething went wrong on our side, or a sending server was unreachable. Retry with backoff.

Retrying

Retry 429 rate_limit_exceeded after the retry-after header and 5xx errors with exponential backoff. When you retry a send, use an Idempotency-Keyso a request that actually succeeded is not sent twice. Don't retry other 4xx errors unchanged — they fail the same way.

Legacy endpoint

The legacy POST /api/v1/emails/send is not wrapped in this envelope: request-validation failures come back as 400 with { statusCode, message: string[], error }, and it returns the full internal message row on success. New integrations should use POST /api/v1/emails.