Veto/docs
Meow Gateway

Error code catalog

Every code the gateway can emit, what it means, and what to do next.

Every non-2xx carries the Stripe-tier envelope:

{
  "error": {
    "type": "invalid_request",
    "code": "capsule_payload_invalid",
    "message": "amount.amount: Invalid",
    "param": "amount.amount",
    "doc_url": "https://docs.veto.so/docs/meow/errors/capsule_payload_invalid",
    "hint": "Must match ^\\d+(\\.\\d{1,2})?$ for USD.",
    "request_id": "req_01hy2z..."
  }
}

Capsule lifecycle

codeHTTPWhat it meansFix
capsule_expired403now ≥ expires_at on the signed payload (+ skew tolerance)Re-mint; raise ttl_seconds if legit
capsule_signature_invalid403JWS signature does not verify against current or prev JWKSCheck the kid in the JWS header matches an active key; run GET /.well-known/veto-keys.json
capsule_kid_unknown403Header kid not present in JWKSRotate consumer's cached JWKS; confirm the signer's kid is in the overlap window
capsule_replayed409nonce already claimed for this entityMint a fresh capsule; each is single-use
capsule_consumed409Atomic CAS found the capsule already in consumed statusMint fresh
capsule_payload_invalid400Zod validation failed on the request bodyInspect error.param + error.message

Drift

codeHTTPWhat it means
beneficiary_hash_mismatch403Runtime beneficiary hash ≠ signed hash. Invoice-swap attack or operator edited the payee between mint and consume
beneficiary_held403Operator marked this counterparty held (compromised)
beneficiary_quarantine_active403First-time payee; HITL approval required before any consume
amount_exceeds_capsule_ceiling403Runtime amount > amount_ceiling.amount
amount_exceeds_entity_cap403Policy pack's budgets.entity_{24h,7d,30d}_usd would be breached
rail_not_in_allowlist403Runtime rail not in the signed rail_allowlist
invalid_amount_precision400Currency-aware precision check (USD=2dp, USDC=6dp)

Policy

codeHTTPWhat it means
policy_eval_error500Internal; compiled pack raised during eval — file a bug
policy_pack_not_found404Requested pack_id (or version) does not exist in storage
policy_pack_hash_mismatch409Pack's sha256 changed under a live capsule; the chain flags this at consume

HITL

codeHTTPEnvelope addsWhat it means
approval_required409approval_id, payload_hashPolicy requires a human. Poll /v1/approvals/:id; re-mint with approval_ref once state=approved
approval_denied403Operator denied. Terminal; do not retry
approval_expired409Approval TTL elapsed. Raise fresh via re-mint
approval_already_resolved409Idempotent replay of a resolve call — already approved or already denied
approval_already_consumed409Single-use approval was already claimed by a prior mint
approval_payload_mismatch409payload_hashApproval was raised for different drift inputs than this mint
dual_control_required409approval_idAmount ≥ dual_control_threshold_usd; TWO distinct approvers must resolve

Upstream Meow

codeHTTPWhat it means
meow_upstream_error502Meow returned non-2xx. Inspect error.message for the raw code
meow_timeout504Request to Meow exceeded timeout
meow_rate_limited429Meow's rate limit. Back off per Retry-After

Invoice

codeHTTPWhat it means
invoice_already_consumed409A capsule already bound this invoice_hash; can't consume twice (prevents double-pay)
invoice_hash_missing400Pack requires an invoice reference; none supplied
invoice_parse_failed502The parser errored; the row is in parse_failed state

Workflow

codeHTTPWhat it means
workflow_invalid_transition409Requested state change violates the edge map. error.hint lists legal next states
workflow_not_found404The referenced workflow_id does not exist
workflow_already_exists409Create attempted with a non-unique (org, entity, workflow_id)

Idempotency

codeHTTPWhat it means
idempotency_key_reused_with_different_payload400Same Idempotency-Key seen, different canonical body. Prevents silent payment-substitution on retry

Infrastructure

codeHTTPWhat it means
not_implemented501Spec'd endpoint not yet shipped in this block
route_not_found404Path doesn't match any registered route
signing_key_missing503No Ed25519 key configured. Run veto-meow-gateway keygen
invalid_json400Body was not valid JSON
payload_too_large413Body > 512KB (or 1MB for invoice ingest)
internal_server_error500Unhandled exception; check logs with error.request_id