Skip to content

Status Codes

How the API reports failures. The two transports signal errors differently — REST uses the HTTP status, GraphQL always returns 200 and puts the failure in errors[] — but both draw from the same set of conditions below.

REST vs GraphQL error shape

REST — the HTTP status carries the outcome; the body carries the message.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{ "detail": "The email field is required.", "status": 422 }

Branch on the status code, not on the message text (messages are localised and may change).

GraphQL — the HTTP status is almost always 200. A failed operation returns its field as null and the reason in a top-level errors[] array.

json
{
  "data": { "createCheckoutOrder": null },
  "errors": [
    { "message": "Please select a payment method." }
  ]
}

A partial success is possible: some fields resolve while errors[] lists what did not. Always check errors[] even when data is present.

Status codes

StatusMeaningTypical causeWhat to do
200OKSuccess (GraphQL: also check errors[])
201CreatedResource created (register, place order, add address)
204No ContentDeleted successfully
400Bad RequestMissing/invalid input, business-rule violationFix the request body
401UnauthorizedMissing/invalid/expired credentialGet a new credential (re-login / rotate / regenerate) — there is no refresh token
403ForbiddenAuthenticated but not allowed (wrong owner, missing permission)Use the right account/token
404Not FoundEntity does not exist, or is not yoursVerify the id
409ConflictOut-of-sequence step (e.g. shipping before an address is set), or empty cartComplete the prerequisite step first
422Unprocessable EntityValidation failed, or stock unavailableCorrect the fields / quantities
429Too Many RequestsRate limit exceededBack off — see Rate Limiting
500Server ErrorUnexpected server faultRetry; report if it persists

GraphQL maps the same conditions into errors[] (there is no HTTP 422/404 over GraphQL — the message identifies the cause).

The two 401 messages

A 401 comes back with one of two messages — treat both identically:

  • Unauthenticated. Please login to perform this action
  • Invalid or expired authentication token

Both mean "get a new credential." There is no refresh flow — see Authentication → Credential lifetimes.

Common conditions

ConditionRESTGraphQL
No / wrong storefront key401 missing_key / invalid_key401 at the transport (same key check)
Not logged in for a customer action401errors[] "unauthenticated"
Accessing another customer's resource403 / 404errors[]
Validation failure422errors[] with the field message
Cart empty at checkout409errors[]
Checkout step out of order409errors[]
Out of stock422errors[]

Handling pattern

  1. REST: switch on the status code. 2xx → success; 401 → renew credential; 403/404 → surface "not available"; 409/422 → show the body message to the user; 429 → back off; 5xx → retry.
  2. GraphQL: treat any non-empty errors[] as a failure even on 200; read errors[0].message for the reason; do not rely on data being null.

Released under the MIT License.