Skip to content
Pidgely Docs

Get started

Errors

Error responses have the shape {statusCode, name, message}. The full list of error names, their HTTP status and how to handle them.

View as Markdown

Pidgely uses conventional HTTP status codes: 2xx for success, 4xx for a problem with the request, 5xx for a problem on our side. Errors have this body:

JSON
{
  "statusCode": 422,
  "name": "validation_error",
  "message": "to: at least one recipient is required"
}
  • name is stable and machine-readable: branch on it, never on message.
  • message is meant for humans. For validation errors it starts with the field, for example subject: is too long or [3].to: … inside a batch.
  • Every response carries an X-Request-Id header. Send your own (up to 64 characters) to correlate logs, and include it when you contact support.

Error names

Status name When What to do
400 invalid_idempotency_key Idempotency-Key longer than 256 characters Use a shorter key
401 missing_api_key No Authorization: Bearer … header Send the key
401 restricted_api_key A sending_access key called an endpoint that needs full_access Use a full-access key for that call
403 invalid_api_key The key does not exist or was revoked Check the key and the environment
403 validation_error The request is valid but not allowed: from domain not verified, key restricted to another domain, plan limit on domains reached, domain already added or verified by another account, sending paused or account suspended Read message; verify the domain or fix the account state
404 not_found The resource does not exist in your account (also returned for ids that are not valid UUIDs) Check the id
409 invalid_idempotent_request The Idempotency-Key was used before with a different request Use a new key for a new request
409 not_cancelable, not_reschedulable The email is no longer scheduled (already sent or canceled) Nothing to cancel or update
409 alias_taken Another template already uses this alias Choose another alias
409 broadcast_not_draft, broadcast_not_cancelable, broadcast_in_progress The broadcast is in a state that does not allow the operation See Broadcasts
422 validation_error A field is missing or invalid, the JSON is malformed, or the body is too large Fix the request; message names the field
422 invalid_attachment An attachment has neither content nor path Provide one of them
429 rate_limit_exceeded Too many requests per second Wait Retry-After seconds and retry
429 daily_quota_exceeded The daily quota (UTC day) is used up Wait for the next UTC day or upgrade
429 monthly_quota_exceeded The monthly quota is used up Wait for the next month or upgrade
500 application_error Unexpected error on our side Retry with backoff (with the same Idempotency-Key for sends)

Retrying

  • Retry 429 and 5xx with exponential backoff. For 429 rate_limit_exceeded, honour Retry-After.
  • Don't retry other 4xx errors unchanged: they fail the same way every time.
  • Make sends safe to retry with an Idempotency-Key: a network timeout then never turns into a duplicate email. Responses with 5xx are not stored, so a retry with the same key runs again.

Native API errors

The native /v1 API uses a different shape, with the field that failed and the request id:

JSON
{
  "error": {
    "code": "validation_error",
    "message": "at least one recipient is required",
    "field": "to",
    "request_id": "8f2c1a7d9e3b4c60"
  }
}

Codes there are the internal ones (domain_not_verified, tenant_paused, plan_limit, idempotency_key_reused, rate_limited, insufficient_scope, …), with the same statuses: 401 missing key, 403 forbidden, 404 not found, 409 conflict, 422 validation, 429 rate or quota. The main API is the recommended surface for new code.

Request limits

Limit Value
POST /emails and POST /emails/batch body 50 MiB
POST/PATCH on templates and broadcasts 5 MiB
Other write endpoints 1 MiB
Built message (headers, bodies and attachments, after encoding) 40 MiB
Request timeout 60 seconds

A body over its limit gets 422 validation_error with request body too large.