VetoVetoDocs
Reference

Reason codes

The complete, stable rejection vocabulary. Every rejection (and several accepts) carries one or more of these SCREAMING_SNAKE_CASE codes — a stable API surface an agent keys off.

Reason codes are the lingua franca of every decision. An agent can't read prose docs at runtime, so every rejection (and several accepts) carries one or more of these SCREAMING_SNAKE_CASE codes. They are a stable API surface — never renamed or repurposed, only added.

import { REASON, humanReason, humanReasons } from '@veto-protocol/checkout';

humanReason('OVER_PER_TX_CAP'); // "The amount exceeds the per-transaction limit."

Happy path

CodeHuman
OKAcceptable.

Mandate — presence & shape

CodeHuman
MANDATE_REQUIREDA signed authorization mandate is required for this amount.
MANDATE_TYPE_UNSUPPORTEDThat mandate type is not supported yet.
MANDATE_MALFORMEDThe presented mandate could not be parsed.

Mandate — cryptographic & binding

CodeHuman
MANDATE_INVALID_SIGNATUREThe signature did not verify against a trusted issuer.
MANDATE_EXPIREDThe mandate has expired.
MANDATE_AMOUNT_INSUFFICIENTThe authorized amount is less than the cart total.
MANDATE_MERCHANT_MISMATCHThe mandate authorized a different merchant.
MANDATE_NOT_APPROVEDThe mandate decision was not an approval.
MANDATE_REPLAYThis authorization was already used.
MANDATE_UNBOUNDThe mandate is not bound to this merchant or cart.
MANDATE_CART_MISMATCHThe mandate authorized different cart contents.

Reputation

CodeHuman
REPUTATION_TOO_LOWThe agent reputation is below the required minimum.
AGENT_BLOCKEDThis agent is blocked by the merchant.

Dollar caps & velocity

CodeHuman
OVER_PER_TX_CAPThe amount exceeds the per-transaction limit.
OVER_DAILY_CAPThis would exceed the agent daily spend limit.
RATE_LIMITED_HOURLYToo many transactions from this agent this hour.
RATE_LIMITED_DAILYToo many transactions from this agent today.

Intent

CodeHuman
INTENT_FORBIDDEN_KEYWORDThe stated intent contains a forbidden term.
INTENT_MISMATCHThe stated intent does not match the cart contents.

Rails & settlement

CodeHuman
RAIL_NOT_ALLOWEDThe selected payment rail is not accepted here.
RAIL_NOT_IMPLEMENTEDThat payment rail is not implemented.
PAYMENT_INVALIDThe payment proof was invalid or could not be captured.
PAYMENT_EXPIREDThe payment quote expired before settlement.

x402 on-chain (real facilitator only)

CodeHuman
SIGNER_MISMATCHThe signature did not recover to the stated payer address.
UNSUPPORTED_CHAINThe chain/network is not supported by the facilitator.
INSUFFICIENT_FUNDSThe payer wallet did not have enough USDC.
NONCE_ALREADY_USEDThis payment authorization was already settled on-chain.
SETTLEMENT_FAILEDOn-chain settlement failed; verify the chain before retrying.

Review routing

CodeHuman
HOLD_FOR_REVIEWHeld for human review.
MANDATE_REQUIRED_HOLDHeld: this amount needs a mandate, which was not provided.

Session lifecycle

CodeHuman
SESSION_NOT_FOUNDNo checkout session with that id.
SESSION_ALREADY_SETTLEDThis checkout session was already settled.
SESSION_EXPIREDThe checkout session has expired; start a new one.
SESSION_INVALID_STATEThe session is not in a settleable state.
POLICY_ERRORThe acceptance policy could not be evaluated; held to be safe.

Request, cart & idempotency

CodeHuman
IDEMPOTENCY_KEY_REUSEDThis idempotency key was already used with a different request.
BAD_REQUESTThe request was malformed.
BAD_JSONThe request body was not valid JSON.
PAYLOAD_TOO_LARGEThe request body was too large.
AGENT_ID_REQUIREDAn agent id is required.
ITEMS_REQUIREDAt least one line item is required.
SKU_UNKNOWNOne of the requested SKUs is not in the catalog.
SKU_UNAVAILABLEOne of the requested SKUs is not available.
QTY_INVALIDA requested quantity was not a positive whole number.
CART_EMPTYThe resulting cart was empty.
CURRENCY_MISMATCHThe line items are priced in more than one currency.
PRICE_MALFORMEDA catalog price was not a valid amount.
CART_BUILD_FAILEDThe cart could not be assembled (catch-all).
QUOTE_FAILEDA payment quote could not be produced for this rail.

Internal / fail-safe

These fire when something unexpected throws. The gate fails safe — it never silently accepts — so a verification or policy error becomes a hold/reject, not an allow.

CodeHuman
MANDATE_VERIFY_ERRORThe mandate could not be verified due to an internal error.
RECEIPT_ISSUE_FAILEDSettlement succeeded but the receipt could not be issued.
NETWORK_ERRORA network error occurred while contacting the merchant.
TOOL_ERRORAn MCP tool wrapper threw while invoking the merchant.

Receipts

CodeHuman
RECEIPT_MALFORMEDThe receipt could not be parsed.
RECEIPT_INVALID_SIGNATUREThe receipt signature did not verify.
RECEIPT_WRONG_TYPEThe receipt was not the expected type.
RECEIPT_WRONG_ISSUERThe receipt was issued by an unexpected party.
RECEIPT_KEY_UNRESOLVEDThe receipt signing key could not be resolved.

Every code here is exported from @veto-protocol/checkout as REASON.<CODE>, with a human gloss via humanReason(code). Unknown codes fall back to the raw code string, so a rail-specific code still renders something rather than undefined. Codes are append-only — never renamed or repurposed — so you can safely key logic off the string.