Skip to content
Sandbox

Errors

Every error is an RFC 9457 Problem Details object whose code alone is a machine contract. The format, the complete catalogue of codes by status, and what to do for each.

View as Markdown

Every Noryo Merchant API error is a Problem Details document (RFC 9457), served as application/problem+json.

{
  "type": "https://developer.noryo.app/errors/idempotency_key_reuse",
  "title": "Idempotency key reused",
  "status": 409,
  "code": "idempotency_key_reuse",
  "detail": "this Idempotency-Key is bound to a different request for the remainder of its TTL",
  "request_id": "req_01a07784-d343-75f8-b0ae-b0629b305cd4"
}
JSON

The fields

FieldContentStable?
typeThe address of the code's page in the error catalogueThe link may change domain; the code does not
titleA short title, in English, for a humanNo: may be reworded
statusThe HTTP status of the response, for every code
codeThe machine code, in snake_caseYes: it is the contract
detailA sentence in English, sometimes more specific than the titleNo: may be reworded
request_idThe identifier of the attempt, identical to the Noryo-Request-Id header

A 410 adds enrichment_id, and so does a 503 engine_error: there it designates the failed attempt, not a result. No other member is added.

Important

Build your logic on code, and on the HTTP status. title and detail are written for humans and may be reworded at any time without a version change: a client that parses them will break at the first editorial pass.

Error bodies never carry a SQLSTATE, a table name, a stack trace, an internal hostname, or the value of your key or your Idempotency-Key. A 500 carries only code and request_id as useful information.

The catalogue

Each code has its own page in the error catalogue.

StatusCodeWhenWhat to do
400invalid_requestBody outside the schema, unknown field, external_transaction_id on a refresh, unknown hostFix the request
400invalid_jsonBody that is not valid JSONFix the request
400identifier_requiredCreate call with neither Idempotency-Key nor external_transaction_id; refresh without Idempotency-KeyAdd the identifier
400invalid_idempotency_keyIdempotency-Key header empty, too long, repeated or outside visible ASCIIFix the key
400invalid_inputNot returned by the current routesNone
400refresh_requires_transaction_idNot returned by the current routes: a refresh of an enrichment without external_transaction_id returns 409 refresh_not_availableSee Refresh
400target_enrichment_requiredNot returned by the current routes: the path always names the targetNone
400unsupported_canonicalizationNot returned by the current routesContact support with the request_id
401invalid_api_keyKey missing, malformed, unknown, revoked or with the wrong prefixFix the key
402sandbox_quota_exhaustedSandbox allowance exhaustedMove to Production
402no_active_subscriptionNo active subscription covers the operationPut the account in order
403insufficient_scopeThe key lacks the route's scopeUse a key with the right scope
403account_inactiveOrganisation or workspace inactiveContact Noryo
403production_not_enabledThe key is not allowed in ProductionSee Going live
404enrichment_not_foundenrichment_id unknown, malformed, from another workspace or environmentCheck the identifier, the key, the environment
404transaction_not_foundRefresh of a transaction with no recorded resultCreate an enrichment first
409idempotency_key_reuseSame Idempotency-Key, different request, within 24 hoursA new key for a new request
409transaction_id_conflictSame external_transaction_id, different economic inputFix the input or the identifier
409input_mismatchRefresh whose input differs from the transaction'sSend the original input
409refresh_not_availableOriginal enrichment without external_transaction_idRead with GET, or create with an identifier
410result_content_expiredContent purged after 90 daysSee Retention and 410
413request_entity_too_largeBody over 16 KiBShrink the body
415unsupported_media_typeContent-Type other than application/jsonSend JSON
429rate_limitedRate-limit bucket emptyRetry after Retry-After
500internal_errorUnexpected errorRetry with the same key; quote the request_id
503engine_errorThe resolution engine did not answer; nothing billed or memorisedRetry with the same key
503busyTransient contention, or an identical request in progressRetry after Retry-After
503pricing_not_activatedBilling not yet activated for the operationRetry after Retry-After

Retry policy

StatusRetry?
429Yes, after Retry-After
503Yes, with the same Idempotency-Key: nothing was billed or memorised
500Yes, with the same Idempotency-Key
409No: fix the payload or the key
Other 4xxNo

Details are in Retries.

The attempt identifier

Every response carries Noryo-Request-Id, and every error body repeats it in request_id. One attempt has exactly one identifier: the same one in the header, the body and Noryo's logs, including on a 500. Quote it to support and we can find the exact attempt. See Request IDs.

Published on 2026-10-09 10:18 UTC (version 2).

Was this page helpful?