Errors
Errors
Every failure carries a stable code. Branch on the code and never on the message: the wording can change at any time, the code will not.
Paths, methods, scopes, field names, error codes and validation rule names are published in English, because English is the language of the interface itself — they are what a caller types or matches on. So is every code sample and JSON payload, and the exact sentence an error response carries: /v1 does not read Accept-Language, so translating what the API literally sends would misdescribe it. Everything written about them follows the language of this page.
The error envelope
Every non-2xx response has the same shape. documentation_url points straight at the entry below, and request_id is the value to quote in a support request. details carries machine-readable context — for a refused body that is issues, each one a JSON Pointer at the field that was wrong.
{
"error": {
"code": "validation_failed",
"message": "The request body failed validation.",
"documentation_url": "https://passportcraft.com/docs/api/errors#validation_failed",
"request_id": "req_9Fv2KpQ0aXbT4Lmn",
"details": {
"issues": [
{ "source": { "pointer": "/data/product_name" }, "rule": "required" }
]
}
}
}Codes
Each code is linked from the response that carries it, so this page is usually reached at the entry that is needed.
invalid_key
401The API key provided is not valid.
API returnsThe API key provided is not valid.
Any endpoint can return this.
key_revoked
401This API key has been revoked.
API returnsThis API key has been revoked.
Any endpoint can return this.
key_expired
401This API key has expired.
API returnsThis API key has expired.
Any endpoint can return this.
key_rotated
401This API key was replaced by a rotation and its overlap window has closed.
API returnsThis API key was replaced by a rotation and its overlap window has closed.
Any endpoint can return this.
mode_mismatch
400The key prefix does not match the credential. Check whether you meant a test or a live key.
API returnsThe key prefix does not match the credential. Check whether you meant a test or a live key.
Any endpoint can return this.
insufficient_scope
403This credential does not carry the scope required for this operation.
API returnsThis credential does not carry the scope required for this operation.
Which endpoints return this
- get
/organizations/{organization}/capabilities - get
/organizations/{organization}/events - get
/organizations/{organization}/passports - post
/organizations/{organization}/passports - get
/organizations/{organization}/publish-approvals/{id} - get
/organizations/{organization}/passports/{id} - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/documents - get
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports - get
/organizations/{organization}/imports - get
/organizations/{organization}/imports/{id}
organization_not_found_or_not_granted
404No such organization.
API returnsNo such organization.
Which endpoints return this
- get
/organizations/{organization}/capabilities - get
/organizations/{organization}/events - get
/organizations/{organization}/passports - post
/organizations/{organization}/passports - get
/organizations/{organization}/publish-approvals/{id} - get
/organizations/{organization}/passports/{id} - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/documents - get
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports - get
/organizations/{organization}/imports - get
/organizations/{organization}/imports/{id}
resource_not_found
404No such resource.
API returnsNo such resource.
Which endpoints return this
- get
/categories/{category}/schema - get
/organizations/{organization}/publish-approvals/{id} - get
/organizations/{organization}/passports/{id} - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - get
/organizations/{organization}/imports/{id}
wildcard_not_supported
400The "-" organization wildcard is reserved and not yet supported.
API returnsThe "-" organization wildcard is reserved and not yet supported.
Which endpoints return this
- get
/organizations/{organization}/capabilities - get
/organizations/{organization}/events - get
/organizations/{organization}/passports - post
/organizations/{organization}/passports - get
/organizations/{organization}/publish-approvals/{id} - get
/organizations/{organization}/passports/{id} - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/documents - get
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports - get
/organizations/{organization}/imports - get
/organizations/{organization}/imports/{id}
validation_failed
422The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/imports
invalid_request
400The request could not be understood.
API returnsThe request could not be understood.
Any endpoint can return this.
method_not_allowed
405The endpoint exists but does not answer this HTTP method. The Allow header on the refusal lists the methods it does answer.
API returnsThis endpoint does not support that HTTP method. The Allow header lists the ones it does.
payload_too_large
413The request body is larger than this endpoint accepts. details.limit_bytes carries the ceiling that was applied.
API returnsThe request body is larger than this endpoint accepts.
Any endpoint can return this.
unsupported_media_type
415The request body did not arrive as application/json.
API returnsThe request body must be sent as application/json.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/validate - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/imports
idempotency_conflict
409This Idempotency-Key was already used with a different request body.
API returnsThis Idempotency-Key was already used with a different request body.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/imports
already_exists
409A resource with this identifier already exists.
API returnsA resource with this identifier already exists.
Which endpoints return this
precondition_failed
412The resource changed — either since the version you supplied, or while your request was in flight. The current_version we report is the version we read, not necessarily the one now stored — re-read the passport rather than computing from it.
API returnsThe resource changed since the version you supplied.
resource_busy
409Another request is modifying this resource. Wait for the Retry-After header, then retry.
API returnsAnother request is modifying this resource. Wait for the Retry-After header, then retry.
Which endpoints return this
cursor_invalid
400The pagination cursor is invalid, expired, or was sent with different filters.
API returnsThe pagination cursor is invalid, expired, or was sent with different filters.
Which endpoints return this
no_subscription
402This organization has no active subscription.
API returnsThis organization has no active subscription.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports
plan_required
402This organization’s plan does not include this operation.
API returnsThis organization’s plan does not include this operation.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports
payment_overdue
402Publishing is disabled while payment is overdue.
API returnsPublishing is disabled while payment is overdue.
Which endpoints return this
- post
/organizations/{organization}/passports - patch
/organizations/{organization}/passports/{id} - post
/organizations/{organization}/passports/{id}/publish - post
/organizations/{organization}/passports/{id}/unpublish - post
/organizations/{organization}/passports/{id}/trash - post
/organizations/{organization}/passports/{id}/restore - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/documents - delete
/organizations/{organization}/passports/{id}/documents/{documentId} - post
/organizations/{organization}/imports
gtin_required
422A GTIN is required before this passport can be published.
API returnsA GTIN is required before this passport can be published.
wrong_status
409The passport is not in a status that allows this operation.
API returnsThe passport is not in a status that allows this operation.
Which endpoints return this
not_trashed
409Only a trashed passport can be restored.
API returnsOnly a trashed passport can be restored.
Which endpoints return this
publish_limit_reached
402This organization has used every publish slot its plan allows.
API returnsThis organization has used every publish slot its plan allows.
Which endpoints return this
unit_limit_reached
402This passport carries more units than the plan allows.
API returnsThis passport carries more units than the plan allows.
document_missing
422A required field is satisfied only by a document that is no longer attached.
API returnsA required field is satisfied only by a document that is no longer attached.
Which endpoints return this
document_feeds_extraction
409This document is the record of where a passport's values came from, so it stays while that passport exists. Nothing was detached.
API returnsThis document is the record of where a passport’s values came from, so it stays while that passport exists. Nothing was detached.
Which endpoints return this
delegation_required
403Filing requires an active delegation, verified against the portal at call time.
API returnsFiling requires an active delegation, verified against the portal at call time.
Which endpoints return this
attestation_required
403This operation requires an attestation accepted by a named person at the brand.
API returnsThis operation requires an attestation accepted by a named person at the brand.
Which endpoints return this
test_mode_refused
403Test-mode credentials cannot perform this operation.
API returnsTest-mode credentials cannot perform this operation.
Which endpoints return this
human_approval_required
202The connector asked to publish. A person at the organization must approve it, and nothing was published.
API returnsA person at your organization must approve this publish. The request was recorded and is waiting for them — give them the link in `details.review_url`. Nothing has been published.
connector_writes_drafts_only
409The agent connector may only change a draft. A passport the public can already see needs a person.
API returnsThis product is already visible to the public, so an assistant cannot change it. A person has to make the change — give them the editor link in `details.review_url`.
unit_status_not_allowed
422This unit status is not one the connector may set. The permitted values are named in the details.
API returnsThat unit status is not one an assistant may set. Use one of the values in `details.allowed`, or leave the status empty.
rate_limited
429Too many requests.
API returnsToo many requests in a short time. Wait a moment, then try again.
Any endpoint can return this.
internal_error
500Something went wrong on our side.
API returnsSomething went wrong on our side.
Any endpoint can return this.
configuration_error
500The service is misconfigured. This is not a problem with your request.
API returnsThe service is misconfigured. This is not a problem with your request.
Any endpoint can return this.
Validation rules
These are the rules the passport data itself can break, in any category. A rule name reaches you in three places: under error.details.issues in a 422, under issues in the 200 from the validate endpoint, and under error.detail.issues on a bulk-import row. Create, update and import refuse a value inside data only for the two marked as refused on save — though create also returns required for a category it does not serve. The rest arrive from publish or from the validate endpoint. Publish returns the full list, advisories included, so it names rules that did not cause the refusal. Branch on the rule, never on the message.
required
blocks publishThe field is required for this category and arrived empty, absent, or as an empty list. Creating a passport under a category we do not serve also returns this rule, on the JSON Pointer /category.
How to fixSend a value. A url field that documents a file is also satisfied by attaching that document instead.
type_array
blocks publishalso refused when you saveThe field holds a list, and the value was not one — most often a list sent as a JSON string.
How to fixSend a real JSON array, not a string containing one.
type_array_items
blocks publishalso refused when you saveThe field holds a list of plain text values, and at least one entry was an object, a number, or a boolean.
How to fixSend every entry as a string. The field carries item_type in the category schema when it requires this.
type_number
blocks publishThe field holds a number, and the value was not one — most often a number sent as a string.
How to fixSend a JSON number, unquoted.
number_min
blocks publishThe value is below the smallest number the field accepts.
How to fixRead min on the field in the category schema, then send a value at or above it.
number_max
blocks publishThe value is above the largest number the field accepts.
How to fixRead max on the field in the category schema, then send a value at or below it.
format_date
blocks publishThe value is not a valid ISO 8601 date. A date that does not exist, such as 2025-02-30, is refused here.
How to fixSend YYYY-MM-DD, or an ISO 8601 timestamp in UTC, ending Z. An offset that puts the timestamp on a different date is refused.
format_url
blocks publishThe value is not a valid URL.
How to fixSend an absolute https:// or http:// URL.
invalid_option
blocks publishThe field accepts a fixed set of values, and the value was not one of them. A field that offers an other option is exempt: it stores free text instead.
How to fixRead options on the field in the category schema, then send one of the value entries it lists.
format_gtin
blocks publishThe GTIN is not a real one: it arrived as an empty string, holds characters that are not digits, has the wrong length, has a check digit that does not match, or is a documentation example.
How to fixSend a GTIN-8, GTIN-12, GTIN-13, or GTIN-14 that GS1 issued to you. The message names which problem it is.
format_eori
blocks publishThe EORI number does not match the format the field accepts.
How to fixSend two uppercase country letters, then 1 to 15 uppercase letters or digits. Lowercase is refused.
format_country_code
blocks publishThe country is not two uppercase letters. A lowercase code such as de is refused.
How to fixSend an uppercase ISO 3166-1 alpha-2 code, such as DE.
format_commodity_code
advisoryThe commodity code does not match the HS, CN, or TARIC format.
How to fixSend 6, 8, or 10 digits. You can also publish the passport with the value as it stands.
format_email
blocks publishThe value is not a valid email address.
How to fixSend a complete address.
category_exists
blocks publishThe passport names a product category this API does not serve.
How to fixSending a different category does not clear this one: the stored passport names a category we no longer serve. Recreate it under a category the category list endpoint returns.
Three other things carry a rule name. A product category adds rules of its own, which read several fields together — material percentages that must total 100, for example. An endpoint reports a problem with the request itself the same way, under names such as not_writable. And the publish gate reuses required for a value publishing needs, such as a GTIN, on a field the category itself does not require. In each case the message in the response explains the rule.
Warnings
A warning is not a refusal. It arrives alongside a 200, on a call that succeeded, and names something worth acting on.
environmental_claim_detected
200The passport carries environmental claim language. Publishing succeeded and the passport is live. From 27 September 2026, Directive (EU) 2024/825 requires the trader placing the product on the market to hold substantiation for such claims.