Reason codes

Generated from reason-codes.json, which is the contract. The reason-code vocabulary, by step of the seller's twelve-step sequence (architecture v0.2 §5.6, §8). `status` is the HTTP status the seller answers with; `entry` says whether a signed request.refused entry is written (check 1 never writes; it counts). `seller` says whether agent-bench raises the code today on the signed-envelope path; the self-issued authorization path (demo scripts) keeps its pre-v0.2 codes, marked `legacy`. Buyer-side codes are raised by the buyer against the seller and appear in the buyer's ledger.

Causes

Since 2026-09-26 (D-136): where one code has several causes, the refusal carries `detail`, one of these names, on every face (the error body over REST, error.data over A2A and UCP MCP, the message over UCP REST as <namespace>.detail, the text over MCP) and in the seller's request.refused entry (facts.detail). Every refusal also carries `contract`, the address of this contract's page for the code or the cause (reason-codes.html#<code> or #detail-<name>), when the seller is configured with CONTRACTS_URL. A code without a detail has one cause, or its message names it well enough. Names are stable: a cause that changes gets a new name.

CauseCodeWhat failed
not_sd_jwtmandate_invalidA chain token is not an SD-JWT (issuer JWT followed by ~-separated disclosures).
kb_jwt_not_acceptedmandate_invalidA token ends in a Key Binding JWT; this profile binds with a kb+sd-jwt hop, not a KB-JWT.
disclosure_emptymandate_invalidA token has an empty disclosure segment.
sd_alg_unsupportedmandate_invalid_sd_alg is not sha-256.
disclosure_repeatedmandate_invalidThe same disclosure appears twice.
disclosure_not_jsonmandate_invalidA disclosure does not decode to JSON.
disclosure_malformedmandate_invalidA disclosure is not [salt, name, value] or [salt, value].
disclosure_referenced_twicemandate_invalidOne disclosure is referenced by two digests.
disclosure_wrong_kindmandate_invalidAn object-property disclosure stands where an array element is referenced, or the reverse.
sd_array_malformedmandate_invalidAn _sd array holds something other than digests.
disclosure_name_reservedmandate_invalidA disclosed claim name collides with another or is reserved (_sd, ...).
disclosure_unreferencedmandate_invalidA disclosure is carried that no digest references.
delegate_payload_not_onemandate_invalidThe open mandate does not disclose exactly one delegate_payload item.
root_kid_unknownissuer_not_allowedThe root is signed under a kid no accepted issuer publishes (for a guest: not in its profile or TXT record).
root_iss_mismatchissuer_not_allowedThe root names an iss other than the issuer whose key signed it.
vct_unexpectedmandate_invalidAn open or closed mandate has a vct other than the profile's (mandate.checkout.open.1, mandate.checkout.1, mandate.payment.open.1, mandate.payment.1).
cnf_missingkey_binding_mismatchThe open mandate names no P-256 key in cnf.jwk.
intermediate_hopmandate_invalidA hop is an intermediate kb+sd-jwt+kb: delegation chains are not accepted.
hop_kid_mismatchkey_binding_mismatchThe closing hop names a kid other than the key the root binds (cnf.jwk).
hop_signature_mismatchkey_binding_mismatchThe closing hop is not signed by the key the root binds.
sd_hash_mismatchmandate_invalidThe closing hop's sd_hash is not the hash of the root presented with its disclosures.
issuer_jwt_hash_bindingmandate_invalidThe closing hop binds by issuer_jwt_hash; this profile binds by sd_hash.
hop_iat_missingmandate_invalidThe closing hop carries no iat.
nonce_mismatchmandate_invalidThe closing hop's nonce is not this checkout's (over UCP: the session id).
terminal_hop_cnfmandate_invalidThe closing hop carries cnf: a terminal hop names no further key.
constraints_missingmandate_invalidThe open mandate carries no constraints array.
constraint_untypedmandate_invalidA constraint has no type.
constraint_unresolvedmandate_invalidA constraint type this seller does not evaluate (AP2 receipt: unresolved_constraint).
constraint_repeatedmandate_invalidThe same constraint type appears twice.
open_root_alonemandate_invalidA chain is an open root with no closing hop.
chain_too_longmandate_invalidA chain has more than a root and one terminal hop.
sub_missingmandate_invalidThe open mandate names no person (sub). In both mandate forms (the AP2 chains' open root, the mandate+jwt).
act_sub_invalidmandate_invalidThe open mandate's act.sub is absent or not a spiffe:// URI (a guest's: spiffe://<its domain>/buyer/guest/<kid>). In both mandate forms (the AP2 chains' open root, the mandate+jwt).
delegation_act_actmandate_invalidThe open mandate carries act.act (a delegation chain). In both mandate forms (the AP2 chains' open root, the mandate+jwt).
roots_disagreemandate_invalidThe checkout and payment roots differ in iss, sub, jti, policy_version, iat or exp: they are two halves of one approval.
roots_bound_apartmandate_invalidThe two roots bind different keys (cnf) or name different buyers (act).
roots_issuers_differmandate_invalidThe two roots are signed by different issuers.
merchants_missingmandate_invalidcheckout.allowed_merchants allows no merchant.
line_items_not_onemandate_invalidcheckout.line_items does not require exactly one item.
payment_instrument_missingmandate_invalidThe closed payment mandate names no payment instrument (id and type).
payment_reference_missingmandate_invalidThe open payment mandate carries no payment.reference constraint.
payment_reference_mismatchmandate_invalidpayment.reference names another checkout mandate than the one presented (sd_hash).
iat_exp_missingmandate_invalidThe open mandate carries no iat and exp.
hop_outside_windowmandate_invalidA closing hop was signed outside the open mandate's window.
hop_not_freshmandate_invalidA closing hop was signed more than the allowed skew away from now.
jti_unusablemandate_invalidThe open mandate's jti is absent or shorter than 16 characters. In both mandate forms (the AP2 chains' open root, the mandate+jwt).
cnf_not_request_keykey_binding_mismatchThe mandate binds a key other than the one that signed the request. In both mandate forms (the AP2 chains' open root, the mandate+jwt).
act_sub_not_requesterkey_binding_mismatchThe mandate names a buyer (act.sub) other than the one making the request. In both mandate forms (the AP2 chains' open root, the mandate+jwt).
quote_other_buyer_keykey_binding_mismatchThe quote was issued to another buyer key.
authorization_other_partykey_binding_mismatchThe checkout authorization does not belong to the party the quote was issued to.
detached_jws_malformedmerchant_authorization_invalidap2.merchant_authorization is not a detached JWS (header..signature).
checkout_jwt_missingmandate_invalidThe closed checkout mandate carries neither checkout_jwt nor an embedded checkout with ap2.merchant_authorization.
kid_not_sellermerchant_authorization_invalidThe embedded checkout is signed under a kid other than this seller's instance key.
signature_not_sellermerchant_authorization_invalidThe embedded checkout does not verify under this seller's key: reattach the payload as the seller sent it (the checkout without ap2, RFC 8785) between header and signature.
not_compact_jwsthe code of the token being read (authorization_invalid, mandate_invalid, merchant_authorization_invalid, …)The token is not three non-empty base64url segments.
jws_not_jsonthe code of the token being read (authorization_invalid, mandate_invalid, merchant_authorization_invalid, …)The token's header or payload is not JSON.
jws_header_not_objectthe code of the token being read (authorization_invalid, mandate_invalid, merchant_authorization_invalid, …)The token's header is not a JSON object.
kid_missingthe code of the token being read (authorization_invalid, mandate_invalid, merchant_authorization_invalid, …)The token names no kid.
action_not_purchasemandate_invalidThe mandate's action is not purchase (R-09).
stage_not_cartmandate_invalidThe mandate's stage is not cart or payment: a checkout needs a mandate bound to the quote.
exp_missingmandate_invalidThe mandate carries no exp.
guest_mandate_too_longmandate_invalidA guest mandate lives longer, from its nbf (or iat) to its exp, than the guest tier allows (600 s).
guest_mandate_no_startmandate_invalidA guest mandate carries neither nbf nor iat, so its life cannot be measured.
mandate_unknown_to_authoritymandate_invalidThe authority that issued the mandate does not know it (check 10).

By check

Check 1: size, content type, method, protocol version, rate

Writes no entry; counted.

CodeHTTPWhat it means
request_too_large413Also 400 on the UCP face for a catalog lookup naming more than 20 distinct ids (Catalog Lookup, Batch Size), -32602 over MCP (ucp-profile.md §8).
request_invalid415Also 400 for a body that is not JSON, dropped at the entrypoint, 400 for a malformed correlation_id or one that differs between body and envelope, and 400 for a malformed exercise marker (the caller's test-vector claim; see ledger-entry.schema.json, claimed_exercise).
method_not_allowed405
protocol_unsupported400MCP-Protocol-Version the server does not speak.
rate_limited429A Cloudflare edge rule, so it never reaches the Durable Object. Not yet created.

Check 2: request envelope: signature, typ, nonce, timestamp within 60 s, replay cache

Writes a signed request.refused entry.

CodeHTTPWhat it means
signature_invalid401Not a compact JWS; body edited after signing (R-07, body_sha256); method or path differ; nonce too short; signature fails under the attested key.
header_forbidden401alg other than ES256; jku, x5u, jwk, x5c (outside the key attestation) or crit present. R-21, R-22, R-23.
typ_mismatch401
audience_mismatch401The envelope's aud is not this seller (also raised at check 5 for the mandate, 403).
nonce_replayed401Per signer: a nonce is spent by the key that signed it.
timestamp_out_of_window401

Check 3: buyer identity: key attestation, SVID chain, bundle, SPIFFE ID, optional ANS status

Writes a signed request.refused entry.

CodeHTTPWhat it means
signer_unknown401No valid attestation at https://<trust domain>/.well-known/agent-keys.json names the envelope's kid, or it names it for another SPIFFE ID, or the trust domain is not on BUYER_TRUST_DOMAINS when that is set, or the buyer's documents cannot be fetched. Where the seller takes guests (guest-buyer.md, since 2026-09-18) the kid is looked for first in the TXT record set at _agent-keys.<trust domain>: a record that names it from a zone the resolver did not validate (no AD) is refused with this code and the sentence that says to sign the zone, and a kid found in neither form gets a message that names both.
svid_invalid401Raised by the seller's own SVID verifier (verify:ledger, watcher); the buyer's SVID is verified through the attestation.
attestation_invalid401Raised while resolving keys: bad signer (no kid, no x5c), chain does not reach a CA in the bundle, leaf names another SPIFFE ID, expired, sub is not the thumbprint of cnf.jwk. Surfaces to the caller as signer_unknown; the detail is in the seller's logs, not in the refusal.
identity_revoked403The envelope's kid is listed in the key-revocation+jwt the buyer's domain publishes as `revocations` in /.well-known/agent-keys.json (schemas/key-revocation.schema.json), verified under the bundle like an attestation. Raised after the envelope signature verified under the attested key, so the entry names the revoked instance (buyer, buyer_kid) and counts against its budget as an attested source. Read at the same fetch as the attestations, cached a minute per domain (F-07b).
ans_not_active403Since 2026-09-16 (D2): the buyer's trust domain has an `_ans` TXT (it registered in the ANS) and the transparency-log entry its `_ans-badge` names is not ACTIVE, or the badge is missing or the entry carries no Merkle proof. Read once per trust domain per cache fill, beside the attestations; raised after the envelope signature verified, so the entry names the instance. A domain with no `_ans` TXT is not judged; a resolver or log that cannot be read is not consulted and never refuses (the identity anchor is the domain's own DNSSEC and DANE, the registry an opinion).

Check 4: mandate issuer on the allow-list, JWKS by domain, signature

Writes a signed request.refused entry.

CodeHTTPWhat it means
issuer_not_allowed403In the AP2 v0.2 form: the root's kid is in no trusted authority's key set, or the open content's iss is not the authority whose key verified. Where the seller takes guests (guest-buyer.md): an issuer that is neither listed nor the guest's own, https://<trust domain of the envelope> with its key in the DNS TXT record on the A2A face, the platform's origin with its key in the UCP profile on the UCP face, or a guest issuer whose _agent-keys record set came from a zone the resolver did not validate; the message says what a guest mandate needs. The guest form exists for mandate_jws only on the A2A face, where mandate_ap2 from an unlisted issuer is refused as before, and for the AP2 chains only on the UCP face.
mandate_invalid403Not a mandate+jwt; kid not in the issuer's key set (after one refresh); no sub; no act.sub; a delegation chain (R-12, act.act); action other than purchase; stage other than cart/payment at checkout; no exp; jti too short; unknown to the authority (check 10). In the AP2 v0.2 form (mandate_ap2, since 2026-09-13): not a root plus one terminal kb+sd-jwt hop (an open root alone, a third token, an intermediate kb+sd-jwt+kb hop, a KB-JWT-bound presentation); a disclosure nothing references, referenced twice, malformed, or an _sd_alg other than sha-256; a hop whose sd_hash is not this root's; cnf in the terminal hop; the two roots disagreeing on iss, sub, jti, policy_version, iat, exp, cnf or act; act.act; vct not the profile's. In the AP2 v0.2 form a root typ outside {example+sd-jwt, dc+sd-jwt, vc+sd-jwt} or a hop typ other than kb+sd-jwt is typ_mismatch at step 4.
signature_invalid403The mandate does not verify under the key its kid names.
mandate_missing403A signed envelope checking out without mandate_jws. Also the OAuth path: authenticated subject with no mandate granted.
authority_unavailable503The issuer's key set cannot be read.
authorization_missing401Self-issued path: no bearer at all.
authorization_invalid401Self-issued path: not a JWS, no kid, kid not in the key set, kid not the key's thumbprint.
authorization_denied403Self-issued path: wrong issuer, no subject, missing scope, missing grant, ceiling below the amount.

Check 5: audience

Writes a signed request.refused entry.

CodeHTTPWhat it means
audience_mismatch403In the AP2 v0.2 form: the hop's aud is not this seller's base URL.

Check 6: merchant, action, stage, currency, amount equal to the stored quote total

Writes a signed request.refused entry.

CodeHTTPWhat it means
merchant_mismatch403In the AP2 v0.2 form: checkout.allowed_merchants does not carry our merchant id, the payee (open preset or closed) is not us, or checkout.line_items does not accept the quote's offer at quantity 1.
currency_mismatch403
amount_mismatch403At the cart stage the amount must EQUAL the quote total. On the self-issued path the ceiling only has to cover it, and the refusal is authorization_denied. In the AP2 v0.2 form: the open payment mandate's preset payment_amount, or the closed one, differs from the quote total.
guest_ceiling_exceeded403A guest mandate (guest-buyer.md) for more than GUEST_CEILING_MINOR, 100000 minor units unless set. Raised after the issuer's signature held and the claims every mandate is held to passed, so the entry names the person hash, the buyer and the jti. Above the ceiling the mandate has to come from a listed authority.
mandate_invalid403action other than purchase (R-09), or a stage that is not cart/payment. In the AP2 v0.2 form: a constraint type this seller does not evaluate (the AP2 receipt says unresolved_constraint), no line item requirement or more than one, no payment instrument, no payment.reference.
mandate_denied403OAuth path: mandate does not cover merchant, currency or amount.
checkout_invalid400Checkout body without the configured merchant_id, currency and a quote_id.

Check 7: quote hash

Writes a signed request.refused entry.

CodeHTTPWhat it means
quote_hash_mismatch409The mandate's quote_hash, or a stated quote_hash in the body, differs from the seller's recomputation over the stored JWS (R-08). In the AP2 v0.2 form: the closed checkout_jwt differs from the stored quote JWS byte for byte, or checkout_hash / the payment's transaction_id is not the base64url SHA-256 of that JWS. A payment.reference naming another checkout root is mandate_invalid at this step.
quote_unavailable409Unknown or expired quote id, or a stored quote whose JWS no longer decodes.

Check 8: time window (60 s skew)

Writes a signed request.refused entry.

CodeHTTPWhat it means
mandate_not_yet_valid403
mandate_expired403In the AP2 v0.2 form the window is the open content's iat/exp; a hop iat outside it or not within the skew of now is mandate_invalid at this step.

Check 9: single use (jti) and key binding equals the request signer

Writes a signed request.refused entry.

CodeHTTPWhat it means
mandate_consumed409Cites the first use: request_id, correlation_id, and once settled the payment_intent_id and ledger entry hash. R-06, R-26. In the AP2 v0.2 form the two roots share one jti, claimed once for the pair. A jti is spent under its issuer (since 2026-09-25): a guest's under its origin, so the same jti from a listed authority, or from another guest, is another mandate and is not refused for it. The detail says the next step (since 2026-09-25): a mandate buys once, so a new quote needs a new mandate, and a new quote under the same mandate is refused the same way.
key_binding_mismatch403cnf.jkt differs from the envelope signer's kid, or the mandate carries no cnf at all (R-05: both are a binding that fails at check 9, never mandate_invalid at check 4; settled 2026-09-12); act.sub differs from the envelope's iss; the quote was issued to another buyer key; on the self-issued path, another subject than the quote's. In the AP2 v0.2 form: the hop is not signed by the root's cnf.jwk, that key's thumbprint is not the envelope signer's kid, act.sub is not the envelope's buyer, or the root names no key. A hop answering another nonce than the quote's jti is mandate_invalid at this step.

Check 10: revocation status at the authority, fail closed

Writes a signed request.refused entry.

CodeHTTPWhat it means
mandate_revoked403GET <issuer>/mandates/<jti> answered status revoked. The claim on the jti is released: nothing was spent. For a guest mandate (guest-buyer.md) there is no status to ask: the seller reads the guest's keys again, the DNS TXT record on the A2A face (_agent-keys.<domain>, uncached on its side), the UCP profile on the UCP face (under its 60-second floor), and refuses with this code when a key that signed the mandate is no longer published there (revoked_at null: neither says when). It takes effect within the record's TTL at the resolver, or within a minute for a profile.
authority_unavailable503No answer after one retry, a non-2xx other than 404, or a status the seller does not act on. Fail closed; the claim is released; retryable (R-18). For a guest mandate, at the fresh read of check 10: the resolver could not be read, or answered without AD, for the DNS TXT record on the A2A face; the UCP profile could not be read on the UCP face.

Check 11: the payment adapter

Writes a signed request.refused entry.

CodeHTTPWhat it means
stripe_unavailable502Authentication or authorization failure at the rail: a misconfigured merchant.
stripe_invalid502A definite 4xx or an incomplete answer: nothing created, mandate released.
payment_unknown502NOT a refusal: writes payment.ambiguous, leaves the mandate retryable with the same idempotency key. The buyer moves to REVIEW_REQUIRED.

Other seller codes

CodeHTTPWhat it means
edge_attestation_invalidREQUIRE_EDGE_ATTESTATION mode only.
offer_invalidThe flight tool answered in another currency or with an unusable amount (502).
google_flights_unavailableSerpApi quota or key failure (502). Not the fallback case.
google_flights_no_offerA fare that cannot be expressed in minor units (502). Not the fallback case either: an empty answer falls back to the fixture, a malformed one does not.
origin_refusedMCP: a browser Origin this endpoint does not allow (403).
sse_unsupportedMCP: GET on the endpoint (405).
not_foundUnknown route (404).
admin_deniedMandate administration without the operator credential (401).
witness_unavailableSealing: the witness could not be reached or answered non-2xx. The checkpoint is published unsealed with this error on it; the transaction is not affected. The buyer writes the same word on its own unsealed checkpoints.
receipt_invalidSealing: the witness receipt does not verify under its key set or does not name the checkpoint. Kept as an error on the unsealed checkpoint.
evidence_request_invalidGET /evidence/<jti> (evidence-api.md): no bearer token, not a compact JWS of typ evidence-request+jwt, a kid the verifier's key set does not carry, a signature that does not verify, aud not this seller, iat outside the skew, exp past or more than 120 s after iat, no usable jti, a replayed jti, or mandate_jti not the path's (401).
verifier_not_allowedGET /evidence/<jti>: the request's iss is not on VERIFIERS, or VERIFIERS is empty (403). A policy decision, as issuer_not_allowed is for authorities.
verifier_unavailableGET /evidence/<jti>: the verifier's key set at <iss>/.well-known/jwks.json could not be read, so the request cannot be checked (503).
evidence_not_foundGET /evidence/<jti>[?issuer=<origin>]: no purchase in AP2 form presented that jti under the issuer asked for (a listed authority when issuer is absent, evidence-api.md v0.2), or its retention window (EVIDENCE_RETENTION_DAYS) passed (404).
guest_budget_exhaustedcreate_checkout under a guest mandate (guest-buyer.md) when the day's guest purchases are spent (429): GUEST_PURCHASES_PER_DAY, 20 unless set, per UTC day, all guests together (a count per domain would bound nobody: a zone has as many names as its owner likes). Taken after checks 4 to 10 passed and before the rail, so only a purchase that would have gone through spends one; the claim on the jti is released. Step null: a limit on what nobody this merchant knows vouched for, not one of the twelve checks.
search_budget_exhaustedsearch_flights with no credential at all, when the anonymous budget is spent (429): ANONYMOUS_SEARCHES_PER_DAY and ANONYMOUS_SEARCHES_PER_MONTH, 10 and 60 unless set, counted per UTC day and month, spent only after the input validated and before the provider is called. Written as request.refused with source anonymous and step null: a limit on what nobody vouched for, not one of the twelve checks. An operator token with commerce:search is never refused for this reason. An envelope under an attested key spends, since 2026-09-25, its trust domain's own daily budget (ATTESTED_SEARCHES_PER_DAY, 20 unless set, per UTC day and per domain) unless the domain is on UNBUDGETED_BUYER_DOMAINS, and is refused by it with source key:<kid> and the domain named; a guest's search (an envelope under a key from _agent-keys, guest-buyer.md) spends this budget and is refused by it, with source key:<kid>. Anonymous search is open since 2026-09-14 (D-097).
signature_missingUCP face (ucp.mjs, httpsig.mjs): a completion under the AP2 extension, or any request that must be signed, without Signature-Input and Signature headers (401).
key_not_foundUCP face: the signature names a keyid that the platform profile's keys[] does not publish, after one forced refresh of the profile (401).
digest_mismatchUCP face: Content-Digest does not match the SHA-256 of the body as received (400).
algorithm_unsupportedUCP face: the published key is of a type this verifier does not speak (RSA, an unknown curve); the key set stays valid, the signature is skipped (400).
invalid_profile_urlUCP face: no UCP-Agent header (or meta.ucp-agent on MCP), a profile URL that is not https, that carries credentials, or that names a special-use address (400).
profile_unreachableUCP face: the platform profile could not be fetched, answered non-200 or redirected (424); or the seller's per-minute budget for resolving unknown profiles is spent (503, Retry-After).
profile_malformedUCP face: the platform profile is not JSON, has no ucp object or no date-shaped ucp.version, or exceeds the size bound (422).
version_unsupportedUCP face: the platform profile declares a UCP version this seller does not speak (422).
idempotency_key_reusedUCP face: an Idempotency-Key (or meta.idempotency-key) reused with a different body, by the same platform and operation (409).
forbiddenUCP face: a checkout session read or changed by a platform other than the one that opened it (403).
invalid_requestUCP face: an Idempotency-Key that is not a string of at most 256 characters (400); a catalog request the Catalog schemas do not admit where the seller reads it, such as a lookup without ids, a get_product without id, a field of the wrong type or a cursor the seller did not issue (400, -32602 over MCP; ucp-profile.md §8).
merchant_authorization_invalidUCP face, check 7 (in band, on the checkout with an AP2 error receipt): the checkout the closed mandate embeds (checkout_jwt, or the checkout object with ap2.merchant_authorization) is not this seller's own signature, or its header names another key (403 as a reason; the HTTP answer is 200 with messages[]).
mandate_scope_mismatchUCP face, check 7 (in band): the checkout the closed mandate embeds differs from the session in id, currency, line items or totals (409 as a reason; the HTTP answer is 200 with messages[]).

Buyer side

Raised by agent-buyer (since 2026-09-09) in its own ledger. It also records seller-side and JWS words when it runs the same check itself: quote_invalid, authorization_missing and the JWS policy codes in request.refused; mandate_invalid and key_binding_mismatch in mandate.denied, when a mandate from the authority fails the buyer's own verification. Webhook counters with no reply and no entry: body_invalid, signature_missing, signature_invalid (X-Hub-Signature-256), verification_refused (subscribe handshake).

CodeHTTPWhat it means
dnssec_unvalidatedThe resolver did not validate the chain.
dane_mismatchThe TLSA on the connected host does not match the served certificate (strict, both seller hosts).
record_signature_invalidThe record's sig SvcParam does not verify against the zone's key set, or has lapsed.
card_digest_mismatchThe fetched card bytes do not hash to cap-sha256.
endpoint_out_of_zoneA validly signed card declares an endpoint outside the agent's zone (R-27). POC profile rule, stricter than DNS-AID, ARD and A2A.
ans_not_activeThe registry entry is not ACTIVE in the window. Not raised yet: the buyer does not check ANS (optional, architecture §5.3).
sender_unknownWhatsApp message from a number not on the allow-list: no reply, a counter, no entry (R-25).
verification_failedA check of the seller failed after discovery; the buyer writes counterparty.verified with ok false and sends no request (added 2026-09-10, buyer state machine).
quote_unavailableThe seller answered the search with no option; nothing to bind, REJECTED.
authority_unavailableThe mandate authority could not be reached, or answered nothing usable, at any of its endpoints. Fail closed: no checkout, mandate.denied with this reason (R-18).
mandate_deniedThe authority issued no mandate: the person denied, the standing ceiling does not cover it, the approval link expired. facts.authority_reason carries the authority's own word; mandate.denied, REJECTED.
settlement_invalidThe seller's checkout answer accounts for the money in a way the contract does not: a rail other than simulation or stripe-test, a charge on the simulation rail, a capture on stripe-test with charged false, or no word on the charge (ledger-entry.schema.json, settlement). The receipt is not sealed; the purchase waits in review (added 2026-09-09; the stripe-test capture, charged true in test mode, allowed since 2026-09-12).
response_invalidThe seller's answer to the checkout could not be read after it was sent; the outcome is unknown, so REVIEW_REQUIRED and payment.ambiguous, never REJECTED.
dns_unavailableThe resolver answered an error, or nothing, for a record discovery needs.
record_missingNo SVCB record at the agent's name.
fetch_failedA pinned HTTPS fetch (card, key set) answered other than 200.
correlation_mismatchThe seller did not echo the buyer's correlation id, or a signed quote carries another.
seller_errorThe seller refused with no code the buyer can read.
capabilities_incompatibleThe seller's UCP profile and this buyer's have no usable intersection: the checkout and the AP2 Mandates extension at the release this buyer speaks are not both there, or a session opened requires_escalation (the seller would hand the person to continue_url). Read at discovery, before the person is asked anything (ucp_client.py, 2026-09-24).
ucp_key_mismatchThe seller's UCP profile publishes no key equal to the instance key its SVID vouches for: the party that would sign UCP responses and the merchant authorization is not the one the record led to.
payment_handler_unsupportedThe seller's UCP profile declares no payment handler that takes a card instrument whose credential is the closed AP2 Payment Mandate; this buyer pays with nothing else.
issuer_not_acceptedThe seller lists, under its own namespace, the mandate authorities it accepts, and none of this buyer's is among them: a mandate would be refused at check 4, so nobody is asked to approve one.
transport_unsupportedThe seller's UCP profile declares no rest or no mcp endpoint for the shopping service; this buyer opens the session over rest and reads the catalog over mcp.
seller_unreachableThe seller did not answer the request that opens a checkout session; nothing was sent that could move money.
no_offer_on_airlinesSince 2026-09-26: the person allowed only some airlines for the purchase and the seller has no itinerary on them for the route and date (its search answered with no option and a note). request.refused on search_flights; no mandate is asked for.
airlines_not_honoredSince 2026-09-26: the person allowed only some airlines and a quote the seller returned does not keep to them: it does not sign the same airlines list, or a flight of its itinerary is on another airline (the designator that opens the flight number). request.refused on search_flights; no mandate is asked for.

Authority side

Raised by the mandate authority (authority-api.md). Except request_invalid, the ten codes of "Who may ask" (signature_required to agent_not_linked, which refuse before a request exists: HTTP 401 or 403, no request, no entry), assistant_unknown ("Which assistant asked", the same: HTTP 403, no request, no entry), the four codes of "Who approves" (passkey_required, passkey_unknown, passkey_invalid, invite_expired, which decide nothing and write no entry), the three codes of "Standing rules" (rules_off, rule_invalid, rule_limit, which create no rule and write no entry), link_used, admin_denied, not_found, method_not_allowed and internal_error, each is the reason of a denied or expired request document and of a mandate.denied entry in the authority's ledger; the buyer copies it into facts.authority_reason and never turns it into a check of its own.

CodeHTTPWhat it means
request_invalidPOST /mandate-requests: malformed body (not JSON, over 65536 bytes, a field missing or not a string, a phone-shaped sub, act_sub not spiffe://, cnf_jkt not a thumbprint, correlation_id not a UUID). HTTP 400; no request, no entry.
signature_requiredPOST /mandate-requests without an envelope, under requester: require, or for a person with linked agents. HTTP 401; no request, no entry.
signature_invalidThe envelope is not a request+jwt under the header policy, carries no usable nonce, binds another method, path or body, or does not verify under the attested key its kid names. HTTP 401.
timestamp_out_of_windowThe envelope's iat is more than 60 seconds from the authority's clock. HTTP 401.
audience_mismatchThe envelope's aud is not this authority's issuer. HTTP 401.
signer_unknownThe envelope's iss is not a SPIFFE ID under a public DNS name, the buyer's documents could not be read, no valid attestation of that domain names the kid for that instance, or the domain is not on the authority's allow-list. HTTP 401.
attestation_invalidA key attestation that does not verify under the buyer's bundle (x5c chain or jwt-svid key), has expired, or vouches for another key than its sub names. Raised when reading one attestation; a request is refused with signer_unknown when no good one names the kid.
identity_revokedThe key that signed the envelope was withdrawn by its own domain (key-revocation+jwt). HTTP 403, after the signature held.
nonce_replayedThis envelope was already presented by this key in the last 120 seconds. HTTP 401.
requester_mismatchThe body's act_sub or cnf_jkt is not the instance and key that signed the envelope: an agent asks for a mandate bound to itself. HTTP 403.
agent_not_linkedThe person has linked agents and the one that signed the envelope is not among them. HTTP 403.
assistant_unknownPOST /mandate-requests names the assistant it came through (assistant_token, authority-api.md v0.8) and the token does not hold: not an access token this authority signed, for another person, for a resource that is not the asking buyer's, without the purchase scope, expired more than ten minutes ago, its grant revoked, or presented while oauth is off. HTTP 403; no request, no entry.
subject_unknownThe sub is not in the authority's registry.
seller_unknownThe seller's domain (quote iss) publishes no usable spiffe-svid.json and spiffe-bundle.json, or they do not vouch for the quote's kid.
quote_invalidNot a quote+jwt under the header policy, required fields missing, the signature does not verify under the seller's instance key, or the quote's correlation_id is not the request's.
quote_expiredThe quote's exp plus 60 s skew is past.
seller_not_allowedThe authority is configured with a seller allow-list and the quote's iss is not on it.
currency_not_allowedThe quote's currency is not the currency of the person's ceiling.
ceiling_exceededThe quote's total is above the person's standing ceiling.
allowance_exceededThe purchase would pass the day's allowance whoever runs this authority set for the person (authority-api.md v0.14, The day's allowance): what was approved for them since the start of the calendar day, plus this total, is above it. HTTP 200, status denied; also at the moment of issuing.
approval_undeliverableThe notifier could not deliver the approval link to the destination on record.
person_deniedThe person pressed Deny on the approval page.
approval_expiredThe approval link's validity (600 s by default) passed with no decision, and the request is expired; or a revoke came after the cart mandate's exp plus 60 s (HTTP 410 on the page).
passkey_requiredA form approve on the approval page where the approval takes the person's passkey (authority-api.md, Who approves, since v0.3). HTTP 403, answered as HTML; nothing decided, no entry.
passkey_unknownThe credential posted with a passkey approval is not one enrolled for the person the request is for (another person's and a never-seen one answer alike). HTTP 403; nothing decided, no entry.
passkey_invalidA WebAuthn check failed on a passkey approval or enrollment: client data (type, challenge, origin, framing), authenticator data (RP ID hash, user present, user verified, backup flags), signature, counter, or at enrollment the algorithm or the credential id; the sentence says which. HTTP 403; nothing decided or enrolled, no entry.
invite_expiredA passkey invitation past its expiry (15 minutes by default). HTTP 410; nothing enrolled.
rules_offA standing rule proposed or confirmed at an authority whose /health says rules: off (authority-api.md, Standing rules, since v0.4). HTTP 403; nothing proposed or confirmed, no entry.
rule_invalidA rule proposal outside what the person or the authority allows: the most per purchase above the person's ceiling or in another currency, a departure date in the past, a seller the authority does not issue for; or, for a rule the person makes on their own pages (since v0.11), a seller they never approved a purchase at, an agent they have not linked, a total outside the most per purchase and five times the ceiling, more than ten purchases or thirty days. HTTP 400; no rule, no entry. (The shape and the caps of a proposal, one purchase and 48 hours, are request_invalid.)
rule_limitThe person already has five rules proposed or active. HTTP 403; no rule, no entry.
signups_fullSigning in to enroll under signup: enroll (authority-api.md v0.10): every place of a person waiting for the operator is taken. HTTP 403 on the sign-in's callback page; nobody is made and no entry is written.
limit_exceededThe purchase would pass one of the person's own limits (authority-api.md v0.9, The person's own limits): the most per purchase, the budget or the number of purchases of the rolling period, the same trip again too soon, a blocked seller, a seller scored under the least the person accepts (facts.limit seller_trust, authority-api.md v0.12, What a seller is trusted with), or what the person allows the assistant it came through. The reason of a denied request document and of its mandate.denied, which also names which limit (facts.limit) and the digest of the limits in force (facts.limits_sha256); at the moment of issuing, HTTP 409 on the approval, by the form or with a passkey, and the request is denied with it.
limits_invalidThe person's own pages, setting limits, on the limits page or the sellers page: the document does not fit (an unknown member, an amount above the ceiling or in another currency, a period that is not 1, 7 or 30 days, a seller_trust_at_least off the scale of 1 to 100, an assistant that is not the person's), HTTP 400; or nothing was drafted, or the limits changed meanwhile, HTTP 409. Nothing changes and no entry is written.
person_pausedThe person stopped their agent at this authority (authority-api.md, Stopping): nothing is issued, proposed, confirmed or granted for them until they resume. HTTP 403 on POST /mandate-requests, POST /rules, an approval, a rule's confirmation and the consent page, with no entry; as the reason of a mandate.denied, a request that was waiting when the person stopped.
session_expiredA stop session ran out (ten minutes) or never signed in. HTTP 410; nothing stopped or resumed, no entry.
not_pausedResume for a person who is not stopped. HTTP 409; no entry.
provider_unknownPOST /login named no identity provider this authority accepts (authority-api.md, Signing in to enroll). HTTP 400; nothing started, no entry.
login_stateThe callback of a sign-in belongs to no attempt started in this browser, or to one already finished or older than ten minutes. HTTP 400; no invitation drawn, no entry.
login_failedA sign-in that did not hold: the identity provider could not be read, refused, or its id_token failed a check (the sentence says which). HTTP 502, or 400 when the provider says the person refused; no invitation drawn, no entry.
identity_unboundThe sign-in held and no person of this registry is bound to that identity. HTTP 403; no invitation drawn, no entry. The person reads that their request is in; binding the identity, or letting a new person in, is the operator's.
admin_deniedPOST /mandates/<jti>/revoke without the operator credential. HTTP 401; no entry.
not_foundUnknown jti or request_id, an unknown approval link (answered as HTML) or an unknown route. HTTP 404.
method_not_allowedA route called with a method it does not take. HTTP 405; no entry.
internal_errorAn unexpected fault, answered with the exception's class name and never a trace. HTTP 500; no entry.