Error handling

Understand the failure before deciding to retry.

Use the HTTP status to identify the failure category, the stable error code to choose your integration response and the request ID to trace the operation. Correct invalid requests rather than repeating them unchanged.

Error envelope

Read the error code and retain the request identifier.

The response separates a machine-readable condition from a human-readable explanation. Preserve that distinction in application logic so a wording change does not alter how your integration handles the failure.

Example errorJSON

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The request body is invalid.",
    "requestId": "57780f31-3f41-4485-b9de-87858e145116",
    "details": {
      "issues": [
        { "path": "currency", "message": "Expected USD" }
      ]
    }
  }
}
code
Use this machine-readable value for branching, metrics and alerts.
message
Human-readable diagnostic context. Do not parse it for application logic.
requestId
Store this value with your source operation and provide it when contacting support.
details
Optional structured context such as validation paths. Its fields depend on the error code.

Status guide

Retry only when the condition is transient.

StatusMeaningIntegration action
400Malformed input or required header missingCorrect the request. Do not retry unchanged.
401Credential missing, invalid, expired or revokedStop and restore a valid credential.
403Authenticated but not permittedCheck tenant status and assigned scope; do not broaden scope automatically.
404Route or tenant-owned resource not foundVerify the path and opaque identifier. Do not probe other tenants.
409Idempotency, state or version conflictInspect the error code; read current state before deciding whether to retry.
413Request exceeds the 12 MiB boundaryReduce the request according to the endpoint contract.
415Unsupported media typeSend the documented Content-Type.
422Well-formed request fails semantic validationCorrect fields or referenced resources. Do not retry unchanged.
428If-Match is requiredRead the resource and retry with its current ETag.
429Request rate was limitedHonor Retry-After when this status is returned.
500Unexpected server failureRetry with bounded backoff and the same idempotency key.
503Dependency or stored operation is unavailableRetry with bounded backoff; alert if the condition persists.
No published fixed rate limit

Do not design around an invented request allowance. If a route returns 429, follow its headers. Expected traffic is reviewed during developer onboarding.

Retry decision

Keep a retry connected to the original operation.

A retry repeats the same logical request; it is not a new Shopify order or adjustment. Read the idempotency conventions alongside the status guide before choosing whether to try again.

  1. 01

    Classify the failure

    Validation, authentication, permission and most not-found failures require a correction, not a retry.

  2. 02

    Keep the same idempotency key

    For a transient mutation failure, retry the unchanged logical request with its original key.

  3. 03

    Use bounded backoff

    Limit attempts, add jitter and stop retrying when the operation has a terminal response.

  4. 04

    Escalate with identifiers

    Provide the request ID, environment, endpoint, timestamp and your non-sensitive source reference. Never send the bearer key.