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
- post
/organizations/{organization}/grants - delete
/organizations/{organization}/grants/{keyId} - get
/organizations/{organization}/custom-fields - 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 - post
/organizations/{organization}/passports/{id}/proposals - get
/organizations/{organization}/proposals/{id} - post
/organizations/{organization}/proposals/{id}/withdraw - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - get
/organizations/{organization}/passports/{id}/variants/review - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/units/{unitId}/readings - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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, or this key has no grant on it. A grant ends when someone revokes it or when the organization's arrangement with its partner ends; the organization then leaves GET /organizations.
API returnsNo such organization.
Which endpoints return this
- post
/organizations/{organization}/grants - delete
/organizations/{organization}/grants/{keyId} - get
/organizations/{organization}/custom-fields - 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 - post
/organizations/{organization}/passports/{id}/proposals - get
/organizations/{organization}/proposals/{id} - post
/organizations/{organization}/proposals/{id}/withdraw - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - get
/organizations/{organization}/passports/{id}/variants/review - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/units/{unitId}/readings - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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 - post
/organizations/{organization}/grants - delete
/organizations/{organization}/grants/{keyId} - 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 - post
/organizations/{organization}/passports/{id}/proposals - get
/organizations/{organization}/proposals/{id} - post
/organizations/{organization}/proposals/{id}/withdraw - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - get
/organizations/{organization}/passports/{id}/variants/review - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/units/{unitId}/readings - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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
- post
/organizations/{organization}/grants - delete
/organizations/{organization}/grants/{keyId} - get
/organizations/{organization}/custom-fields - 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 - post
/organizations/{organization}/passports/{id}/proposals - get
/organizations/{organization}/proposals/{id} - post
/organizations/{organization}/proposals/{id}/withdraw - get
/organizations/{organization}/passports/{id}/links - get
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/affichage - get
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - get
/organizations/{organization}/passports/{id}/variants/review - get
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/units/{unitId}/readings - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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}/grants - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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.
body_too_deep
400The request body nests deeper than this endpoint accepts. details.limit_depth carries the nesting depth of the whole body that was applied.
API returnsThe request body nests deeper than this endpoint accepts.
Which endpoints return this
- post
/organizations/{organization}/grants - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - post
/organizations/{organization}/passports/{id}/documents - post
/organizations/{organization}/imports
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}/grants - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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.
gtin_in_use
409This GTIN belongs to another passport. details names its passport, product_name and role (lead or variant). Use that passport or choose a different GTIN.
API returnsThis GTIN belongs to another passport. Use that passport or choose a different GTIN.
variant_limit_reached
422This passport has reached its variant limit. details carries limit, current and requested. Create a second passport to add more; the limit does not depend on the plan.
API returnsThis passport has reached its variant limit. Create a second passport to add more.
Which endpoints return this
variant_review_required
409This passport carries sizes and colours an assistant wrote. A person reviews them first: read GET …/variants/review, then publish with its fingerprint. details carries agent_written_count and the review URL.
API returnsThis passport carries sizes and colours an assistant wrote. A person reviews them first: read the review, then publish with its fingerprint.
Which endpoints return this
variant_review_changed
409The sizes and colours changed after the review this fingerprint names. Read the review again and publish with its current fingerprint. details carries agent_written_count.
API returnsThe sizes and colours changed after the review this fingerprint names. Read the review again and publish with its current fingerprint.
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
- get
/organizations/{organization}/events - get
/organizations/{organization}/passports - get
/organizations/{organization}/passports/{id}/variants - get
/organizations/{organization}/passports/{id}/units - get
/organizations/{organization}/passports/{id}/units/{unitId}/readings - get
/organizations/{organization}/documents - get
/organizations/{organization}/passports/{id}/documents - get
/organizations/{organization}/imports
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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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}/proposals - post
/organizations/{organization}/proposals/{id}/withdraw - post
/organizations/{organization}/passports/{id}/affichage - post
/organizations/{organization}/passports/{id}/variants - delete
/organizations/{organization}/passports/{id}/variants/{variantId} - post
/organizations/{organization}/passports/{id}/variants/remove - post
/organizations/{organization}/passports/{id}/units - post
/organizations/{organization}/passports/{id}/units/{unitId}/readings - 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
- 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}/proposals - post
/organizations/{organization}/passports/{id}/affichage
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
402Adding these units would take the organization over the battery units it can add this plan year. details carries limit, current, requested, bought_remaining and plan_year_ends.
API returnsAdding these units would take the organization over the battery units it can add this plan year. details carries limit, current, requested, bought_remaining and plan_year_ends.
Which endpoints return this
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
document_feeds_reading
409This document supports recorded battery values and cannot be deleted while those battery records exist. Open the battery model to review those records.
API returnsThis document supports recorded battery values and cannot be deleted while those battery records exist. Open the battery model to review those records.
invalid_input
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
invalid_observed_on
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
invalid_source
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
invalid_field
400The request body failed validation.
API returnsThe request body failed validation.
invalid_note
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
invalid_value
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
invalid_document_id
400The request body failed validation.
API returnsThe request body failed validation.
Which endpoints return this
unit_status_required
400This battery already has a status. Choose a status instead of clearing it.
API returnsThis battery already has a status. Choose a status instead of clearing it.
Which endpoints return this
unit_status_transition_forbidden
409A battery cannot return to Original after another status, or change status after Waste.
API returnsThis battery’s status cannot return to Original or change after Waste.
Which endpoints return this
unit_status_history_conflict
409This status would conflict with the battery’s recorded history. Check the date and status.
API returnsThis status would conflict with the battery’s recorded history. Check the date and status.
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
example_passport_not_fileable
409Example passports from the Playground cannot be filed.
API returnsExample passports from the Playground cannot be filed.
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 directly. For a passport the public can already see, it sends a proposal a person approves.
API returnsThis product is already visible to the public, so an assistant cannot change it directly. To change its fields, or the file behind a field, use propose_changes; a person approves the proposal before the public page changes. For anything else, give a person the editor link in `details.review_url`.
proposal_requires_assistant
403Only an assistant connected through PassportCraft can propose a change. This key can change the passport directly.
API returnsOnly an assistant connected through PassportCraft can propose a change. This key can change the passport directly.
no_changes
422Nothing in the proposal differs from what the passport already holds.
API returnsNothing in the proposal differs from what the passport already holds.
Which endpoints return this
unit_status_not_allowed
422Choose one of the five permitted battery statuses named in the details.
API returnsChoose one of the five permitted battery statuses in `details.allowed`, or leave the status empty.
scope_exceeds_key
422The grant asks for a scope the key does not hold on its own organization. A client's grant never exceeds the key's own.
API returnsA grant cannot carry a scope the key does not hold on its own organization
Which endpoints return this
france_mandate_required
403filings:write cannot be granted for this client yet. A person at your organization must first confirm, in the client's workspace, that you hold its written authorisation to file in France.
API returnsfilings:write needs the client's written authorisation, affirmed in its workspace, before it can be granted
Which endpoints return this
grantor_not_seated
403The person who created the calling key no longer holds a seat in this client's workspace, so nobody can be recorded as giving the grant. Create a new key in Settings.
API returnsThe person who created this key no longer holds a seat in this organization
Which endpoints return this
key_not_grantable
409The key named in key_id is revoked, expired, being replaced, or an assistant connection. None of these can be granted.
API returnsThis key cannot be granted: it is revoked, expired, being replaced, or an assistant connection
Which endpoints return this
grant_conflict
409The key already holds a grant here with different scopes. Revoke it, then grant again with the scopes you want.
API returnsThis key already holds a grant here with different scopes; revoke it, then grant again
Which endpoints return this
live_key_playground_only
403None of your clients is on a paid Pro or Scale plan, so this live key acts on your Playground only. It cannot be given access to a client. A live key that still acts on a client cannot be rotated. A test key can still act on your clients.
API returnsThis live key acts on your Playground only. It can act on a client once one of your clients is on a paid Pro or Scale plan.
Which endpoints return this
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.
Refusals from the PassportCraft app
The signed-in app calls its own routes, and those routes refuse with the codes below. They are not part of the /v1 contract and may change. They are listed so that a message you see in the app, or a help article, has somewhere to point.
billing_managed_by_partner
The workspace's partner manages its billing. Checkout, the billing portal and plan changes all refuse with this code.
API returnsBilling for this workspace is managed by the partner that pays for it
partner_role_fixed
This person works for the workspace's partner. The partner chooses what they can do here, so you cannot change it. The workspace's own owner or administrators can remove them.
API returnsThe partner sets what its staff can do in this workspace.
home_members_only
Only the workspace's own owner or administrators can do this, for example accept, decline or stop a partner. A partner's staff cannot, whatever their role. They can rotate a key only when their partner's staff made it in this workspace and it acts on this workspace alone.
API returnsOnly the workspace's own owner or administrator can do this
client_already_linked
This workspace already has a partner, or a partner's request it has not answered yet.
API returnsThis workspace already has a partner, or a request it has not answered
partner_chain_not_allowed
The workspace already manages clients, or a partner already manages it. An organization can be a partner or a partner's client, never both, so this arrangement cannot start.
API returnsAn organization can manage clients or be managed by a partner, not both
not_a_partner
The organization named in X-Organization does not manage any client.
API returnsThis organization does not manage clients
partner_staff_only
Only the managing partner's own staff can do this, such as confirming a client's written authorisation for France filings.
API returnsOnly the partner's staff can do this
link_not_found
No partner arrangement with that id exists for this workspace.
API returnsLink not found
link_not_pending
That request has already been answered.
API returnsThis request has already been answered
link_not_accepted
The partner arrangement is not active: it is still waiting for an answer, or it has ended.
API returnsThis link is not active
same_organization
An organization cannot manage itself.
API returnsAn organization cannot manage itself
organization_not_found
No workspace matches the address or email given.
API returnsOrganization not found
organization_header_required
The request did not name a workspace. Send the workspace's slug in the X-Organization header.
API returnsThe X-Organization header is required
organization_not_a_member
The signed-in person is not a member of the workspace named in X-Organization.
API returnsNot a member of this organization
continuity_pending
The plan the partner paid for is still running. Billing for this workspace changes on the date it was paid to.
API returnsThe current plan runs to the date it was paid to; billing for this workspace changes after that
partner_terms_missing
No billing terms are recorded for this partner yet, so no plan can be opened on its account.
API returnsThis partner has no billing terms recorded
partner_customer_missing
The partner has no payment account yet.
API returnsThis partner has no payment account yet
partner_card_missing
The partner has no payment method on file. It adds one on its own Billing page.
API returnsThis partner organization has no payment method on file
client_already_subscribed
This workspace already pays for its own subscription.
API returnsThis workspace already has its own subscription
plan_below_current
The plan chosen is smaller than the one this workspace is on.
API returnsThat plan is smaller than the one this workspace is on
continuity_not_available
There is no paid period from a former partner to carry on for this workspace.
API returnsThere is nothing to continue on this workspace
yearly_not_accepted
A client plan opens only after the partner confirms its yearly billing period for that client.
API returnsThe partner has not confirmed the yearly billing period for this client; record its confirmation before opening the plan.
stripe_refused
The payment provider refused the request.
API returnsStripe refused the request
payment_pending
The payment outcome is not yet known. Check the existing request’s status; do not create another client or submit another payment.
API returnsThe payment result is not yet known. Check its status before starting another payment.
price_changed
The confirmed price differs from the latest preview. Review the updated price before submitting again. No client was created.
API returnsThe price changed. Review the current amount before creating the client.
price_changed_after_create
The client was created on Free. The price changed and the unpaid payment attempt was safely closed. Contact support to activate its plan; do not create the client again.
API returnsThe client was added on Free. The reviewed payment did not proceed. Contact support to activate the plan.
creation_token_invalid
This review does not match the user, workspace or client details. Review the correct details again. If a creation request was already submitted and its outcome is unknown, contact support instead of starting again.
API returnsThis creation review is invalid. If creation has already started, check its status or contact support.
creation_token_expired
The creation authorization has expired. Check any existing creation request first; if none was submitted, review the payment again.
API returnsThis creation review expired. Check any existing operation before reviewing a new creation.
creation_operation_expired
The retained status of this creation request is no longer available. Contact support before taking further action; do not create the client again.
API returnsThis operation status is no longer available. Contact support before creating another client.
creation_conflict
This creation request is already tied to different details. Check the original request or contact support; do not start another creation.
API returnsThis operation belongs to different creation details. Check the original operation or contact support.
client_creation_undone
Nothing was created and nothing was charged. Review the payment and try again.
API returnsThe client could not be created and nothing was charged. Review the payment again.
client_vat_unverified
A workspace takes over billing only once it has given its country.
API returnsGive the workspace's country before you add a card.
client_details_required
A client workspace needs the client's legal name and an email address for our notices.
API returnsThe client's legal name and an email address for notices are required.
terms_acceptance_required
A workspace accepts a partner's request, or buys a paid plan, only together with the current Terms of Service and Data Processing Agreement.
API returnsAccept the current Terms of Service and Data Processing Agreement together with the request.
client_not_managed
The organization named is not a client your organization manages.
API returnsThat organization is not a client your organization manages
keys_admin_partner_only
keys:admin can only be given to a key that belongs to an organization that manages clients.
API returnskeys:admin can only be granted on the own keys of an organization that manages clients
grant_not_found
No key from another organization holds access to this workspace under that id.
API returnsNo key from another organization holds a grant here under that id
partner_agreement_required
The partner has not accepted the current partner agreement, or its agreement has ended. It accepts the agreement on its Partner terms page.
API returnsThis partner has not accepted the current partner agreement, or its agreement has ended. It must accept the agreement on its Partner terms page first.
agreement_unpublished
The partner agreement is not published yet, so it cannot be accepted.
API returnsThe partner agreement is not published yet
agreement_text_changed
The agreement changed while the page was open. Reload Partner terms and accept the version shown.
API returnsThe agreement changed after it was shown. Reload the page and accept the version shown.
partner_admin_access_fixed
This person is an owner or administrator at the partner, so they work on every client the partner manages. An owner always works on every client. To choose an administrator's clients, make them an editor or viewer at the partner first.
API returnsOwners and administrators work on every client. To limit an administrator's clients, make them an editor or viewer on your Team page first.
seat_removed_by_client
The client removed this person from its workspace. The partner cannot add them back. The client's owner or administrator can allow them again from the client's Team page.
API returnsThe client removed this person from its workspace. Only the client can allow them again.
partner_staff_managed_by_partner
A partner's staff cannot remove each other from a client's workspace. The partner chooses its staff's clients from its own Team page, and the client's own owner or administrators can remove anyone.
API returnsOnly this workspace's own owner or administrators can remove a partner's staff here. The partner can change its staff's clients from its own Team page.
member_not_found
This person is no longer on the team. Reload the list and try again.
API returnsMember not found
playground_has_no_plans
The workspace is a partner's Playground. It has fixed limits and no plan to buy, so checkout, plan changes and buying serial numbers all refuse with this code. A partner buys a plan for a client when it adds the client.
API returnsYour Playground has fixed limits and no plan to buy. To buy a plan for a client, use Add client on the Clients page. Client billing, under Partner settings, shows what you pay.
client_not_partner_paid
The partner does not pay for this client's plan, the partner arrangement with the client is ending, or the client's plan is set to cancel. Moving the client to a larger plan and adding serial numbers for it both refuse with this code.
API returnsYour organization does not pay for this client's plan, or the client is leaving or set to cancel.
partner_agreement_ended
The partner agreement has ended, so the partner cannot move a client to a larger plan.
API returnsYour partner agreement has ended, so a client's plan cannot move to a larger plan.
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.
type_text
blocks publishThe field holds text, and the value was not text — most often a number, a boolean or a list sent for a field the category schema declares as text, or for a choice field that also takes a written-in answer.
How to fixSend the value as a JSON string. Read type on the field in the category schema. A select that offers an other option takes a written-in answer as a string too.
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.
Passport data limits
The data of a passport has limits on its size. A create, an update or a proposal that would leave the data past one of them is refused with a 422 validation_failed. The validate endpoint answers with the same 422 when our check finds the data past a limit. Close to the byte limit, the database can still refuse the data on save, even after that check accepted it. One issue under error.details.issues names the rule. An import row that would do the same fails with field_wrong_shape. The same issue sits under error.detail.issues on the row. Each issue has source.pointer, rule, limit and received. Branch on the rule, never on the message.
source.pointer names the top-level field that holds the problem, as the passport would look after your change. On an update, a proposal or a request to the validate endpoint this can be a field you did not send. The pointer starts at /data on a create, an update and a request to the validate endpoint, and at /fields on a proposal. On an import row it starts at /rows/<n>/data, where n is the row's index in the import. A rule about the whole passport, such as too_many_fields, points at that start alone.
received is a count of entries for list_too_long and too_many_entries, and a count of top-level fields for too_many_fields. For data_too_large it is a size in bytes. When the database finds that breach, it counts the stored JSON text, which can be a little larger than the JSON you sent. For number_out_of_range, limit and received are null, because the response never repeats the number.
list_too_long
One list in the passport data holds more than 500 entries. A list counts wherever it sits, including inside another list or inside an object.
How to fixCut the longest list in the field that source.pointer names, down to 500 entries or fewer. A PATCH replaces a list as a whole, so send the shortened list.
API returns"limit": 500
too_many_entries
The lists in the passport data together hold more than 5,000 entries. Every list counts, including lists inside other lists.
How to fixRemove entries until the lists hold 5,000 entries or fewer in total. source.pointer names the field that holds the most entries.
API returns"limit": 5000
data_too_large
The passport data is larger than 262,144 bytes as JSON text. Bytes are counted in UTF-8, so one character can take up to four bytes.
How to fixShorten the text in the largest field, which source.pointer names, or remove values the passport does not need.
API returns"limit": 262144
number_out_of_range
A number in the passport data is outside the range the passport accepts. Zero is accepted. Any other number must be at least 1e-30 and below 1e30, ignoring its sign.
How to fixFind the number in the field that source.pointer names and send one inside that range.
API returns"limit": null
too_many_fields
The passport data has more than 1,000 fields at its top level.
How to fixRemove top-level fields the passport does not need. The category schema lists the fields a category defines.
API returns"limit": 1000
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 claims, found in its wording or in fields the brand marked as environmental information. 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.