Every JSON endpoint returns the same envelope on both success and failure. On success,
status.code is 0, errors is empty, and data carries the payload. On failure,
the HTTP status reflects the broad failure category and the envelope’s status /
errors fields carry detail.
Envelope shape
{
"status": {
"code": 100,
"errorMessage": "Customer 1099 is outside the scope of this API key."
},
"data": null,
"count": null,
"message": "Customer 1099 is outside the scope of this API key.",
"errors": [
{
"code": 100,
"message": "Customer 1099 is outside the scope of this API key."
}
]
}
HTTP status codes
| Status | Meaning |
|---|
200 | Success. Inspect status.code for service-level result detail. |
201 | Resource created (used by some webhook subscribe operations). |
400 | Validation failure. The errors array names the offending fields. |
401 | Missing, expired, or invalid bearer token. Re-authenticate. |
403 | Authenticated, but the resource is outside your API key’s KeyType or CompanyId/CustomerId/SiteId scope. |
404 | Resource does not exist or has been archived. |
429 | Rate limit exceeded (60 requests per minute on external endpoints). |
500 | Unhandled server error. Retry with backoff; if persistent, contact support with the trace ID. |
Status codes inside the envelope
status.code is a numeric service-level code that gives more nuance than the HTTP status.
The most common values are:
status.code | Meaning |
|---|
0 | Success. |
100 | Generic application error. Inspect status.errorMessage and errors[] for detail. |
401 | Authentication required or rejected (mirrors HTTP 401). |
403 | Authorization failed (mirrors HTTP 403). |
404 | Resource not found (mirrors HTTP 404). |
The full ServiceResultType catalog evolves over time. For unrecognised codes, fall back to
the HTTP status and the errors[].message text — both are stable contracts.
Retry strategy
401 — refresh the bearer token and retry once. Do not retry blindly; if the
refresh also fails, the API key has likely been revoked.
403 — do not retry. Fix the request scope.
429 — back off. Honour the next minute boundary; the limit is a fixed window.
5xx — retry with exponential backoff (e.g., 1s, 2s, 4s, 8s) up to a small cap.
Treat the request as non-idempotent if you cannot guarantee otherwise.