{"openapi":"3.1.0","info":{"title":"x402 Payment Facilitator API","description":"\nUltravioleta DAO x402 Payment Facilitator - Gasless micropayments for the agentic economy.\n\n## Overview\n\nThe x402 facilitator enables gasless micropayments across multiple blockchain networks using the HTTP 402 Payment Required protocol. It acts as a settlement intermediary, verifying EIP-3009/EIP-712 payment authorizations and submitting them on-chain.\n\n## Supported Networks\n\n### EVM Chains (Mainnet)\nEthereum, Base, Polygon, Optimism, Avalanche, Arbitrum, Celo, HyperEVM, Unichain, Monad, Scroll, Robinhood Chain (settles Paxos USDG - no native USDC), BSC, SKALE Base\n\n### EVM Chains (Testnet)\nEthereum Sepolia, Base Sepolia, Polygon Amoy, Optimism Sepolia, Avalanche Fuji, Arbitrum Sepolia, Celo Sepolia, HyperEVM Testnet, Unichain Sepolia, SKALE Base Sepolia, Monad Testnet, Robinhood Chain Testnet\n\n### SVM Chains (Solana Virtual Machine)\n- **Solana**: Mainnet (`solana`) and Devnet (`solana-devnet`)\n- **Fogo**: Mainnet (`fogo`) and Testnet (`fogo-testnet`)\n- **XRPL (XRP Ledger)**: Mainnet (`xrpl`) and Testnet (`xrpl-testnet`) — native XRP, pre-signed Payment transaction blobs; not the EVM `xrpl-evm` sidechain\n\n### Other Non-EVM Chains\n- **NEAR Protocol**: Mainnet (`near`) and Testnet (`near-testnet`)\n- **Stellar/Soroban**: Mainnet (`stellar`) and Testnet (`stellar-testnet`)\n- **Algorand**: Mainnet (`algorand`) and Testnet (`algorand-testnet`)\n- **Sui**: Mainnet (`sui`) and Testnet (`sui-testnet`)\n\n## Core Endpoints\n\n- `POST /verify` - Verify payment authorization structure and signatures\n- `POST /settle` - Submit verified payment to blockchain for settlement\n- `GET /supported` - List all supported networks and payment schemes\n\n## ERC-8004 Reputation (Trustless Agents)\n\nThe facilitator supports [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004) for AI agent identity and reputation across **18 networks** (10 mainnets + 8 testnets), spanning both EVM and Solana.\n\n**EVM networks:** `ethereum`, `base`, `polygon`, `arbitrum`, `optimism`, `celo`, `bsc`, `monad`, `avalanche`, `ethereum-sepolia`, `base-sepolia`, `polygon-amoy`, `arbitrum-sepolia`, `optimism-sepolia`, `celo-sepolia`, `avalanche-fuji`\n\n**Solana networks:** `solana`, `solana-devnet` (via [QuantuLabs 8004-solana](https://github.com/QuantuLabs/8004-solana) + [ATOM Engine](https://github.com/QuantuLabs/8004-atom))\n\n**Note:** For EVM networks, `agentId` is a numeric uint256 (e.g., `42`). For Solana, `agentId` is a base58 Pubkey (e.g., `7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv`). Solana reputation responses include bonus `atomStats` with trust tiers, quality scores, and anti-Sybil metrics.\n\n### Endpoints:\n- `POST /register` - Register a new agent on-chain (gasless; sync or async via `Prefer: respond-async`)\n- `GET /register/status/{job_id}` - Poll an async registration until `agentId` is ready\n- `POST /feedback` - Submit on-chain reputation feedback (EVM only)\n- `POST /feedback/revoke` - Revoke previously submitted feedback (EVM only)\n- `POST /feedback/response` - Append agent response to feedback (EVM only)\n- `GET /reputation/:network/:agentId` - Query agent reputation summary (EVM + Solana)\n- `GET /identity/:network/:agentId` - Get agent identity from registry (EVM + Solana)\n- `GET /identity/:network/:agentId/metadata/:key` - Read specific agent metadata (EVM + Solana)\n- `GET /identity/:network/total-supply` - Get total registered agents on a network (EVM + Solana)\n\n## Bazaar Discovery\n\nCurated resource discovery for x402-enabled services. Entries carry a discovery `source`,\na liveness `health` status from periodic probing, and a curated `tier`\n(`first_party` > `vip` > `verified` > `listed`) which also drives listing order.\n\n- `GET /discovery/resources` - List curated resources (filters: category, provider, tag, network, source, sourceFacilitator, q, health, tier; any other parameter is a 400)\n- `GET /discovery/stats` - Aggregate catalog metrics (60s cache)\n- `GET /bazaar` - HTML Bazaar explorer UI\n- `GET /discovery/attestation/{hash}` - ERC-8004 attestation evidence body\n- `POST /discovery/register` - Register a new resource (rate limited)\n\n**Admin** (require `Authorization: Bearer <BAZAAR_ADMIN_TOKEN>`; return 404 when no admin token is configured):\n\n- `DELETE /discovery/resources?url=...` - Permanently unregister a resource\n- `POST /discovery/admin/suppress` - Hide a resource from listings without deleting it\n- `POST /discovery/admin/release` - Un-suppress a resource\n\n## Protocol Documentation\n\n- [x402 Protocol](https://x402.org)\n- [EIP-3009 (transferWithAuthorization)](https://eips.ethereum.org/EIPS/eip-3009)\n- [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004)\n- [Ultravioleta DAO](https://ultravioletadao.xyz)\n","contact":{"name":"Ultravioleta DAO","url":"https://ultravioletadao.xyz"},"license":{"name":"Apache-2.0","url":"https://www.apache.org/licenses/LICENSE-2.0"},"version":"1.73.0"},"servers":[{"url":"https://facilitator.ultravioletadao.xyz","description":"Production"},{"url":"http://localhost:8080","description":"Local Development"}],"paths":{"/accepts":{"post":{"tags":["Core"],"summary":"Negotiate payment requirements (Faremeter middleware)","description":"\nNegotiation endpoint used by `@faremeter/middleware` and compatible x402 clients.\n\nReceives merchant payment requirements, matches them against the facilitator's\nsupported capabilities, and returns enriched requirements with facilitator-specific\ndata (feePayer, tokens, escrow contracts, etc.).\n\n**How it works:**\n1. Middleware sends the merchant's desired payment requirements\n2. Facilitator filters to only those it can handle (matching scheme + network)\n3. Facilitator enriches each match with `extra` data (feePayer, tokens, features)\n4. Middleware uses the enriched requirements in the 402 response to clients\n\n**Supports both v1 and v2 network formats** (auto-detected):\n- v1: `\"network\": \"base\"` (string enum)\n- v2: `\"network\": \"eip155:8453\"` (CAIP-2 format)\n\n**Request body:**\n```json\n{\n  \"x402Version\": 1,\n  \"accepts\": [\n    {\n      \"scheme\": \"exact\",\n      \"network\": \"solana\",\n      \"maxAmountRequired\": \"10000\",\n      \"asset\": \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n      \"payTo\": \"SomePublicKey...\",\n      \"description\": \"Access to premium API\",\n      \"maxTimeoutSeconds\": 90,\n      \"resource\": \"https://api.example.com/data\"\n    }\n  ],\n  \"error\": \"\"\n}\n```\n\n**Response (enriched):**\n```json\n{\n  \"x402Version\": 1,\n  \"accepts\": [\n    {\n      \"scheme\": \"exact\",\n      \"network\": \"solana\",\n      \"maxAmountRequired\": \"10000\",\n      \"asset\": \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n      \"payTo\": \"SomePublicKey...\",\n      \"description\": \"Access to premium API\",\n      \"maxTimeoutSeconds\": 90,\n      \"resource\": \"https://api.example.com/data\",\n      \"extra\": {\n        \"feePayer\": \"F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq\",\n        \"tokens\": [\n          { \"token\": \"usdc\", \"address\": \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\", \"decimals\": 6 }\n        ]\n      }\n    }\n  ],\n  \"error\": \"\"\n}\n```\n\n**Note:** Requirements for unsupported scheme+network combinations are silently dropped from the response.\n","operationId":"path_accepts_post","requestBody":{"description":"Merchant payment requirements to negotiate","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Enriched payment requirements","content":{"application/json":{"schema":{"type":"object"},"example":{"x402Version":1,"accepts":[{"scheme":"exact","network":"base","maxAmountRequired":"1000000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","payTo":"0x...","extra":{"tokens":[{"token":"usdc","address":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","decimals":6}]}}],"error":""}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object"},"example":{"x402Version":1,"accepts":[],"error":"Missing or invalid 'accepts' array"}}}}}}},"/api/stats":{"get":{"tags":["Discovery"],"summary":"Pre-aggregated totals per network and asset","description":"Totals maintained on write, so the cost of this call does not grow with history — it never scans.\n\nTwo caveats travel in the response body because they change how the numbers should be read. **Operations that ERROR are not recorded at all**, so a 100% success rate means 'no failures were recorded', not 'no failures occurred'. And **counting began when the store was enabled**, so anything settled before that is unknown rather than zero.\n\n`volumeAtomic` is a STRING: these are u256-shaped values and a JSON number silently loses precision above 2^53.","operationId":"path_api_stats","responses":{"200":{"description":"Aggregated totals","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Store unavailable or not configured"}}}},"/bazaar":{"get":{"tags":["Bazaar"],"summary":"Bazaar explorer UI","description":"\nServes the HTML Bazaar explorer: a browsable view of the curated catalog backed by\n`GET /discovery/resources` and `GET /discovery/stats`.\n\nReturns `text/html`, not JSON. Use the discovery endpoints for programmatic access.\n","operationId":"path_bazaar_ui","responses":{"200":{"description":"Bazaar explorer HTML page","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/blacklist":{"get":{"tags":["Compliance"],"summary":"Get OFAC sanctioned addresses","description":"\nReturns the list of OFAC sanctioned blockchain addresses. Payments involving these addresses are blocked.\n\n**Response:**\n```json\n{\n  \"addresses\": [\"0x...\", \"0x...\"],\n  \"lastUpdated\": \"2026-01-15T00:00:00Z\",\n  \"source\": \"OFAC SDN List\"\n}\n```\n","operationId":"path_blacklist","responses":{"200":{"description":"Sanctioned addresses list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/discovery/admin/release":{"post":{"tags":["Bazaar"],"summary":"Release a suppressed resource (admin)","description":"\n**Admin only.** Reverses `POST /discovery/admin/suppress`, making the resource visible in\nlistings again.\n\nRequires an `Authorization: Bearer <BAZAAR_ADMIN_TOKEN>` header. When the server has no admin\ntoken configured the whole admin surface is absent and this route returns **404**.\n\nRate limited to roughly 5 requests per minute per IP.\n\n**Request body:**\n```json\n{ \"url\": \"https://api.example.com/paid\" }\n```\n\n**Response:**\n```json\n{ \"success\": true, \"url\": \"https://api.example.com/paid\", \"suppressed\": false }\n```\n","operationId":"path_bazaar_admin_release","parameters":[{"name":"Authorization","in":"header","description":"Bearer <BAZAAR_ADMIN_TOKEN>","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Release request: url of the suppressed resource","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Resource released","content":{"application/json":{"schema":{"type":"object"},"example":{"success":true,"url":"https://api.example.com/paid","suppressed":false}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Admin surface disabled (no admin token configured)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/discovery/admin/suppress":{"post":{"tags":["Bazaar"],"summary":"Suppress a resource (admin)","description":"\n**Admin only.** Hides a resource from every listing without deleting it, so the entry can be\nreleased later.\n\nRequires an `Authorization: Bearer <BAZAAR_ADMIN_TOKEN>` header. When the server has no admin\ntoken configured the whole admin surface is absent and this route returns **404**.\n\nRate limited to roughly 5 requests per minute per IP.\n\n**Request body:**\n```json\n{ \"url\": \"https://api.example.com/paid\", \"reason\": \"spam\" }\n```\n\n**Response:**\n```json\n{ \"success\": true, \"url\": \"https://api.example.com/paid\", \"suppressed\": true }\n```\n","operationId":"path_bazaar_admin_suppress","parameters":[{"name":"Authorization","in":"header","description":"Bearer <BAZAAR_ADMIN_TOKEN>","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Suppression request: url plus a reason string","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Resource suppressed","content":{"application/json":{"schema":{"type":"object"},"example":{"success":true,"url":"https://api.example.com/paid","suppressed":true}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Admin surface disabled (no admin token configured)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/discovery/attestation/{hash}":{"get":{"tags":["Bazaar"],"summary":"Get attestation evidence","description":"\nServes the hosted ERC-8004 attestation evidence body referenced by an on-chain curation\nattestation. The path key is a lowercase sha256 hex digest of the attested resource URL:\nexactly 64 characters matching `[0-9a-f]{64}`. Any other shape is rejected with 400 so a URL\npath segment can never be mapped to arbitrary content.\n\n**Response (application/json):**\n```json\n{\n  \"type\": \"uptime\",\n  \"endpoint\": \"https://mcp.execution.market/mcp\",\n  \"network\": \"base\",\n  \"agentId\": 2106,\n  \"uptime\": 99.77,\n  \"window\": { \"probes\": 100, \"ok\": 99 },\n  \"prober\": \"uvd-bazaar-health/1.0\"\n}\n```\n","operationId":"path_bazaar_attestation","parameters":[{"name":"hash","in":"path","description":"Lowercase sha256 hex digest of the resource URL (64 chars, [0-9a-f]{64})","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attestation evidence body","content":{"application/json":{"schema":{"type":"object"},"example":{"type":"uptime","endpoint":"https://mcp.execution.market/mcp","network":"base","agentId":2106,"uptime":99.77,"window":{"probes":100,"ok":99},"prober":"uvd-bazaar-health/1.0"}}}},"400":{"description":"Invalid evidence key format (not a 64-char lowercase hex digest)","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"No evidence stored for that key","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/discovery/register":{"post":{"tags":["Bazaar"],"summary":"Register a resource","description":"\nRegisters a paid resource in the Bazaar catalog so clients can discover it via\n`GET /discovery/resources`.\n\n**Rate limited** to roughly 5 requests per minute per IP: registration triggers DNS lookups and\noutbound fetches against caller-supplied URLs.\n\n**Request body:**\n```json\n{\n  \"url\": \"https://api.example.com/paid\",\n  \"type\": \"http\",\n  \"description\": \"Premium market data API\",\n  \"accepts\": [\n    {\n      \"scheme\": \"exact\",\n      \"network\": \"eip155:8453\",\n      \"asset\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n      \"amount\": \"10000\",\n      \"payTo\": \"0x...\",\n      \"maxTimeoutSeconds\": 300\n    }\n  ],\n  \"metadata\": {\n    \"provider\": \"Example\",\n    \"category\": \"data\",\n    \"tags\": [\"api\"]\n  }\n}\n```\n\n**Fields:**\n- `type` (required): one of `http`, `mcp`, `a2a`, `facilitator`.\n- `accepts` (required, except for `facilitator` entries): payment options in x402 v2 shape with\n  CAIP-2 `network` values.\n- `metadata` (optional): `provider`, `category`, `tags`.\n\n**Validation (400):** unsupported `scheme`, userinfo embedded in the URL\n(`https://user:pass@host`), a host resolving to a private / loopback / link-local / cloud metadata\nIP, or an empty `accepts` array on a non-`facilitator` type.\n","operationId":"path_bazaar_register","requestBody":{"description":"Resource registration request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"201":{"description":"Resource registered","content":{"application/json":{"schema":{"type":"object"},"example":{"success":true,"message":"Resource registered successfully","url":"https://api.example.com/paid"}}}},"400":{"description":"Validation failure (bad scheme, URL userinfo, private/metadata IP host, empty accepts)","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Resource already registered","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Rate limited (roughly 5 requests per minute per IP)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/discovery/resources":{"get":{"tags":["Bazaar"],"summary":"List curated bazaar resources","description":"\nLists x402-enabled resources known to the curated Bazaar catalog.\n\n**Ordering:** results are sorted by curated tier first (`first_party` > `vip` > `verified` > `listed`),\nthen by liveness (`alive` resources first), then by `lastUpdated` descending.\n\n**Health visibility:** when `health` is omitted, quarantined resources are hidden.\nPass `health=any` to return everything, or a specific status to filter to it.\n\n**Response:**\n```json\n{\n  \"x402Version\": 2,\n  \"items\": [\n    {\n      \"url\": \"https://api.meshrelay.xyz/payments/access/alpha-test\",\n      \"type\": \"http\",\n      \"x402Version\": 2,\n      \"description\": \"MeshRelay premium IRC channel access\",\n      \"accepts\": [\n        {\n          \"scheme\": \"exact\",\n          \"network\": \"eip155:8453\",\n          \"asset\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n          \"amount\": \"100000\",\n          \"payTo\": \"0xe4dc963c56979E0260fc146b87eE24F18220e545\",\n          \"maxTimeoutSeconds\": 300\n        }\n      ],\n      \"lastUpdated\": 1784818083,\n      \"metadata\": {\n        \"provider\": \"MeshRelay\",\n        \"category\": \"communication\",\n        \"tags\": [\"irc\"]\n      },\n      \"source\": \"self_registered\",\n      \"sourceFacilitator\": null,\n      \"firstSeen\": 1784818112,\n      \"health\": {\n        \"status\": \"alive\",\n        \"lastChecked\": 1784900000,\n        \"httpStatus\": 402,\n        \"latencyMs\": 240\n      },\n      \"curation\": {\n        \"tier\": \"first_party\",\n        \"label\": \"MeshRelay\",\n        \"firstParty\": true,\n        \"verification\": {\n          \"protocol\": \"erc8004\",\n          \"network\": \"base\",\n          \"agentId\": 2106,\n          \"feedbackCount\": 0,\n          \"uptime\": 99.77\n        }\n      }\n    }\n  ],\n  \"pagination\": { \"limit\": 10, \"offset\": 0, \"total\": 21195 }\n}\n```\n\n**Optional fields:** `metadata`, `sourceFacilitator`, `firstSeen`, `health` and `curation` are\nomitted when unknown. Only `url`, `type`, `x402Version`, `accepts`, `lastUpdated` and `source`\nare always present.\n\n**Timestamps** (`firstSeen`, `lastUpdated`, `health.lastChecked`) are Unix epoch **seconds**,\nserialized as JSON numbers -- not ISO-8601 strings and not milliseconds.\n\n**Unknown parameters are rejected with a 400**, listing the ones supported. A parameter the\nserver accepted and ignored would be indistinguishable from a filter that matched everything,\nso `?search=logs` fails loudly and points at `q` instead of quietly returning the whole catalog.\n","operationId":"path_bazaar_list","parameters":[{"name":"limit","in":"query","description":"Maximum number of resources to return (default: 10, max: 100)","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"offset","in":"query","description":"Number of resources to skip (default: 0)","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"category","in":"query","description":"Filter by metadata category (e.g., finance, communication)","required":false,"schema":{"type":"string"}},{"name":"provider","in":"query","description":"Filter by metadata provider name","required":false,"schema":{"type":"string"}},{"name":"tag","in":"query","description":"Filter by metadata tag","required":false,"schema":{"type":"string"}},{"name":"network","in":"query","description":"Exact CAIP-2 network match (e.g., eip155:8453, solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp)","required":false,"schema":{"type":"string"}},{"name":"source","in":"query","description":"Discovery source: self_registered | settlement | crawled | aggregated","required":false,"schema":{"type":"string"}},{"name":"sourceFacilitator","in":"query","description":"Facilitator the entry was aggregated from (e.g., coinbase, payai, thirdweb)","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Free-text search over url, description, provider and tags. Max 128 characters (longer returns 400)","required":false,"schema":{"type":"string"}},{"name":"health","in":"query","description":"Liveness filter: alive | degraded | auth_gated | quarantined | unknown | unprobeable | any. When omitted, quarantined resources are hidden; 'any' returns everything","required":false,"schema":{"type":"string"}},{"name":"tier","in":"query","description":"Curated tier filter: first_party | vip | verified | listed","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Curated resource listing","content":{"application/json":{"schema":{"type":"object"},"example":{"x402Version":2,"items":[{"url":"https://api.meshrelay.xyz/payments/access/alpha-test","type":"http","x402Version":2,"description":"MeshRelay premium IRC channel access","accepts":[{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"100000","payTo":"0xe4dc963c56979E0260fc146b87eE24F18220e545","maxTimeoutSeconds":300}],"lastUpdated":1784818083,"metadata":{"provider":"MeshRelay","category":"communication","tags":["irc"]},"source":"self_registered","sourceFacilitator":null,"firstSeen":1784818112,"health":{"status":"alive","lastChecked":1784900000,"httpStatus":402,"latencyMs":240},"curation":{"tier":"first_party","label":"MeshRelay","firstParty":true,"verification":{"protocol":"erc8004","network":"base","agentId":2106,"feedbackCount":0,"uptime":99.77}}}],"pagination":{"limit":10,"offset":0,"total":21195}}}}},"400":{"description":"Invalid query: an unsupported parameter, or `q` longer than 128 characters","content":{"application/json":{"schema":{"type":"object"},"example":{"error":"unknown query parameter: search","hint":"did you mean q?","supported":["limit","offset","category","network","provider","tag","source","sourceFacilitator","health","tier","q"]}}}}}},"delete":{"tags":["Bazaar"],"summary":"Unregister a resource (admin)","description":"\n**Admin only.** Permanently removes a resource from the Bazaar catalog.\n\nRequires an `Authorization: Bearer <BAZAAR_ADMIN_TOKEN>` header. When the server has no admin\ntoken configured the whole admin surface is absent and this route returns **404**.\n\nRate limited to roughly 5 requests per minute per IP.\n\n**Response:**\n```json\n{ \"success\": true, \"url\": \"https://api.example.com/paid\", \"removed\": true }\n```\n","operationId":"path_bazaar_admin_delete","parameters":[{"name":"url","in":"query","description":"Exact resource URL to unregister","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Bearer <BAZAAR_ADMIN_TOKEN>","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Resource removed","content":{"application/json":{"schema":{"type":"object"},"example":{"success":true,"url":"https://api.example.com/paid","removed":true}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Unknown URL, or admin surface disabled (no admin token configured)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/discovery/stats":{"get":{"tags":["Bazaar"],"summary":"Bazaar catalog statistics","description":"\nAggregate metrics for the curated Bazaar catalog. Served from a 60-second in-process cache,\nso counters can lag recent registrations or health probes by up to a minute.\n\n- `total` counts every resource in the catalog.\n- `visible` counts the resources returned by the default `GET /discovery/resources` listing\n  (quarantined resources excluded).\n\n**Response:**\n```json\n{\n  \"total\": 21195,\n  \"visible\": 19263,\n  \"bySource\": { \"aggregated\": 21067, \"self_registered\": 128 },\n  \"bySourceFacilitator\": { \"payai\": 19800, \"thirdweb\": 622, \"coinbase\": 336 },\n  \"byNetwork\": { \"eip155:8453\": 20991, \"eip155:1\": 56 },\n  \"byTier\": { \"first_party\": 10, \"vip\": 127, \"verified\": 1814, \"listed\": 19244 },\n  \"byHealth\": { \"alive\": 1814, \"quarantined\": 1932, \"auth_gated\": 263, \"unknown\": 17029 },\n  \"generatedAt\": 1784900000\n}\n```\n","operationId":"path_bazaar_stats","responses":{"200":{"description":"Catalog metrics","content":{"application/json":{"schema":{"type":"object"},"example":{"total":21195,"visible":19263,"bySource":{"aggregated":21067,"self_registered":128},"bySourceFacilitator":{"payai":19800,"thirdweb":622,"coinbase":336},"byNetwork":{"eip155:8453":20991,"eip155:1":56},"byTier":{"first_party":10,"vip":127,"verified":1814,"listed":19244},"byHealth":{"alive":1814,"quarantined":1932,"auth_gated":263,"unknown":17029},"generatedAt":1784900000}}}}}}},"/escrow/state":{"post":{"tags":["Escrow"],"summary":"Query escrow payment state","description":"\nQueries the on-chain state of an escrow payment from the AuthCaptureEscrow contract.\nThis is a read-only view call (no gas consumed).\n\nReturns the capturable amount, refundable amount, and whether payment has been fully collected.\n\n**Request body:**\n```json\n{\n  \"paymentInfo\": {\n    \"operator\": \"0x...\",\n    \"receiver\": \"0x...\",\n    \"token\": \"0x...\",\n    \"maxAmount\": \"1000000\",\n    \"preApprovalExpiry\": 281474976710655,\n    \"authorizationExpiry\": 281474976710655,\n    \"refundExpiry\": 281474976710655,\n    \"minFeeBps\": 0,\n    \"maxFeeBps\": 100,\n    \"feeReceiver\": \"0x...\",\n    \"salt\": \"0x...\"\n  },\n  \"payer\": \"0x...\",\n  \"network\": \"eip155:8453\",\n  \"extra\": {\n    \"escrowAddress\": \"0x...\",\n    \"operatorAddress\": \"0x...\",\n    \"tokenCollector\": \"0x...\"\n  }\n}\n```\n\n**Response:**\n```json\n{\n  \"hasCollectedPayment\": false,\n  \"capturableAmount\": \"1000000\",\n  \"refundableAmount\": \"0\",\n  \"paymentInfoHash\": \"0x...\",\n  \"network\": \"eip155:8453\"\n}\n```\n","operationId":"path_escrow_state","requestBody":{"description":"Escrow state query","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Escrow state","content":{"application/json":{"schema":{"type":"object"},"example":{"hasCollectedPayment":false,"capturableAmount":"1000000","refundableAmount":"0","paymentInfoHash":"0xabcdef...","network":"eip155:8453"}}}},"400":{"description":"Query failed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/events":{"get":{"tags":["Discovery"],"summary":"Live traffic stream (Server-Sent Events)","description":"Streams one Server-Sent Event per facilitator operation, so observers can render live traffic without scraping logs. The SSE `event:` name is the operation (`verify` or `settle`) and `data:` is the JSON payload below; a `:keepalive` comment every 15s holds the connection open through the load balancer.\n\n`network` is the facilitator's canonical slug, the same one `/supported` uses. A `settle` carries the transaction hash; a `verify` has none, because nothing has settled yet.\n\nThe stream is lossy on purpose: it can never slow down or fail a payment, so a subscriber that falls behind loses events and stays connected. It is also bounded — the endpoint returns **503** with `Retry-After` once the concurrent-subscriber cap is reached, and **404** when the operator has disabled it with `X402_EVENTS_ENABLED=false`.\n\nOperators can narrow what is published without a code change: `X402_EVENTS_DETAIL=minimal` drops `payer`/`tx`/`amount`/`asset`, and `X402_EVENTS_SCOPE=allowlist` restricts the stream to payers in `X402_EVENTS_ALLOWLIST`.\n\nBy default operations that ERROR are not published, so `ok:false` only ever means \"resolved and came back negative\". Set `X402_EVENTS_PUBLISH_FAILURES=true` to emit them; they carry an `error` field holding a bounded CATEGORY (`contract_revert`, `invalid_signature`, `insufficient_funds`, …) and never the error text.","operationId":"path_events","responses":{"200":{"description":"SSE stream of traffic events (`text/event-stream`)","content":{"application/json":{"schema":{"type":"object"},"example":{"ts":1769000000000,"kind":"settle","network":"base","ok":true,"payer":"0x...","tx":"0x...","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","resource":"https://api.example.com/premium-data","payTo":"0x...","description":"Premium data feed","scheme":"exact"}}}},"404":{"description":"Stream disabled by the operator (X402_EVENTS_ENABLED=false)"},"503":{"description":"Concurrent-subscriber cap reached; retry after the `Retry-After` delay"}}}},"/feedback":{"get":{"tags":["ERC-8004"],"summary":"Get feedback submission schema","description":"Returns the JSON schema for ERC-8004 feedback submission requests, including all supported networks and related endpoints.","operationId":"path_feedback_get","responses":{"200":{"description":"Feedback schema with supported networks","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["ERC-8004"],"summary":"Submit reputation feedback","description":"\nSubmits on-chain reputation feedback for an AI agent via the ERC-8004 Reputation Registry (EVM) or Agent Registry with ATOM Engine CPI (Solana).\n\n**Supported networks:** 18 networks (EVM + Solana).\n\n**agentId format:** Numeric (42) for EVM, base58 Pubkey string for Solana. Both JSON numbers and strings are accepted.\n\n**EVM request:**\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"base\",\n  \"feedback\": {\n    \"agentId\": 42,\n    \"value\": 87,\n    \"valueDecimals\": 0,\n    \"tag1\": \"starred\",\n    \"tag2\": \"quality\",\n    \"endpoint\": \"https://agent.example/api\",\n    \"feedbackUri\": \"ipfs://Qm...\"\n  }\n}\n```\n\n**Solana request:**\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"solana\",\n  \"feedback\": {\n    \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n    \"value\": 87,\n    \"valueDecimals\": 0,\n    \"tag1\": \"quality\",\n    \"tag2\": \"api\",\n    \"endpoint\": \"https://agent.example/api\",\n    \"feedbackUri\": \"ipfs://Qm...\",\n    \"score\": 95\n  }\n}\n```\n\nSolana feedback triggers ATOM Engine CPI for trust scoring (trust tiers, HyperLogLog diversity, EMA quality).\n\n**Send `score` (0-100) on Solana.** Without it the engine records the feedback on the\nagent but scores nothing - the program reports `had_impact=false` and reputation stays\nat zero no matter how much feedback accumulates.\n","operationId":"path_feedback_post","requestBody":{"description":"ERC-8004 feedback request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Feedback submission result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Feedback submission failed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/feedback/response":{"post":{"tags":["ERC-8004"],"summary":"Append response to feedback","description":"\nAppends an agent's response to existing feedback.\n\n**EVM request:**\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"base\",\n  \"agentId\": 42,\n  \"clientAddress\": \"0x...\",\n  \"feedbackIndex\": 1,\n  \"responseUri\": \"ipfs://Qm...\",\n  \"responseHash\": \"0x...\"\n}\n```\n\n**Solana request** (requires `sealHash` for SEAL v1 integrity, `clientAddress` as Solana Pubkey):\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"solana\",\n  \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n  \"clientAddress\": \"Bz5K7...\",\n  \"feedbackIndex\": 1,\n  \"responseUri\": \"ipfs://Qm...\",\n  \"responseHash\": \"0x...\",\n  \"sealHash\": \"0xabc123...\"\n}\n```\n","operationId":"path_feedback_response","requestBody":{"description":"Append response request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Response appended","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Failed to append response","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/feedback/revoke":{"post":{"tags":["ERC-8004"],"summary":"Revoke feedback","description":"\nRevokes previously submitted reputation feedback.\n\n**EVM request:**\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"base\",\n  \"agentId\": 42,\n  \"feedbackIndex\": 1\n}\n```\n\n**Solana request** needs the SEAL v1 hash of the feedback being revoked. Send the\ncontent under `originalFeedback` and the facilitator derives it; the values must match\nthe original submission exactly.\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"solana\",\n  \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n  \"feedbackIndex\": 1,\n  \"originalFeedback\": {\n    \"value\": 95, \"valueDecimals\": 0,\n    \"tag1\": \"uptime\", \"tag2\": \"verify\",\n    \"endpoint\": \"https://api.example.com\",\n    \"feedbackUri\": \"https://example.com/feedback.json\"\n  }\n}\n```\n`sealHash: \"0x...\"` is still accepted if you computed it yourself (keccak256 over the\nprogram's SEAL v1 layout) and takes precedence over `originalFeedback`.\n","operationId":"path_feedback_revoke","requestBody":{"description":"Revoke feedback request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Revocation result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Revocation failed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Returns the health status of the facilitator service.","operationId":"path_health","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object"},"example":{"status":"healthy"}}}}}}},"/identity/{network}/owner/{address}":{"get":{"tags":["ERC-8004"],"summary":"Resolve an agent by its owner","description":"\nReturns the first agent held by an address, for callers that need to know whether\nan owner already has one before minting another.\n\n**EVM networks:** `balanceOf` then batched `ownerOf` via Multicall3.\n\n**Solana networks:** a `getProgramAccounts` scan filtered by the AgentAccount\ndiscriminator and the `owner` field. `balance` is the number of agents matched.\nThe value read is `AgentAccount.owner`, which the registry caches from the Core\nasset: an asset moved outside the registry's own transfer leaves it stale until\nsomeone calls `sync_owner`.\n\n```json\n{\n  \"agentId\": \"247Y4QLwz9ZbcuHR2nX2EQLZHCsMs1GTqvgd6fpdn85Q\",\n  \"owner\": \"6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv\",\n  \"agentUri\": \"https://example.com/agent.json\",\n  \"network\": \"solana\",\n  \"balance\": \"1\"\n}\n```\n\n**404 means the owner holds nothing; 503 means the lookup could not reach a\nverdict.** Treat them differently: persisting \"not registered\" from a 503 is how\na transient RPC failure becomes a permanent wrong answer, and on a mint path it\nleads to minting a duplicate agent. A 503 carries `\"retryable\": true`.\n","operationId":"path_identity_by_owner","parameters":[{"name":"network","in":"path","description":"Network name (e.g., base, solana, solana-devnet)","required":true,"schema":{"type":"string"}},{"name":"address","in":"path","description":"Owner address: 0x-hex for EVM, base58 for Solana","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent found","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid network or address","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Address owns no agent on this network","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Lookup inconclusive, retry","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/identity/{network}/total-supply":{"get":{"tags":["ERC-8004"],"summary":"Get total registered agents","description":"\nReturns the total number of registered agents on a specific network.\n\n**EVM networks** return the ERC-721 totalSupply from the AgentRegistry contract.\nThe ATOM Engine tracks quality through EMA scores, not positive/negative tallies, so\nthere are no such counters.\n\n**Solana networks** read the Metaplex Core collection referenced by the RootConfig PDA:\n`totalSupply` is its `current_size` (net of burns) and `numMinted` its all-time mint count.\nThe registry itself keeps no agent counter on-chain.\n\n**EVM Response:**\n```json\n{\n  \"network\": \"base\",\n  \"totalSupply\": 156\n}\n```\n\n**Solana Response:**\n```json\n{\n  \"network\": \"solana\",\n  \"totalSupply\": 42\n}\n```\n","operationId":"path_identity_total_supply","parameters":[{"name":"network","in":"path","description":"Network name (e.g., ethereum, base, solana)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Total supply","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid or unsupported network","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/identity/{network}/{agent_id}":{"get":{"tags":["ERC-8004"],"summary":"Get agent identity","description":"\nRetrieves agent identity information from the ERC-8004 Identity Registry.\n\n**EVM networks:** ethereum, base, polygon, arbitrum, optimism, celo, bsc, monad, avalanche + testnets\n\n**Solana networks:** solana, solana-devnet (reads AgentAccount PDA from 8004-solana program)\n\n**EVM Response:**\n```json\n{\n  \"agentId\": 42,\n  \"owner\": \"0x...\",\n  \"agentUri\": \"ipfs://Qm...\",\n  \"agentWallet\": \"0x...\",\n  \"network\": \"base\"\n}\n```\n\n**Solana Response:**\n```json\n{\n  \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n  \"owner\": \"5FHwkrdxPMsgAJBDkWmcoLiN9m1K95VCGw7qr4eXfjsP\",\n  \"agentUri\": \"https://example.com/agent.json\",\n  \"nftName\": \"My AI Agent\",\n  \"feedbackCount\": 47,\n  \"network\": \"solana\"\n}\n```\n","operationId":"path_identity","parameters":[{"name":"network","in":"path","description":"Network name (e.g., ethereum, base, solana, solana-devnet)","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","description":"Agent ID: numeric for EVM (e.g., 42), base58 Pubkey for Solana","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent identity","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid network or agent","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Agent not found","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/identity/{network}/{agent_id}/metadata/{key}":{"get":{"tags":["ERC-8004"],"summary":"Read agent metadata","description":"\nReads a specific metadata key from an agent's Identity Registry entry.\n\nSupports both EVM and Solana networks. On Solana, metadata is stored in MetadataEntryPda accounts derived from the agent's NFT address and metadata key hash.\n\n**Response:**\n```json\n{\n  \"agentId\": 42,\n  \"key\": \"description\",\n  \"value\": \"0x48656c6c6f\",\n  \"valueUtf8\": \"Hello\",\n  \"network\": \"base\"\n}\n```\n","operationId":"path_identity_metadata","parameters":[{"name":"network","in":"path","description":"Network name (e.g., ethereum, base, solana)","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","description":"Agent ID: numeric for EVM, base58 Pubkey for Solana","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","description":"Metadata key (e.g., description, website, version)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Metadata value","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid network or agent","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Agent or metadata key not found","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/register":{"get":{"tags":["ERC-8004"],"summary":"Get agent registration schema","description":"Returns the JSON schema for ERC-8004 agent registration requests, including supported networks and body format.","operationId":"path_register_get","responses":{"200":{"description":"Registration schema","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["ERC-8004"],"summary":"Register a new agent","description":"\nRegisters a new ERC-8004 agent on-chain. The facilitator pays all gas fees.\n\n**Supported networks:** 18 networks (EVM + Solana). EVM chains use ERC-721 NFTs, Solana uses Metaplex Core NFTs.\n\n**EVM request:**\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"base\",\n  \"agentUri\": \"ipfs://Qm.../agent.json\",\n  \"metadata\": [{\"key\": \"description\", \"value\": \"0x...\"}],\n  \"recipient\": \"0x...\"\n}\n```\n\n**Solana request:** `recipient` is a base58 Solana address.\n```json\n{\n  \"x402Version\": 1,\n  \"network\": \"solana\",\n  \"agentUri\": \"ipfs://Qm.../agent.json\",\n  \"metadata\": [{\"key\": \"x402Support\", \"value\": \"true\"}],\n  \"recipient\": \"6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv\"\n}\n```\n\nOn Solana the facilitator mints, initializes the agent's ATOM stats account, then\ntransfers the Metaplex Core asset to `recipient`, paying every fee. The ordering is\nrequired: only the owner can initialize the stats, so it happens before the transfer.\nWithout that account the ATOM Engine records feedback but scores none of it.\n\n`agentWallet` does not survive the transfer and must be re-set by the new owner,\nthe same as on EVM.\n\nIf the mint succeeds but the transfer fails, the response is a 500 that still carries\n`agentId` and `transaction`: the agent exists and is held by the facilitator, and is\nnever reported as delivered.\n\n**EVM response:** `agentId` is a numeric string (ERC-721 tokenId).\n**Solana response:** `agentId` is a base58 Pubkey (Metaplex Core NFT mint address).\n\n```json\n{\n  \"success\": true,\n  \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n  \"transaction\": \"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d6...\",\n  \"owner\": \"facilitator-pubkey...\",\n  \"network\": \"solana\"\n}\n```\n\n**Async mode (EVM):** send header `Prefer: respond-async` (or `X-Async: true`) to\nget an immediate `202 Accepted` with a `jobId` instead of blocking on the ~28s\non-chain confirmation. Poll `GET /register/status/{jobId}` until `status` is\n`done` and `agentId` is populated. The `Location` header of the 202 points at the\nstatus URL, keeping the facilitator's on-chain latency out of the caller's\ntimeout budget.\n\n**Idempotency / in-flight lock:** a second registration for the same\n`network|agentUri|recipient` while the first is still confirming is not\nre-minted — the async path returns the existing job, the sync path returns\n`409 Conflict`.\n","operationId":"path_register_post","requestBody":{"description":"Agent registration request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Registration result (sync)","content":{"application/json":{"schema":{"type":"object"}}}},"202":{"description":"Async registration accepted; poll /register/status/{jobId}","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Registration failed","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"A registration for this agent is already in progress","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/register/status/{job_id}":{"get":{"tags":["ERC-8004"],"summary":"Poll async registration status","description":"\nReturns the status of an asynchronous ERC-8004 registration started with\n`Prefer: respond-async` on `POST /register`.\n\n`status` progresses `pending -> mint_confirmed -> done` (or `failed`). Once\n`mint_confirmed`/`done`, `agentId` is populated. Terminal jobs are retained for\none hour before they age out (then this returns `404`).\n\n```json\n{\n  \"jobId\": \"reg_42\",\n  \"status\": \"done\",\n  \"network\": \"base\",\n  \"agentId\": \"17\",\n  \"transaction\": \"0x...\",\n  \"transferTransaction\": \"0x...\",\n  \"owner\": \"0x...\"\n}\n```\n","operationId":"path_register_status","parameters":[{"name":"job_id","in":"path","description":"Job id from the async POST /register","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current job status","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Job not found or expired","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/reputation/{network}/{agent_id}":{"get":{"tags":["ERC-8004"],"summary":"Get agent reputation","description":"\nQueries the reputation summary for an AI agent from the ERC-8004 Reputation Registry.\n\n**EVM networks:** ethereum, base, polygon, arbitrum, optimism, celo, bsc, monad, avalanche + testnets\n\n**Solana networks:** solana, solana-devnet (reads from ATOM Engine for enriched reputation data)\n\n**Client address filtering (EVM only):** The `clientAddresses` query parameter accepts comma-separated Ethereum addresses to filter reputation data by specific clients. If omitted, the endpoint auto-discovers all clients who have given feedback via the on-chain `getClients()` function.\n\n**Examples:**\n- `/reputation/base/42` - EVM agent (all clients, auto-discovered)\n- `/reputation/solana/7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv` - Solana agent (with ATOM stats)\n- `/reputation/base/42?includeFeedback=true&tag1=quality` - with feedback entries filtered by tag\n\n**EVM Response:**\n```json\n{\n  \"agentId\": 42,\n  \"summary\": { \"count\": 15, \"summaryValue\": 87, \"summaryValueDecimals\": 0 },\n  \"feedback\": [...],\n  \"atomStats\": null,\n  \"network\": \"base\"\n}\n```\n\n**Solana Response (includes ATOM Engine bonus data):**\n```json\n{\n  \"agentId\": \"7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv\",\n  \"summary\": { \"count\": 47, \"summaryValue\": 78, \"summaryValueDecimals\": 0 },\n  \"atomStats\": {\n    \"trustTier\": 3, \"trustTierName\": \"Trusted\",\n    \"qualityScore\": 78, \"loyaltyScore\": 64, \"confidence\": 85, \"riskScore\": 12,\n    \"diversityRatio\": 67, \"minScore\": 40, \"maxScore\": 99, \"lastScore\": 95,\n    \"feedbackCount\": 47, \"lastFeedbackSlot\": 301118422\n  },\n  \"network\": \"solana\"\n}\n```\n","operationId":"path_reputation","parameters":[{"name":"network","in":"path","description":"Network name (e.g., ethereum, base, solana, solana-devnet)","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","description":"Agent ID: numeric for EVM (e.g., 42), base58 Pubkey for Solana","required":true,"schema":{"type":"string"}},{"name":"include_feedback","in":"query","description":"Include individual feedback entries","required":false,"schema":{"type":"boolean"}},{"name":"client_addresses","in":"query","description":"Comma-separated client addresses to filter by. If omitted, auto-discovers all clients via getClients()","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Reputation data","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid network or agent","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Agent not found","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/settle":{"get":{"tags":["Core"],"summary":"Get settlement schema","description":"Returns the JSON schema for payment settlement requests.","operationId":"path_settle_get","responses":{"200":{"description":"Settlement schema","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Core"],"summary":"Settle payment on-chain","description":"\nSubmits a verified payment authorization to the blockchain for settlement.\n\n**Process:**\n1. Verifies the payment (same as /verify)\n2. Calls `transferWithAuthorization` on the token contract\n3. Returns transaction hash on success\n\n**Upto Settlement (scheme: \"upto\"):**\n\nWhen `scheme: \"upto\"`, the client provides a Permit2-signed authorization for a maximum amount.\nThe server settles for the actual usage amount (<= authorized max). If actual amount is 0, no\non-chain transaction is submitted.\n\nUses `x402UptoPermit2Proxy.settle(permit, amount, owner, witness, signature)` via Uniswap Permit2.\n\n**Escrow / Commerce Lifecycle (scheme: \"escrow\" or \"commerce\"):**\n\nBoth `\"escrow\"` and `\"commerce\"` schemes are supported and functionally identical.\nThe `\"commerce\"` alias was introduced by x402r for marketplace integrations (e.g., Execution Market).\nThe `action` field controls the operation:\n\n| Action | Description | Signature Required |\n|--------|-------------|-------------------|\n| `authorize` (default) | Lock funds in escrow | Yes (ERC-3009) |\n| `release` | Send escrowed funds to receiver | No |\n| `refundInEscrow` | Return escrowed funds to payer | No |\n\nEscrow contracts deployed on 11 networks. See `/supported` for networks with active PaymentOperator deployments.\n\n**Escrow release/refund payload** (no signature needed):\n```json\n{\n  \"scheme\": \"escrow\",\n  \"action\": \"release\",\n  \"payload\": {\n    \"paymentInfo\": { \"operator\": \"0x...\", \"receiver\": \"0x...\", ... },\n    \"payer\": \"0x...\",\n    \"amount\": \"1000000\"\n  },\n  \"paymentRequirements\": {\n    \"network\": \"eip155:8453\",\n    \"extra\": { \"escrowAddress\": \"0x...\", \"operatorAddress\": \"0x...\", \"tokenCollector\": \"0x...\" }\n  }\n}\n```\n\n**Response on success:**\n```json\n{\n  \"success\": true,\n  \"transaction\": \"0x...\",\n  \"network\": \"base\",\n  \"payer\": \"0x...\"\n}\n```\n\n**Response on failure:**\n```json\n{\n  \"success\": false,\n  \"errorReason\": \"insufficient_balance\",\n  \"payer\": \"0x...\",\n  \"network\": \"base\"\n}\n```\n","operationId":"path_settle_post","requestBody":{"description":"x402 settle request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Settlement result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Settlement failed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/supported":{"get":{"tags":["Discovery"],"summary":"List supported payment kinds","description":"\nReturns all supported payment kinds (network + scheme + version combinations).\n\n**Schemes:**\n- `exact` - Direct EIP-3009 payment settlement (v1 and v2 formats)\n- `upto` - Permit2-based variable amount settlement (v2 only, CAIP-2 networks). Client authorizes a max amount; server settles actual usage (<= max). Ideal for usage-based pricing (LLM tokens, bandwidth, metered APIs).\n- `escrow` - x402r PaymentOperator escrow (v2 only, CAIP-2 networks)\n- `fhe_transfer` - FHE encrypted transfer via Zama (v1 and v2)\n\n**Upto networks (11):** Base, Optimism, Arbitrum, Polygon, BSC, Ethereum, HyperEVM, Monad, Base Sepolia, Avalanche Fuji, Arbitrum Sepolia — via the x402UptoPermit2Proxy contract (Permit2-based, canonical CREATE2 address `0x4020A4f3b7b90ccA423B9fabCc0CE57C6C240002`).\n\n`upto` is **not** available on every EVM network that supports `exact`. The proxy address is identical on all chains because it is deployed with CREATE2, but the deployment still has to be replayed per chain, and on Avalanche, Celo, Scroll, Unichain and Optimism Sepolia it never was — the address has no code there. Query `/supported` rather than assuming: it now lists `upto` only where settlement can actually succeed.\n\n**Escrow networks (9 total):** Base, Ethereum, Polygon, Arbitrum, Celo, Monad, Avalanche, Base Sepolia, Ethereum Sepolia.\nOnly networks with a deployed PaymentOperator appear in the response.\n\n**Response includes both v1 and v2 formats:**\n- v1: `\"network\": \"base\"` (string enum)\n- v2: `\"network\": \"eip155:8453\"` (CAIP-2 format)\n","operationId":"path_supported","responses":{"200":{"description":"Supported payment kinds","content":{"application/json":{"schema":{"type":"object"},"example":{"kinds":[{"x402Version":1,"scheme":"exact","network":"base"},{"x402Version":2,"scheme":"exact","network":"eip155:8453"},{"x402Version":2,"scheme":"upto","network":"eip155:8453"},{"x402Version":2,"scheme":"escrow","network":"eip155:8453","extra":{"escrowAddress":"0xb9488351E48b23D798f24e8174514F28B741Eb4f","operatorAddress":"0x...","tokenCollector":"0x48ADf6E37F9b31dC2AAD0462C5862B5422C736B8"}}]}}}}}}},"/transactions":{"get":{"tags":["Discovery"],"summary":"Recent operations the facilitator recorded","description":"Recent verify/settle operations, newest first.\n\n**This is an index, not a ledger.** The record is written best-effort AFTER the operation resolved, so an unreachable store loses rows and never blocks a payment. The chain is authoritative; a row missing here does not mean the payment did not happen.\n\nCounting starts when the store was enabled — earlier operations are absent, not zero. `limit` is capped at 200.","operationId":"path_transactions","parameters":[{"name":"limit","in":"query","description":"Rows to return (1-200, default 50)","required":false,"schema":{"type":"integer","minimum":0}},{"name":"network","in":"query","description":"Canonical slug, e.g. `base`","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent operations","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Transaction store unavailable or not configured"}}}},"/verify":{"get":{"tags":["Core"],"summary":"Get verification schema","description":"Returns the JSON schema for payment verification requests.","operationId":"path_verify_get","responses":{"200":{"description":"Verification schema","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Core"],"summary":"Verify payment authorization","description":"\nVerifies an x402 payment authorization without settling it on-chain.\n\n**Checks performed:**\n- Payload structure validation\n- EIP-712 signature verification\n- Nonce validity\n- Amount matching\n- Timestamp validity (validAfter/validBefore)\n- Token and network support\n\n**Request body:**\n```json\n{\n  \"x402Version\": 1,\n  \"paymentPayload\": {\n    \"signature\": \"0x...\",\n    \"payload\": {\n      \"scheme\": \"exact\",\n      \"network\": \"base\",\n      \"asset\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n      \"from\": \"0x...\",\n      \"to\": \"0x...\",\n      \"amount\": \"1000000\",\n      \"validAfter\": 1700000000,\n      \"validBefore\": 1700100000,\n      \"nonce\": \"0x...\"\n    }\n  },\n  \"paymentRequirements\": {\n    \"scheme\": \"exact\",\n    \"network\": \"base\",\n    \"maxAmountRequired\": \"1000000\",\n    \"payTo\": \"0x...\",\n    \"asset\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\"\n  }\n}\n```\n","operationId":"path_verify_post","requestBody":{"description":"x402 verify request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"type":"object"},"example":{"isValid":true}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object"},"example":{"error":"Invalid signature"}}}}}}},"/version":{"get":{"tags":["Discovery"],"summary":"Get facilitator version","description":"Returns the current version of the facilitator. The version always matches the Cargo.toml package version.","operationId":"path_version","responses":{"200":{"description":"Version info","content":{"application/json":{"schema":{"type":"object"},"example":{"version":"(current Cargo.toml version)"}}}}}}}},"components":{},"tags":[{"name":"Core","description":"Core x402 payment verification and settlement (exact, upto, escrow schemes)"},{"name":"Escrow","description":"Gasless escrow lifecycle (authorize, release, refund, state query)"},{"name":"Discovery","description":"Network and scheme discovery"},{"name":"ERC-8004","description":"AI Agent reputation and identity (ERC-8004 Trustless Agents) - 18 networks (EVM + Solana)"},{"name":"Bazaar","description":"Decentralized resource discovery registry"},{"name":"Compliance","description":"OFAC compliance and sanctions screening"},{"name":"Health","description":"Service health and status"}]}