Errors

Every planEvery plan.

Every error has the same JSON body: an error object with a machine-readable code and a human-readable message. Branch on code, not on the message, which may change.

401, 403 and 429 errors also carry upgrade_url (where to get a key or a bigger plan) and docs_url (the page that explains the error). A 429 adds plan, limit (daily or monthly: the window that blocked the call) and limit_value.

Error body

HTTP/1.1 403 Forbidden

{
  "error": {
    "code": "forbidden",
    "message": "Transfer partners requires a Pro plan or above",
    "upgrade_url": "https://cardapi.dev/pricing?utm_source=api&utm_medium=error&utm_campaign=forbidden",
    "docs_url": "https://cardapi.dev/pricing#plan-fields"
  }
}

Rate-limited body

HTTP/1.1 429 Too Many Requests
Retry-After: 3600

{
  "error": {
    "code": "rate_limited",
    "message": "Daily limit of 100 calls reached on the Free plan. Starter gives 500 calls/day and 15,000/month, with a 7-day free trial for new customers: https://cardapi.dev/pricing",
    "plan": "free",
    "limit": "daily",
    "limit_value": 100,
    "upgrade_url": "https://cardapi.dev/pricing?utm_source=api&utm_medium=error&utm_campaign=rate_limited",
    "docs_url": "https://cardapi.dev/docs/rate-limits"
  }
}

Error codes

StatusCodeMeaning
400bad_requestA parameter or the request body is invalid. The message names the parameter, e.g. a malformed slug or a limit that isn't a number.
401unauthorizedThe Authorization header is missing, the key is malformed or unknown, or the key was deactivated.
403forbiddenYour plan doesn't include this endpoint. The message names the plan it needs, e.g. "Transfer partners requires a Pro plan or above".
403account_suspendedThe account is suspended. Contact support@cardapi.dev.
404not_foundNo such card, issuer, webhook or route. /v1/cards/compare names the slugs it couldn't find.
409use_portalPOST /v1/auth/upgrade on an account that already has a paid plan. Change the plan in the developer portal.
413payload_too_largeThe request body is too large.
429rate_limitedYour account's daily or monthly quota is used up. Retry-After gives the seconds until the blocking window resets; the X-RateLimit-* headers carry the numbers.
500internal_errorSomething failed on CardAPI's side. Retry later; if it persists, tell support@cardapi.dev.
503service_unavailableCardAPI briefly couldn't check your key or usage. Retry-After is 30. This is not your quota.
504timeoutThe request took longer than 30 seconds to process.

Retrying

Retry 429, 503 and 504 after the Retry-After header (429 and 503 send one). Don't retry 400, 401, 403 or 404 unchanged: the same request gets the same answer.

Related

Re-checked against issuer sites every Friday · last change Oct 17