Skip to content

Errors

One error shape, a fixed list of codes, and nothing leaked from inside the system.

Error shape

json
{
  "error": {
    "code": "INVALID_SUBDIVISION",
    "message": "subdivision_code 'XX' is not supported for country MY.",
    "request_id": "req_9f2c41a7be03d5710c8e2b44"
  }
}

Branch on code, never on message. Messages are written for humans and may be reworded. Some errors add context fields such as limit, used or retry_after_seconds.

What errors never contain

No stack traces, no SQL, no provider internals, no configuration values. If something breaks on our side you get 500 INTERNAL_ERROR and a request_id to quote.

Code reference

CodeHTTPMeaning and fix
INVALID_REQUEST400The request was not a POST, or mixed mutually exclusive fields.
INVALID_DATE400A date field was missing, malformed, or not a real calendar date.
INVALID_JSON400The request body was not a JSON object.
PAYLOAD_TOO_LARGE413The request body exceeded 64 KB.
UNKNOWN_FIELD400The body contained a field the operation does not accept.
MISSING_API_KEY401No Authorization: Bearer key and no x-api-key header.
INVALID_API_KEY401The key does not match any active key.
REVOKED_API_KEY401The key was revoked.
EXPIRED_API_KEY401The key passed its expiry date.
API_KEY_IN_QUERY_STRING401An api_key query parameter was present. Keys must travel in headers only.
ENVIRONMENT_MISMATCH403A test key was used against live, or the reverse.
FEATURE_NOT_AVAILABLE403The account does not have this feature.
PLAN_UPGRADE_REQUIRED403The operation needs a higher plan.
NOT_FOUND404Unknown operation path.
BUSINESS_CALENDAR_NOT_FOUND404No Business Calendar with that id is owned by this account.
BUSINESS_CALENDAR_FORBIDDEN403The calendar exists but is not usable by this account.
CONFLICT409The request conflicts with existing state.
INVALID_COUNTRY422country_code is not a supported ISO 3166-1 country.
INVALID_SUBDIVISION422subdivision_code is not supported for that country. There is no fallback to national holidays.
INVALID_TIMEZONE422timezone is not a valid IANA identifier.
RANGE_TOO_LARGE422The date range exceeded the maximum supported span.
VALIDATION_ERROR422A field failed its type, range or format rule.
RATE_LIMIT_EXCEEDED429Too many requests this minute for the account's plan.
API_QUOTA_EXCEEDED429The account's monthly request allowance is used up.
INTERNAL_ERROR500Something failed on our side. Quote the request_id.
SERVICE_UNAVAILABLE503The API is not accepting traffic, or usage could not be recorded.

Retry policy

  • 429: retry after the retry-after header. Back off exponentially; do not hammer.
  • 503: retry with backoff, the condition is temporary.
  • 4xx other than 429: do not retry. Fix the request or the key first.
  • 500: retry once, then alert with the request_id.