{"protocol":"x402","x402Version":1,"version":"2.0","audience":"autonomous-agent","philosophy":"Vaultfire is a self-describing, custody-free, agent-native commerce surface. Every endpoint publishes its full input/output schema, contract ABI fragment, error catalog, and pricing. Agents pay with x402, sign locally, and broadcast their own transactions. Vaultfire holds nothing.","twoTierIntrospection":{"anchor":"two-tier-introspection","summary":"Free GET + priced POST share the same URL. GET returns inputSchema, contract metadata, reverts, integration steps, and a live proof. POST executes.","pattern":["GET /api/x402/actions/{action}            → 200 spec (inputSchema, outputSchema, contract, reverts, examples, liveProof)","POST /api/x402/actions/{action} (no auth) → 402 challenge with accepts[0], examples[0], errors[], errorCatalog, abi, agentHints","POST /api/x402/actions/{action} + X-PAYMENT → 200 with txData (caller signs + broadcasts)"],"whyItMatters":"inputSchema is intentionally omitted from the 402 body to keep the challenge compact. Agents that GET first never pay for an under-specified call."},"probeRate":{"safeRequestsPerSecond":4,"perIpLimits":{"get":"60 req/min (Upstash fixed window)","post":"20 req/min (Upstash fixed window)","platformBurst":"~10 req/s (Vercel DDoS protection, per-IP)"},"backoff":"exponential, base 1s, cap 30s; respect Retry-After header on 429","errorCodeFor429":"VF-PAY-005"},"capabilities":["x402-v1-exact-scheme","eip-3009-usdc-settlement","eip-712-typed-data","machine-readable-schemas-per-endpoint","machine-readable-error-catalog","machine-readable-abi-fragments","hosted-full-abis-with-integrity-hash","multi-chain (base, polygon, avalanche, arbitrum)","replay-protection-upstash-kv","rate-limit-distributed-upstash-kv","tx-prepare-no-custody","discovery-self-describing","related-endpoint-graph","examples-per-endpoint","free-preflight-balance-check","settlement-tx-hash-in-200-body","cors-allowlist-on-paid-lanes"],"loop":[{"step":0,"action":"preflight-balance","method":"GET","path":"/api/x402/agent-preflight?address={wallet}&chain=base","purpose":"FREE balance + readiness check. Returns USDC + ETH balance and per-price-tier `canAfford` so an agent can decide whether to attempt a paid lane before signing a payment. Avoids VF-PAY-007 round-trips. Use chain=all to probe every supported network at once.","cache":"10s public"},{"step":1,"action":"discover","method":"GET","path":"/api/x402/discovery","purpose":"Fetch the full inventory of 82+ endpoints with lane kind, price, network, and direct URL.","cache":"60s public + 600s stale-while-revalidate"},{"step":2,"action":"introspect","method":"GET","path":"/api/x402/actions/{action}","purpose":"Fetch the free, full per-endpoint spec — inputSchema, outputSchema, contract ABI fragment, related endpoints, reverts, examples, errors.","cache":"300s public"},{"step":3,"action":"optional-full-abi","method":"GET","path":"/api/x402/abis/{contract}","purpose":"Fetch the FULL hosted ABI for any Vaultfire contract referenced by an endpoint, with sha256 integrity hash for verification.","cache":"24h public"},{"step":4,"action":"probe-paid-lane","method":"POST","path":"/api/x402/actions/{action}","body":"inputSchema-conformant JSON","headers":"(no X-PAYMENT yet)","expect":"HTTP 402 with accepts[0] containing maxAmountRequired, payTo, asset, EIP-712 domain."},{"step":5,"action":"sign-payment","where":"agent local wallet","purpose":"Sign an EIP-3009 transferWithAuthorization for USDC matching accepts[0]. Generate a fresh random 32-byte nonce. Use validBefore = now + 300s.","privateKeyPolicy":"NEVER send private keys to Vaultfire. Sign locally; submit only the signature."},{"step":6,"action":"submit-paid","method":"POST","path":"/api/x402/actions/{action}","body":"same inputSchema-conformant JSON","headers":"X-PAYMENT: base64(JSON({x402Version, scheme, network, payload}))","expect":"HTTP 200 with `txData` containing unsigned EVM transaction the agent can sign + broadcast. The 200 body also carries `settlement: { transaction, network, payer, txHash, explorerUrl, note }` mirroring the canonical `X-PAYMENT-RESPONSE` header. CDP settles ~2-5s after the 200; the tx hash is final but the on-chain receipt may not be queryable for up to one block."},{"step":7,"action":"sign-tx","where":"agent local wallet","purpose":"Sign txData with the same caller wallet. Use chainId from networks[*].chainId."},{"step":8,"action":"broadcast","method":"POST","path":"/api/x402/submit-signed","purpose":"Optional free relay. Agents with their own RPC can broadcast directly.","alternative":"eth_sendRawTransaction against networks[*].rpc"},{"step":9,"action":"verify-onchain","method":"GET","path":"/api/x402/trust/agent-status?address={wallet}","purpose":"Read on-chain state to confirm the action landed. All Vaultfire reads return canonical contract state."},{"step":10,"action":"handle-errors","reference":"/api/x402/errors","purpose":"On any non-2xx response, branch on error.code (e.g. VF-PAY-005). Retry per the catalog's retryable + retryAfterSeconds fields."}],"responseShapes":{"paymentChallenge402":{"x402Version":1,"error":"string","accepts":[{"scheme":"\"exact\"","network":"\"base\" | \"polygon\" | \"avalanche\" | \"arbitrum\"","maxAmountRequired":"string (atomic units, 6-decimal USDC)","resource":"string (absolute URL)","description":"string","mimeType":"\"application/json\"","payTo":"string (0x address)","maxTimeoutSeconds":"number","asset":"string (0x USDC contract address)","outputSchema":{"input":{"type":"http","method":"POST","bodyType":"json","bodyFields":"Record<string, FieldSpec>"},"output":{"type":"object","properties":"Record<string, FieldSpec>"}},"extra":{"name":"\"USD Coin\"","version":"\"2\"","serviceName":"string","tags":"string[]","iconUrl":"string","serviceUrl":"string","serviceDescription":"string","category":"string"}}]},"actionSuccess":{"success":true,"txData":{"to":"string (0x address)","data":"string (0x hex calldata)","value":"string (wei, decimal)","chainId":"number","gasLimit":"string (optional)"},"chain":"string"},"errorResponse":{"success":false,"error":{"code":"string (VF-DOMAIN-NNN)","message":"string (human-readable)","category":"string","retryable":"boolean","retryAfterSeconds":"number (optional)"}}},"conventions":{"addressFormat":"0x-prefixed lowercase hex; 20 bytes; mixed-case checksums accepted","amountUnits":"atomic — USDC is 6-decimal, ETH/native is 18-decimal","chainNames":"base, polygon, avalanche, arbitrum","chainIds":{"base":8453,"polygon":137,"avalanche":43114,"arbitrum":42161},"nonceGeneration":"32 random bytes — crypto.getRandomValues or equivalent","timestampFormat":"unix seconds (uint256) for EIP-3009; ISO-8601 strings for logging","emDash":"real U+2014 character only — never the \\u2014 escape sequence"},"humanDocs":{"overview":"https://theloopbreaker.com/docs","quickstart":"https://theloopbreaker.com/quickstart","spec":"https://theloopbreaker.com/docs/spec","abis":"https://theloopbreaker.com/api/x402/abis","errors":"https://theloopbreaker.com/api/x402/errors","discovery":"https://theloopbreaker.com/api/x402/discovery","repository":"https://gitlawb.com/z6MkryiNsYdFEMHv95wxzSQ1vtFXPyVQQrxXdPw3tE5HpfxV/vaultfire"},"security":{"custody":"NONE. Vaultfire never holds funds or private keys.","signing":"tx-prepare model. All signatures happen in the caller wallet.","privateKeysAccepted":false,"nonceStorage":"Upstash KV (durable, distributed). Nonces fail closed on KV outage.","rateLimiting":"Upstash KV (distributed). Fails open on KV outage.","cors":"Paid lanes allowlist only. Public lanes wildcard.","securityHeaders":["X-Frame-Options: DENY","X-Content-Type-Options: nosniff","Referrer-Policy: strict-origin-when-cross-origin","Permissions-Policy: interest-cohort=()"]}}