Skip to main content
Every error response — whatever the HTTP status — shares the same envelope, EnvelopedErrors, wrapping one or more Error objects:
errors is an array: a single response — typically a 400 on plan/resource creation — can report several invalid fields at once.

Reference table

The API currently defines 11 business error codes:
This list is not yet exposed as a formal enum on the Error.code field in the API reference schema — it’s compiled from the current server implementation. If you’re generating a client from openapi.yaml, don’t assume this table is exhaustive for future versions; check the changelog when upgrading.

Same HTTP status, different code

The HTTP status alone doesn’t tell you which business error occurred — most statuses map to several codes (all of INVALID_INPUT, ID_NOT_UNIQUE, KEYS_NOT_UNIQUE, INVALID_ID_REFERENCE, INVALID_VALUE, PRECONDITION_FAILED, and NOT_IMPLEMENTED return 400). Always read code, not just the status. Conversely, you may see a 403 documented under either “Forbidden” or “Unauthorized” depending on the endpoint in the API reference — this naming isn’t consistent across the spec, but both cases behave identically: HTTP 403 with code: "NOT_ALLOWED". Match on code, not on the response name shown in the reference.

properties

The exact keys returned in properties for each code (for example, which field name or invalid value is included in an INVALID_VALUE or INVALID_ID_REFERENCE error) are not documented in the current API reference and need confirmation from the backend team before being published here. Treat any properties content as informational and not stable until this section is updated.

What this page doesn’t cover

  • Infeasible plans are not an error. Submitting a plan the engine can’t fully satisfy still returns a normal 200/201 — the plan is accepted, and unplanned stops or constraint violations show up in the solution (unaffectedStopIds, violations) rather than as an Error. See Handling infeasibility.
  • Rate limiting. The OTP-related endpoints (/auth/mfa/resendOTP, /login/resendOTP) return a 429 when called too often, but currently without a structured JSON body — it doesn’t follow the EnvelopedErrors format described above.

See also