Skip to main content

Errors

Most problems are reported through the GraphQL errors array of a response with the HTTP status 200. A few requests are rejected before the GraphQL operation is looked at and get a different HTTP status. Check the status first, then inspect the errors field of the body.

HTTP status codes​

HTTP statusWhen it appearsWhat to do
200 OKThe request reached the GraphQL endpoint. This includes requests whose body is not valid JSON, operations with syntax or validation errors, missing scopes, and throttled requests. The body may contain errors for individual fields or for the whole operation.Parse the JSON body. If errors is present, handle it according to its code.
400 Bad RequestThe path names a version that is not served (anymore). The error code is PICKWARE_GRAPHQL__UNSUPPORTED_API_VERSION.Move to a supported version, see Versioning.
401 UnauthorizedThe Authorization header is missing, or the access token is invalid or expired.Exchange your credentials for a new access token. See Authentication.
402 Payment RequiredThe merchant's plan does not include the API. The error code is PICKWARE_GRAPHQL__API_DISABLED.Upgrade the plan. Retrying does not help.
404 Not FoundThe path does not name a version in the YYYY-MM or YYYY-MM-unstable format, for example /api/graphql without a version.Fix the endpoint URL, see Getting started.
5xxA transient server-side problem.Retry with exponential backoff. Include the request ID if you have to contact support.

The bodies of the 400 and 402 responses are not GraphQL responses but JSON:API error documents:

{
"errors": [
{
"status": "402",
"code": "PICKWARE_GRAPHQL__API_DISABLED",
"title": "Pickware GraphQL is not enabled",
"detail": "The Pickware GraphQL endpoint is currently disabled. Please upgrade your plan to access it."
}
]
}

GraphQL error shape​

GraphQL responses can contain both data and errors. A response with partial data may still include errors for fields that could not be resolved. This response deletes a webhook subscription whose ID does not exist:

{
"data": null,
"errors": [
{
"message": "Webhook subscription \"0190f3a2b6c47d1e8a9b2c3d4e5f6a7b\" was not found.",
"path": ["deleteWebhookSubscription"],
"extensions": {
"code": "NOT_FOUND",
"requestId": "7c1e9a4f2b6d48e0a3f5c8b1d9e2a6f4"
}
}
]
}

A query for a single record by ID, such as product(id:), does not report an unknown ID as an error. It returns null for that record.

Rejected input​

When the input of a mutation is invalid or breaks a business rule of the shop, for example because a value contradicts the state of the shop, the response carries one entry in errors per problem found, not just the first one. Every entry describes one problem in its message, so a client can show all of them at once. Its code is BAD_REQUEST, or CONFLICT when the problem is that the data to delete is still in use.

The message of such an entry is translated according to the request's Accept-Language header. Without a supported language, it is English.

{
"data": null,
"errors": [
{
"message": "The currency of a supplier order can only be changed to a currency that exists in this shop.",
"path": ["createSupplierOrder"],
"extensions": {
"code": "BAD_REQUEST",
"requestId": "7c1e9a4f2b6d48e0a3f5c8b1d9e2a6f4"
}
}
]
}

Error codes​

CodeMeaningSuggested action
BAD_REQUESTThe request body, the GraphQL document, its variables, or the input of a mutation are invalid. This includes a query above the complexity limit of 5,000 or the depth limit of 15, see Rate limits.Read the message, check the generated API reference for field names and input types, and correct the request. Retrying it unchanged fails again.
UNAUTHORIZEDThe access token does not belong to an active Pickware GraphQL API token, for example because it comes from a user's session in the administration or the token was deactivated.Use an access token exchanged from the credentials of an active Pickware GraphQL API token.
FORBIDDENThe token does not have a scope the operation requires. The code is also used when the merchant's plan includes read access only and the request is a mutation, and when the operation needs a feature that is not part of the plan; extensions.requiredFeature then names the feature.Add the missing scope to the token. When the plan is the cause, retrying does not help until the plan changes.
NOT_FOUNDThe record a mutation refers to does not exist or is not visible to the token.Verify the identifier and token permissions.
CONFLICTThe request conflicts with the current state of the data.Reload the affected data and decide whether to retry.
THROTTLEDThe request costs more points than are currently left in the merchant's rate-limit bucket.Wait for the retryAfter value in extensions or the Retry-After header. See Rate limits.
MAX_COST_EXCEEDEDThe request costs more points than the merchant's rate-limit bucket can hold, so it can never run.Use smaller pages or split the query. Retrying it unchanged fails again.
UPSTREAM_UNAVAILABLEA service the operation depends on did not answer.Retry with exponential backoff.
INTERNALAn unexpected server-side error. The message is generic.Retry with exponential backoff. Include the request ID if you have to contact support.

Debugging requests​

Every response of the GraphQL endpoint carries the request's ID in the X-Pickware-Request-Id header, a string of 32 hexadecimal characters. Most errors repeat it as extensions.requestId, but syntax and validation errors, THROTTLED, and MAX_COST_EXCEEDED do not, so log the header. Include the ID when contacting support so the Pickware team can find the failing request quickly.

For schema-level validation errors, compare your operation with the generated reference for fields such as products, stocks, and ProductFilterInput.