Skip to main content
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

StatusMeaning
200Success. Inspect status.code for service-level result detail.
201Resource created (used by some webhook subscribe operations).
400Validation failure. The errors array names the offending fields.
401Missing, expired, or invalid bearer token. Re-authenticate.
403Authenticated, but the resource is outside your API key’s KeyType or CompanyId/CustomerId/SiteId scope.
404Resource does not exist or has been archived.
429Rate limit exceeded (60 requests per minute on external endpoints).
500Unhandled 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.codeMeaning
0Success.
100Generic application error. Inspect status.errorMessage and errors[] for detail.
401Authentication required or rejected (mirrors HTTP 401).
403Authorization failed (mirrors HTTP 403).
404Resource 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.