Errors

Every error is returned as JSON with the same envelope. The HTTP status code tells you whether you should retry.

HTTP status codes

CodeMeaningShould you retry?
200OK—
400Bad request — a required field is missing or invalid, or a filter key is unknown.No. Fix the request first.
401Missing or invalid credentials, or the IP is not whitelisted for this user.No. Repeated failed auth locks your IP for 30 seconds.
403Authenticated, but the user is not allowed on this route / method / module.No. Adjust the user's access controls.
404The document, resource or paginated page does not exist.Only if you asked for the wrong thing.
405Wrong HTTP method for this endpoint.No. Fix the method.
503Service temporarily unavailable (e.g. scheduled database maintenance).Yes, back off exponentially. Start at 5 minutes.
5xx (other)Server-side error.Yes, with exponential backoff.

Envelope

Errors use the same JSON envelope as success:

{
  "is_error": true,
  "http_code": 400,
  "data": null,
  "messages": [
    "Invalid filter field 'foo'"
  ],
  "request_route": ".../sales/list/foo:bar/",
  "your_ip": "1.2.3.4",
  "your_user": "api_user_xyz",
  "your_method": "GET"
}

Common causes

401 — Unauthorized

Failed 401s lock your IP for 30 seconds. Do not retry in a loop — fix the credentials or IP whitelist first.

403 — Forbidden

400 — Bad request

Always check the status code, not just is_error. A rejected write returns 400 (or 500 if the failure was on our side) — never 200. On some endpoints, notably the eCommerce order import, data also carries the payload we received plus an import_summary showing what we actually stored, so you can compare it against what you sent without opening a support ticket.

404 — Not found

Retry policy summary

4xx  → do not retry, fix the request
5xx  → retry with exponential backoff (5s, 15s, 45s, ...) up to a few minutes
timeout / network error → retry with backoff, but be idempotent-aware on write endpoints

» Continue to Endpoints.