Skip to main content

Errors

The API uses HTTP codes in the conventional sense: 2xx worked, 4xx is a problem with the request, 5xx is a problem on the server.

Codes​

CodeMeaningWhat to do
200OK—
400Malformed requestInvalid JSON or a missing required parameter. Fix it and retry.
401Not authenticatedKey missing, invalid or revoked. Check the api_access_token header.
403Not allowedThe key is valid, but the user who owns it has no access to the resource.
404Not foundThe resource does not exist or does not belong to this account. Check the account ID in the path.
422UnprocessableThe request is well formed, but the data failed validation. The body says which field.
429Limit exceededWait and retry with backoff. See Rate limits.
500Server errorRetry later. If it persists, contact support.

401 and 403 are different things​

  • 401 — who are you? The key was not recognized.
  • 403 — I know who you are, but you may not. The key is valid; it is the user who owns it that lacks the permission. Retrying will not help: either the user gains the permission, or the key has to belong to another user.

A 404 is usually the wrong account​

Nearly every endpoint is scoped by account (/api/v1/accounts/{account_id}/…). Asking for a resource in another account returns 404, not 403 — on purpose, so as not to reveal that the resource exists. If an ID you know exists returns 404, check the account_id in the path before hunting for the bug anywhere else.

Validation errors​

A 422 usually carries the reason in the body:

{
"message": "Validation failed: Name can't be blank"
}

Some endpoints return the errors per field:

{
"errors": {
"email": ["has already been taken"]
}
}

The format is not uniform across the API. When handling errors generically, prefer the HTTP code and use the body only to display the message.

When integrating​

  • Handle 429 and 5xx with retry and backoff; do not retry 4xx — repeating an invalid request only burns quota.
  • Log the response body when something fails: it almost always says what was missing.
  • Do not infer success from the body. Check the status.