Errors

GraphQL errors arrive with HTTP 200

This is the single most important thing to get right. A GraphQL request that fails still returns HTTP 200, with the failure described in an errors array:

If your HTTP client checks only the status code, every one of these looks like a success.

Most GraphQL client libraries do this for you. Hand-rolled fetch calls are where this bites.

Partial success is possible

errors and data are not mutually exclusive. A query requesting several fields can return data for some and an error for others — the failed field is null in data, and path in the error names it. Do not assume errors being present means data is unusable.

Error fields

FieldMeaning
message
Human-readable description
path
Which field in your query failed
locations
Line and column in your query document

OAuth errors are different

The token and revoke endpoints are REST and use real status codes:

SituationStatusBody
Missing Authorization header
401
authorization error — plain text
Bad client ID or secret
401
{"error":"invalid_client","error_description":"..."}
Unsupported grant type
403
{"error":"unsupported_grant_type",...}

Two things to code around: the missing-header response is not JSON, so parsing it will throw; and unsupported_grant_type returns 403 where RFC 6749 §5.2 specifies 400.

Always capturex-request-id

Every response carries a request ID:

Log it alongside failures. It is the correlation key support will ask for, and it is the difference between a diagnosable report and "the API returned an error yesterday".

Retrying

Retry with exponential backoff on 429 (see Rate limits) and on 5xx.

Do not blindly retry GraphQL errors returned with HTTP 200 — most are deterministic (bad scope, missing permission, invalid ID) and will fail identically forever.

Mutations are not idempotent and there is no idempotency-key mechanism. Retrying a mutation that may have succeeded can duplicate its effect. Before retrying, query to establish current state — for example, re-read the order before re-sending acceptOrder.

Built with