Errors¶
All endpoints return errors as RFC 7807 application/problem+json:
{
"type": "https://docs.flexgalaxy.ai/dev/wes-contract/errors.html#cross-warehouse-credential",
"title": "Credential not authorized for this warehouse",
"status": 403,
"detail": "Credential WH-Tokyo-01/AcmeWES attempted to post for WH-Tokyo-02.",
"instance": "/wes/v1/realtime/movements",
"trace_id": "01J7Y6K1NQ3W2C0X4V0R5T6E7N"
}
trace_id is propagated end-to-end via the W3C traceparent header. Include it in every support request.
Status table¶
Status |
Meaning |
Partner action |
|---|---|---|
|
Malformed request — invalid JSON, missing required field, unknown enum value. |
Fix the request shape. Do not retry as-is. |
|
Missing or invalid credential — cert not in registry, expired API key, bad HMAC signature. |
Check certificate, key rotation, secret rotation, environment config. |
|
Credential valid but not authorized for the resource or warehouse. |
Check partner-registry warehouse scoping; never bypass with a more-privileged credential. |
|
The referenced cursor / job / window / mapping does not exist. |
Verify the identifier; treat as terminal — do not retry. |
|
State conflict — e.g. a fresh confirmation for an already- |
Inspect the referenced state. For confirmation conflicts, route through supervisor discrepancy resolution. |
|
Schema-valid but business-invalid — unknown SKU, wrong UoM, unknown location, malformed |
Fix the underlying data, not the request shape. |
|
Rate limited. |
Honor |
|
Platform-side failure. |
Retry with exponential backoff. Open a support ticket including |
|
Receiving side is in maintenance or temporarily offline. |
Retry with exponential backoff. Honor |
Idempotency notes on errors¶
A
200 OKwithreplay: trueis not an error — it is the expected response to a retry of an already-applied request. See Idempotency and ordering.A
409for a window key collision is also not the same as a replay. Two differentcorrelation_ids for the same window key is a planner-side rule violation; the supervisor workflow exists for this case.A
422on a movement does not roll back other items in the same batch. Each item’s status is reported individually in the response.
Batch responses¶
Endpoints that accept arrays return a per-item result. A batch of 100 movements with one bad SKU returns 200 OK with 99 entries marked ACCEPTED and one marked REJECTED. The HTTP status is 200 because the batch was processed; the per-item status carries the actual outcome.
{
"results": [
{ "correlation_id": "...", "status": "ACCEPTED" },
{ "correlation_id": "...", "status": "ACCEPTED", "replay": true },
{ "correlation_id": "...", "status": "REJECTED",
"reason": "Unknown SKU 'SKU-FOO-001'." }
],
"summary": { "accepted": 2, "rejected": 1 }
}
A request that is itself malformed (bad JSON, missing required envelope field) returns 400 for the whole request — no per-item processing happens.
Retry strategy¶
Status class |
Retry? |
Strategy |
|---|---|---|
|
n/a |
Done. |
|
No. |
Fix the input and resubmit with a fresh |
|
Yes |
Honor |
|
Yes |
Exponential backoff. Cap at 24h before DLQ. |
Retrying a 4xx (other than 429) wastes resources on both sides and risks corrupting your idempotency state. The planner / executor will not change its answer on retry of the same (partner_id, correlation_id).