API

Handling Errors

Every error response uses this envelope

{
  "errors": [
    {
      "message": "Quantity must be greater than 0",
      "pointer": ["items", 0, "quantity"]
    },
    {
      "message": "Not Found",
      "pointer": ["company_id"]
    }
  ]
}

Every endpoint reports failures the same way: a JSON body with a single errors array, where each entry describes one problem. You only need to write one error parser for the entire API.

FieldDescription
messageA human-readable description of the problem.
pointerThe path to the offending part of your request: field names and array indices, e.g. ["items", 0, "quantity"] is the quantity of the first entry in items. ["base"] means the error applies to the request as a whole.

Use pointer — not the text of message — to react to errors programmatically. Messages may be reworded at any time without notice; pointers are stable.

Some responses include additional section and context fields on each error. These are deprecated — ignore them, and do not build logic on them.

Status codes

StatusMeaning
400The request was invalid: a malformed or missing field, a bad filter value, or a business rule that rejects it. The errors array says what and where.
401The API token is missing or invalid.
403The token is valid but lacks the permission the endpoint requires, or your user's team restrictions hide the record.
404No record with that id exists for your company, including a malformed id.
429Rate limit exceeded: a list endpoint or a PDF download. Wait for Retry-After, then retry.

These are the only error statuses the API returns. A 5xx response is never something your request caused: it is a bug on our end, and we'd appreciate a report to support with the request you sent (minus your token).

On this page