Public API

Errors

Every error code the API returns, its HTTP status, what it means and what to do about it.

Errors use the standard envelope: an error object with a stable code and a readable message, and meta.request_id.

{
  "error": {
    "code": "SCOPE_MISSING",
    "message": "This token is missing the organization:read scope."
  },
  "meta": { "request_id": "3a91d0c2-7b4e-4f8a-9c1d-5e2f6a7b8c90" }
}

Branch on error.code and the HTTP status. The message is written for people and may change.

Error codes

CodeHTTP statusMeaningWhat to do
AUTH_INVALID401The token is missing, malformed, unknown, revoked or expired, or its owner can no longer hold it (for example the owner was deactivated).Check the Authorization header and the token's status and owner in Settings > API. Do not retry with the same token.
API_DISABLED403The API is switched off for this organization.Ask an Executive to turn it on under Settings > API > Settings.
PLAN_REQUIRED403The plan does not include API access, or the subscription is past due, suspended, cancelled or unpaid.Resolve billing. API access is included in Pro, Business and Enterprise.
IP_NOT_ALLOWED403The request came from an address outside the token's IP allowlist.Call from an allowed address, or update the allowlist.
SCOPE_MISSING403The token does not hold the scope this endpoint requires. The message names that scope. Also returned when a webhook subscription would deliver events whose read scope the token does not hold.Add the scope to the token or its API role, if the owner's role allows it.
FORBIDDEN403The token's owner is not allowed to do this in the app, even though the token holds the scope, for example approving their own request. Also returned when the client address cannot be determined.Use a token whose owner has the authority in the app.
MODULE_DISABLED403The module this endpoint belongs to (for example time tracking or expenses) is switched off for the organization.An administrator can switch the module on in the app.
NOT_FOUND404The resource does not exist, belongs to another organization, or the path is not an API endpoint.Check the id and the path.
METHOD_NOT_ALLOWED405The path exists but does not accept this HTTP method. The Allow header lists the methods it does accept.Use a method from the Allow header.
CONFLICT409The request conflicts with the resource's current state (for example an expense report that is no longer awaiting a decision, or a name that is already taken), or a request with the same idempotency key is still in progress.Re-read the resource, or wait and retry.
IDEMPOTENCY_CONFLICT409The Idempotency-Key was already used with a different request.Use a new key for a different request.
VALIDATION_FAILED422The body, a parameter, the cursor or a header is invalid. Malformed JSON and a body that is not application/json return this code. Also returned when the app's own rules refuse a write, for example insufficient balance or a locked date; the message then says why. details may name the field.Fix the request. Retrying unchanged will fail again.
RATE_LIMITED429A rate limit was exceeded, or the address is temporarily blocked after repeated failed authentication.Wait for the number of seconds in Retry-After, then retry. See Rate Limits.
INTERNAL500Something went wrong on our side.Retry with backoff. If it persists, contact support with the request id.
UNAVAILABLE503The API is temporarily unavailable.Retry with backoff.

Error bodies never include stack traces or internal details, and never list the token's scopes.

Which errors to retry

Retry?Codes
Yes, after Retry-AfterRATE_LIMITED
Yes, with exponential backoffINTERNAL, UNAVAILABLE, and network errors or timeouts
After waiting brieflyCONFLICT caused by an in-progress idempotent request
No, fix the cause firstAUTH_INVALID, API_DISABLED, PLAN_REQUIRED, IP_NOT_ALLOWED, SCOPE_MISSING, FORBIDDEN, MODULE_DISABLED, NOT_FOUND, METHOD_NOT_ALLOWED, IDEMPOTENCY_CONFLICT, VALIDATION_FAILED

When you retry a write, send the same Idempotency-Key so it cannot be applied twice. See Idempotency keys.

The network edge in front of the API can answer before your request reaches it: 413 for a request body over 1 MB, and 429 when an address sends too many requests. These responses may not use the JSON envelope. Treat any 429 the same way: wait, then retry.