Errors and troubleshooting

Identify the failed boundary, decide whether to retry and preserve unknown outcomes.

Read the response, not just its status

Company API errors normally include a machine-readable code and a human-readable message:

{"code":"INSUFFICIENT_SCOPE","message":"This API key is missing the 'payroll:write' scope."}

Branch on code and HTTP status; do not parse prose. SDKs raise KuaError with status, code and message. Network/TLS/transport errors may occur before an HTTP error can be parsed. Kola OIDC uses its own error / error_description envelope, described in the handshake guide.

Choose the next action

ResultMeaning and action
200 / 201Read or creation succeeded. Match returned IDs and verify the destination outcome.
202Accepted/queued. Monitor the resource; this is not delivery or settlement.
204Successful operation with no response body. Verify intended state if the operation matters.
400Validation or unsupported operation. Resolve the returned code instead of retrying unchanged.
401Credential missing, invalid, expired or revoked. Check host and credential type.
403Scope, workspace approval or endpoint authority denied. Ask the authorised company administrator to resolve it.
404Resource missing or inaccessible in this company. Check stored key mode, company and ID; don’t substitute another company’s credential.
409State/idempotency/mode conflict. Inspect the exact code and current resource state.
429Request/recovery limit. Use bounded backoff; see rate limits.
5xx / timeoutOutcome may be unknown. Reconcile before a consequential retry; preserve the original operation identity.

Common codes

  • INSUFFICIENT_SCOPE: issue the specific resource grant. Read permission does not grant mutation or deletion, and rotating a key preserves its scopes.
  • TEST_MODE_UNSUPPORTED: no isolated Test behavior for this route. Staging event/add-on reads use 409; unsupported writes and the webhook family use 400. Do not replace a Test key with a Live key just to finish a tutorial.
  • IDEMPOTENCY_KEY_MISMATCH: the same operation identity has different body bytes. Recover the original request; see idempotency.
  • IDEMPOTENCY_LEGACY_RECONCILIATION_REQUIRED: the old operation may already have completed. Reconcile it; do not create a new key to bypass the conflict.
  • PAYROLL_RUN_EMPTY: no eligible salaried roster for that draft/period. Check the salary/setup prerequisite.
  • WEBHOOK_INVALID_URL: check the absolute receiver URL and endpoint policy before registering again.
  • MODULE_NOT_ENABLED: legacy module-gate behavior, not an instruction to find the retired Settings → Modules page. Check the deployed API and actual eligibility.

Retry without repeating an effect

Both SDKs leave retries to your application. Back off transient reads. For writes, retain the same credential, method/path, key and exact body bytes; changing any of them can create a new operation namespace. A lost response does not prove nothing happened, including after credential rotation or receipt expiry.

For a webhook replay, retain its body requestKey and reason; Pending is queued. For an OIDC exchange, restart authorisation after an expired/used or unrecoverable code. Those protocols are not interchangeable with a generic HTTP retry.

Escalate with useful evidence

Record key mode, UTC time, status/code, operation/resource ID and the redacted response. Include whether the outcome is known, queued or uncertain and what has already been read back. Contact developer support without an API key, bearer token, signing secret, raw personal data or payment credentials.

Resolved when: the prerequisite is fixed, the intended operation’s state is known and any retry preserves the right identity. A cleared error message alone does not establish a completed business effect.

Search documentation

↑ ↓ to move · Enter to open · Esc to close