kapi WorksDocs
Errors

Errors

Every error code the API returns, with what it means and what your integration should do.

Errors use application/problem+json (RFC 9457):

{
  "type": "https://docs.kapiworks.com/errors/invalid_token",
  "title": "Invalid API key",
  "status": 401,
  "detail": "The API key is invalid or no longer active.",
  "code": "invalid_token"
}

Act on code, or on type, which is the address of the code's page here. They are stable. title and detail are for people and can change, so do not parse them.

Every code

StatusCodeWhat to do
400invalid_requestFix the query and send it again. Unknown or repeated parameters, malformed dates and IDs, and periods longer than 400 days are refused.
400invalid_cursorStart the pull again without a cursor. A cursor works only on the endpoint and filters that produced it, for the same company.
400key_in_urlA URL can be stored in logs and browser history. Ask the company administrator for a new key, and send it only in the Authorization header.
401invalid_tokenStop polling and ask the company administrator for a new key. Unknown, expired and revoked keys get the same answer.
403insufficient_scopeAsk the company administrator for a key with the scope named in the WWW-Authenticate header. Retrying the same key does not help.
403ip_not_allowedCall from one of the key's networks, or ask the company administrator for a key that allows yours.
404not_foundUse a documented path on the API host.
405method_not_allowedThe API is read-only. The Allow header lists the methods it accepts.
422before_historyUse history_complete_from as the earliest moment you ask for. Earlier records are unavailable, not empty.
422record_too_largeUse a records pack for this register, and report the request ID to Kapi support.
429rate_limitedWait at least Retry-After seconds, then add a small random delay. Refused calls do not count against the limit.
429concurrent_limitWait for the running calls to finish, then retry after Retry-After seconds. Run one pull at a time per company.
502read_failedKeep your last complete pull. Retry with exponential backoff, and report the request ID if it keeps failing.
503unavailableContact Kapi support with the request ID. Retrying does not help until the configuration is fixed.
503upstream_unavailableRetry after Retry-After seconds with exponential backoff and jitter. Keep your last complete pull meanwhile.
503writer_unavailableRetry after Retry-After seconds. A pull already in progress can still finish from its cursor.
504read_timeoutRetry with a smaller limit, then return to your usual page size.

Headers that come with errors

  • X-Request-Id on every error. Quote it when you contact support, without the key.
  • WWW-Authenticate on 401 and 403 scope refusals. A scope refusal names the scope it needs.
  • Retry-After on 429 and 503: wait at least that many seconds.
  • Allow on 405, listing GET, HEAD.

Retrying

Retry connection failures and statuses 429, 502, 503 and 504, at most five times, with delays such as 1, 2, 4, 8 and 16 seconds plus a little random jitter. Retry-After takes precedence over your own delay. Use a timeout on every request, and when retries stop, report a failed sync instead of an empty result.

Do not retry 400, 401, 403, 404, 405 or 422 without changing something: the same request gets the same answer. Retrying a GET is safe, because reading creates no records.

On this page