{"openapi":"3.1.0","info":{"title":"LEGIT","description":"Trust-check any x402 merchant or agent address on Algorand, Base, Solana, or 17 other chains before routing a payment. Returns a real-time grade (A+ to F) and score (0-100) built from live uptime, response latency, and payment coherence measurements, not self-reported data. Run as a pre-payment trust check: call GET /v1/check/{address} before any x402 payment to an address you have not paid before. Free: check a single address, pull a full trust report, batch-check multiple addresses, get a routing recommendation between two counterparties, resolve a merchant's on-chain identity, query the ranked merchant leaderboard, see trending active merchants, and read live network pulse. Paid ($0.004 Algorand / $0.005 Base, via x402): compare two addresses side-by-side, get arena verdicts, pull 30-day score history for trend analysis, set a webhook-armed watch sentinel (7-day diagnostic tier or 30-day standard, same rail price) that fires on grade transitions, and run deep-check due diligence. Use before sending an x402 payment to an unknown merchant, before accepting a counterparty in agent-to-agent settlement, or to monitor a critical upstream service for trust degradation. Created by GONNA.","version":"0.1.0","contact":{"name":"GONNA","url":"https://gonna.bond/gonnaverse/","email":"legit@gonna.bond"},"x-logo":{"url":"https://legit.gonna.bond/favicon.png"},"x-guidance":"LEGIT is the trust and routing layer for the x402 agentic economy. Trust-check any x402 merchant address on Algorand, Base, Solana or 17 other chains before routing a payment: grades (A+ to F) and scores (0-100) come from live uptime, latency and payment-coherence probes, never self-reported data. Run as a pre-payment trust check: call GET /v1/check/{address} before any x402 payment to an address you have not paid before. Start FREE: GET /v1/check/{address} (full trust report), /v1/leaderboard (ranked shortlist), /v1/trending, /v1/pulse, /v1/arena/preview. Paid per call in USDC over x402: GET /v1/compare (2-5 merchants head-to-head), /v1/arena (24h cross-chain settlement benchmark, ?network= filter), /v1/history?address=... (30-day trust trend), POST /v1/watch (7- or 30-day change sentinel, webhook-armed), POST /v1/deep-check (due diligence, up to 10 addresses). How to pay: call a paid endpoint without paying and it answers 402 with a PaymentRequired document listing every active rail; pay one rail and retry with the PAYMENT-SIGNATURE header. Rails cheapest first: algorand-mainnet $0.004, base-mainnet and solana-mainnet $0.005 per call. Watch companions GET /v1/watches/{watch_id} and /v1/watches/{watch_id}/events are FREE: the watch id is the bearer capability for status and the event feed. Webhook payload anatomy: /docs; agent manifest: /llms.txt. Use LEGIT before sending an x402 payment to an unknown merchant, before accepting a counterparty in agent-to-agent settlement, or to monitor a critical upstream for trust degradation."},"paths":{"/health":{"get":{"summary":"Liveness probe","description":"Liveness probe: ``{\"status\": \"ok\"}`` when the service is up (FREE).","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Health Get"}}}}},"security":[]}},"/v1/leaderboard":{"get":{"summary":"Query the ranked merchant leaderboard to shortlist counterparties","description":"Leaderboard with optional ?network= filter (SPEC_V2, Module A).\n\n``networks`` always lists the distinct networks present BEFORE filtering\nso clients can build filter chips; backwards compatible with Wave 1.\n\nWave 16 (Instant Speed): cacheable for 30s. ``view=trimmed`` is the\ndashboard's diet variant: null optional fields are omitted entirely\n(the dashboard treats absent and null identically), which removes\nhundreds of ``\"field\":null`` pairs from a large board. The default\nview is byte-for-byte the public contract it always was.\n\nWave 18 (The Instant Doctrine): opt-in server pagination via\n``page``/``size`` (25/50/100) plus a ``q`` name/address substring\nfilter, sliced AFTER the existing filter+sort+rank logic so ranks\nstay global; the paged payload also carries ``counts`` (cheap\nper-network tallies for the dashboard chips). A 30s in-process TTL\ncache (keyed by the full query string) fronts every variant; the\nrate limiter still sees every request.\n\nWave 40 (La Voce): testnet networks and dormant merchants (no\nmeasurement inside LEGIT_ACTIVE_WINDOW_DAYS, default 7 days) are out\nof the default view; ``?include_testnet=true`` and\n``?include_dormant=true`` restore them, dormant entries flagged\n``dormant: true``.\n\nWave 41 (La Bellezza, W0): ``rank`` is the consecutive position in\nthe returned view (post testnet/dormant policy): 1,2,3 with no\nholes. The additive ``rank_global`` preserves the absolute\npre-filter rank; with both opt-ins active, rank == rank_global.","operationId":"leaderboard_v1_leaderboard_get","parameters":[{"name":"network","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":32,"pattern":"^[a-z0-9-]+$"},{"type":"null"}],"description":"Optional exact-match network filter (e.g. base-mainnet)","title":"Network"},"description":"Optional exact-match network filter (e.g. base-mainnet)"},{"name":"view","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(full|trimmed)$"},{"type":"null"}],"description":"Optional payload diet. 'trimmed' omits null-valued optional fields (additive contract: absent instead of null); the default keeps the full Wave 1 shape.","title":"View"},"description":"Optional payload diet. 'trimmed' omits null-valued optional fields (additive contract: absent instead of null); the default keeps the full Wave 1 shape."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Wave 18: optional 1-based server page. When page and/or size are given the response becomes the paged shape {generated_at, total, page, size, entries} sliced AFTER the global rank/filter logic, so ranks stay global.","title":"Page"},"description":"Wave 18: optional 1-based server page. When page and/or size are given the response becomes the paged shape {generated_at, total, page, size, entries} sliced AFTER the global rank/filter logic, so ranks stay global."},{"name":"size","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Wave 18: page size, one of 25, 50, 100 (default 50 when paging).","title":"Size"},"description":"Wave 18: page size, one of 25, 50, 100 (default 50 when paging)."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}],"description":"Wave 18: optional name/address substring filter.","title":"Q"},"description":"Wave 18: optional name/address substring filter."},{"name":"include_testnet","in":"query","required":false,"schema":{"type":"boolean","description":"Wave 40: testnet/devnet/amoy/sepolia networks are excluded by default; pass ?include_testnet=true to restore them (same entry shape).","default":false,"title":"Include Testnet"},"description":"Wave 40: testnet/devnet/amoy/sepolia networks are excluded by default; pass ?include_testnet=true to restore them (same entry shape)."},{"name":"include_dormant","in":"query","required":false,"schema":{"type":"boolean","description":"Wave 40: the default view shows only merchants with a measurement inside the active window (LEGIT_ACTIVE_WINDOW_DAYS, default 7 days); pass ?include_dormant=true for the full view, with dormant entries flagged dormant=true.","default":false,"title":"Include Dormant"},"description":"Wave 40: the default view shows only merchants with a measurement inside the active window (LEGIT_ACTIVE_WINDOW_DAYS, default 7 days); pass ?include_dormant=true for the full view, with dormant entries flagged dormant=true."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Leaderboard"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/stats":{"get":{"summary":"Read headline service stats and storage facts","description":"Headline service stats: merchant and measurement counts, average\ntrust score and verifiable storage facts (FREE, cached 30s).","operationId":"stats_v1_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Stats"}}}}},"security":[]}},"/v1/compare":{"get":{"summary":"Compare 2-5 addresses side-by-side before picking one to pay","description":"Compare 2-5 merchant addresses head-to-head (FREE, rate limited).\n\nReturns a TrustReport-like summary per address plus ``winner`` (best\ntrust score; Wave 7 ties broken by more real payments settled, then\nlower median latency, then higher sample size) and a plain-English\n``rationale``. Untracked addresses are included with ``score=null``\nand ``tracked=false``; they cannot win.\n\nWave 41c (Il Cliente Cieco): ``addresses`` is optional. A blind\nclient (one that paid and calls with no parameters) gets the top\nmerchants of the current default ranking compared, with the additive\n``defaults_applied`` field disclosing the choice; when the ranking\nholds too few real merchants no sensible default exists and the\nparameter stays honestly required (self-documenting 422). Paid: $0.004 on Algorand / $0.005 on Base, via x402 (per call in USDC on algorand-mainnet or base-mainnet; the 402 response lists every active rail). The POST /v1/watch 7-day diagnostic tier pays the same per-call rail price as the 30-day watch.","operationId":"compare_v1_compare_get","parameters":[{"name":"addresses","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":2000},{"type":"null"}],"description":"Comma-separated merchant addresses (2-5). Optional: when omitted, the top merchants of the current default ranking are compared and the choice is disclosed in defaults_applied.","title":"Addresses"},"description":"Comma-separated merchant addresses (2-5). Optional: when omitted, the top merchants of the current default ranking are compared and the choice is disclosed in defaults_applied.","examples":{"two_addresses":{"summary":"Compare two Algorand merchant addresses","value":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A,ZQFL2SVFDQDKFAUCCE2WVXH6EF3LRUUJZLKJMDIED56LODOKW23JSKB7NT"},"three_addresses":{"summary":"Compare three Algorand merchant addresses","value":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A,ZQFL2SVFDQDKFAUCCE2WVXH6EF3LRUUJZLKJMDIED56LODOKW23JSKB7NT,TARTD3TCZERKBTXQQEQED76TGSCBU6SL2QE3Z5K74GKTRCIHFMSIDAOLJP"}}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareResponse"},"example":{"generated_at":"2026-01-01T00:00:00+00:00","entries":[{"address":"ADDRESS_A","name":"Merchant A","score":82.5,"grade":"B","provisional":false,"uptime_pct":99.5,"latency_p50_ms":210.0,"sample_size":12,"settle_count":340,"network":"algorand-mainnet","explorer_url":"https://allo.info/account/ADDRESS_A","tracked":true},{"address":"ADDRESS_B","name":null,"score":null,"grade":null,"provisional":false,"uptime_pct":null,"latency_p50_ms":null,"sample_size":0,"settle_count":0,"network":null,"explorer_url":null,"tracked":false}],"winner":"ADDRESS_A","rationale":"Merchant A wins: highest trust score (82.5 vs 71.0)."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"Payment required: the body is an x402 PaymentRequired document (x402Version, error, resource, accepts) listing the USDC payment offers for every active rail; retry with a payment payload.","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.004"},"protocols":[{"x402":{}}]}}},"/v1/check/{address}":{"get":{"summary":"Trust-check a merchant address before paying it","description":"Full trust report for one merchant (Algorand address or base URL).","operationId":"check_v1_check__address__get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustReport"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/receipts":{"get":{"summary":"Receipts","description":"Verified on-chain payment receipts for one tracked merchant.\n\nThe 30-day ledger of real settlements observed by LEGIT's own keyless\nchain scan (Algorand first): who paid, how much, when, with the\non-chain transaction id as independently verifiable evidence.\n``receipts`` is newest-first and capped at 100 entries while\n``total_receipts`` and ``volume_usd`` cover the full window. An empty\nwindow is an honest empty answer (total_receipts 0, receipts []),\nnever invented rows; untracked addresses get an honest 404.\n\nWave 47b: the address is a mandatory query parameter (the /v1/history\nconvention), so the registered path is exactly \"/v1/receipts\" and an\noperator-declared X402_PREMIUM_PATHS entry matches it byte-for-byte.\nThis endpoint is FREE by construction: it ships outside\nX402_PREMIUM_PATHS and stays free until the operator adds the path to\nthat env var (per-path payment via the app.payments middleware, which\nthis wave does not touch).","operationId":"receipts_v1_receipts_get","parameters":[{"name":"address","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":300,"description":"Merchant address (or base URL) exactly as tracked by LEGIT, e.g. ?address=ADDR.","title":"Address"},"description":"Merchant address (or base URL) exactly as tracked by LEGIT, e.g. ?address=ADDR.","examples":{"algorand_address":{"summary":"30-day receipts of one Algorand merchant","value":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"}}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiptsResponse"}}}},"404":{"description":"The address is not tracked by LEGIT: an honest 404, never an invented ledger."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/route":{"get":{"summary":"Get a routing recommendation between two counterparties","description":"Phase 0 routing: keyword match on merchant name/address, best score wins.","operationId":"route_v1_route_get","parameters":[{"name":"need","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Need"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/report/{address}":{"get":{"summary":"Pull the full trust report of one merchant before integrating","description":"Deep report: full breakdown, 30-row score history, rank and percentile.\n\nFREE (rate limited). Unknown addresses get an honest unrated report.\nThe fabricated demo report requires the explicit ``?demo=true`` opt-in.","operationId":"report_v1_report__address__get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}},{"name":"demo","in":"query","required":false,"schema":{"type":"boolean","description":"Opt-in demo mode: for the five hardcoded demo addresses, return the fabricated illustration report flagged demo=true. Off by default: fabricated data is never served unmarked.","default":false,"title":"Demo"},"description":"Opt-in demo mode: for the five hardcoded demo addresses, return the fabricated illustration report flagged demo=true. Off by default: fabricated data is never served unmarked."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeepReport"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/batch-check":{"post":{"summary":"Batch-check multiple addresses in one call","description":"Trust-report-lite for 1..20 validated addresses in one call.\n\nFREE (rate limited). Fabricated demo entries require the explicit\n``?demo=true`` opt-in; when any are included the response is flagged\n``demo: true`` at the top level and per entry.","operationId":"batch_check_v1_batch_check_post","parameters":[{"name":"demo","in":"query","required":false,"schema":{"type":"boolean","description":"Opt-in demo mode: demo addresses resolve to the fabricated illustration entries flagged demo=true. Off by default.","default":false,"title":"Demo"},"description":"Opt-in demo mode: demo addresses resolve to the fabricated illustration entries flagged demo=true. Off by default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"addresses":{"type":"array","items":{"type":"string","maxLength":300},"minItems":1,"maxItems":20,"description":"1 to 20 merchant addresses or base URLs, each validated like /v1/check. Untracked addresses get an honest unrated report, never an invented score.","example":["G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"]}},"required":["addresses"]},"example":{"addresses":["G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"]}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchReport"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/trending":{"get":{"summary":"See trending active merchants","description":"FREE. Top 5 by 24h score delta; falls back to top 5 by score.\n\nWave 8.9 (the honesty gate): the demo-merchant fallback renders ONLY\nwhile the DB holds zero real merchants. When real merchants exist but\nno score signal has landed yet (cold start after a redeploy), the strip\ngets an honest empty list and the dashboard says it is gathering 24h\nsignals, instead of inventing names.\n\nWave 18 (The Instant Doctrine): served from the cycle-computed\nsnapshot; on a cold boot it computes ONCE, stores and serves. The\npath and shape are identical to what they always were.\n\nWave 40 (La Voce): testnet networks and dormant merchants are out of\nthe default strip; ?include_testnet=true and ?include_dormant=true\nrestore them, dormant entries flagged ``dormant: true``. The opt-in\nvariants are computed fresh per request (bounded grouped queries,\nrate limited); the snapshot serves the default view.","operationId":"trending_v1_trending_get","parameters":[{"name":"include_testnet","in":"query","required":false,"schema":{"type":"boolean","description":"Wave 40: testnet/devnet/amoy/sepolia networks are excluded by default; pass ?include_testnet=true to restore them (same entry shape).","default":false,"title":"Include Testnet"},"description":"Wave 40: testnet/devnet/amoy/sepolia networks are excluded by default; pass ?include_testnet=true to restore them (same entry shape)."},{"name":"include_dormant","in":"query","required":false,"schema":{"type":"boolean","description":"Wave 40: the default strip shows only merchants with a measurement inside the active window (LEGIT_ACTIVE_WINDOW_DAYS, default 7 days); pass ?include_dormant=true for the full field, dormant entries flagged dormant=true.","default":false,"title":"Include Dormant"},"description":"Wave 40: the default strip shows only merchants with a measurement inside the active window (LEGIT_ACTIVE_WINDOW_DAYS, default 7 days); pass ?include_dormant=true for the full field, dormant entries flagged dormant=true."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trending"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/pulse":{"get":{"summary":"Read the live x402 network pulse","description":"Real network pulse: the facilitator's masked live transaction stream,\nmerged with recent on-chain USDC payments from the Wave 8.5 ledger.\n\nWave 18 (The Instant Doctrine): served from the cycle-computed\nsnapshot (refreshed every indexer cycle), so a page load never waits\non the facilitator round-trip. Cold boot computes ONCE, stores and\nserves. Graceful empty list when the facilitator is unreachable.\nEach transaction carries ``tx_url`` (Wave 3.2): an explorer link when\nthe stream exposes a real on-chain hash, else None. On-chain rows are\nhonestly labeled ``event=\"onchain_payment\"`` and never presented as\nfacilitator settles.","operationId":"pulse_v1_pulse_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Pulse V1 Pulse Get"}}}}},"security":[]}},"/v1/chain-logos":{"get":{"summary":"Resolve official chain brand tiles","description":"Wave 14 (The Chain Heraldry): network slug -> official tile URL.\n\nStatic payload (the mapping only changes with a deploy), cacheable for\n10 minutes. Unmapped chains (skale-base-mainnet, aws-base, unknown\nslugs) are simply absent: clients keep their monogram/glyph fallback.","operationId":"chain_logos_v1_chain_logos_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Chain Logos V1 Chain Logos Get"}}}}},"security":[]}},"/v1/networks":{"get":{"summary":"Check per-chain payment health before routing","description":"Per-chain payment network health from the facilitator, plus honest\ncoverage counts from our own DB.\n\nCached 60s. Graceful empty ``networks`` list when the facilitator is\nunreachable. Wave 8.6: ``settlement_rails`` counts the facilitator\nrails (the 6 gasless chains) while ``chains_indexed``/``indexed_chains``\nreport how many chains the oracle actually indexes merchants on, so the\ntwo scopes are never conflated.","operationId":"networks_v1_networks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Networks V1 Networks Get"}}}}},"security":[]}},"/v1/merchant/{address}/identity":{"get":{"summary":"Resolve a merchant's on-chain identity across chains","description":"Cross-chain identity for a merchant, from our DB.\n\nGraceful 404-shape: ``{\"found\": false}`` (HTTP 200) when the address is\nunknown. Categories are best-effort filled from the facilitator's live\nidentity record ([] when unavailable).","operationId":"merchant_identity_v1_merchant__address__identity_get","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","title":"Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Merchant Identity V1 Merchant  Address  Identity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/arena":{"get":{"summary":"Get arena verdicts: the 24h cross-chain settlement benchmark","description":"Wave 6 (The Arena): the public cross-chain x402 settlement benchmark.\n\nRanks every chain with any signal (pulse transactions in the last 24h,\ntracked merchants, or facilitator network health) by real settle count\n(Wave 8.9: micropayments are a count economy; volume only breaks ties).\nCached 60s. Honest by construction: with zero pulse data in the\nwindow the narrative says the arena is still gathering its first data\nand no leader is named. Wave 39 (Il Biglietto da Visita): the optional\n?network= slug narrows the benchmark to one chain (cached separately\nper slug); an unknown slug is an honest 400 listing the valid slugs. Paid: $0.004 on Algorand / $0.005 on Base, via x402 (per call in USDC on algorand-mainnet or base-mainnet; the 402 response lists every active rail). The POST /v1/watch 7-day diagnostic tier pays the same per-call rail price as the 30-day watch.","operationId":"arena_v1_arena_get","parameters":[{"name":"network","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"description":"Optional chain slug filter, e.g. ?network=base-mainnet: the benchmark is narrowed to that one network. Omit it for the full cross-chain arena. An unknown slug is an honest 400 listing the slugs currently benchmarked.","title":"Network"},"description":"Optional chain slug filter, e.g. ?network=base-mainnet: the benchmark is narrowed to that one network. Omit it for the full cross-chain arena. An unknown slug is an honest 400 listing the slugs currently benchmarked.","examples":{"single_network":{"summary":"Benchmark one chain (Base)","value":"base-mainnet"},"algorand_only":{"summary":"Benchmark Algorand only","value":"algorand-mainnet"}}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Arena V1 Arena Get"},"example":{"generated_at":"2026-01-01T00:00:00+00:00","window_hours":24,"chains":[{"network":"base-mainnet","network_name":"Base","chain_family":"evm","tx_count_24h":150,"settles_24h":120,"settles_facilitator_24h":118,"settles_onchain_24h":2,"large_inflows_24h":0,"verifies_24h":30,"volume_usdc_24h":61.25,"avg_ticket_usdc_24h":0.51,"merchants_tracked":8,"avg_trust_score":76.4,"latency_p50_ms":240.0,"avg_settlement_time":"2s","rank":1}],"large_inflows_24h":0,"leader":"base-mainnet","narrative":"Base leads x402 settlement: 120 settles totaling 61.25 USDC in 24h."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"Payment required: the body is an x402 PaymentRequired document (x402Version, error, resource, accepts) listing the USDC payment offers for every active rail; retry with a payment payload.","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.004"},"protocols":[{"x402":{}}]}}},"/v1/arena/preview":{"get":{"summary":"Preview the settlement arena for free","description":"Wave 16: the FREE trimmed arena snapshot for the public homepage.\n\nSame groups/structure the dashboard needs to render the arena doors,\nevery indexed chain included and stripped to the rendered fields.\nExplicitly free tier (never in DEFAULT_PREMIUM_PATHS), cached 60s both\nin-process and via Cache-Control. Built from the same assembly as the\npremium /v1/arena so the two views can never disagree about the facts.","operationId":"arena_preview_v1_arena_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Arena Preview V1 Arena Preview Get"}}}}},"security":[]}},"/.well-known/legit":{"get":{"summary":"Discover LEGIT's endpoints, pricing and rails","description":"Machine-readable service document: endpoints, pricing, rails.\n\nWave 37 (The Aligned Docs): this document must say what production\ndoes. The free tier below is served without payment today; the premium\ntier (compare, arena, history, watch, deep-check) answers 402 with\nx402 offers at the real prices when the operator lists it in\nX402_PREMIUM_PATHS. Only rails that exist in the 402 documents are\nlisted (never promise a rail that does not exist).","operationId":"wellknown__well_known_legit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Wellknown  Well Known Legit Get"}}}}},"security":[]}},"/v1/history":{"get":{"summary":"Pull 30-day score history of one merchant for trend analysis","description":"Thirty days of trust history for one x402 merchant.\n\nThe daily series combines the surviving daily probe rollups and the\nraw probes still inside the retention window (sample counts, uptime,\nlatency avg/min/max) with the daily average/min/max trust score and\nmodal grade from LEGIT's score history. Every day carries a lean\n\"meta\" block (coverage, provenance, and gap_kind only when a\nmeasured day has no score row) so an agent can tell a rollup-backed\nday from a raw-only day and a compaction hole from a scoring gap.\ncoverage describes measurement completeness, not score completeness.\nA day can be coverage: complete with score: absent when probes ran\nbut scoring did not.\nThe current snapshot adds the\nlatest score, grade, probe tier, 7d and 30d uptime and the median\nlatency. One call answers the question every buyer asks before\nintegrating: is this merchant getting better or worse? Untracked\naddresses get an honest 404; a tracked merchant stale for its probe\ntier queues an on-demand re-probe, disclosed in the response.\n\nWave 41c (Il Cliente Cieco): ``address`` is optional. A blind client\n(one that paid and calls with no parameters) gets the history of the\nrank-1 merchant of the current default ranking, with the additive\n``defaults_applied`` field disclosing the choice; when the ranking\nholds no real merchant no sensible default exists and the parameter\nstays honestly required (self-documenting 422). Paid: $0.004 on Algorand / $0.005 on Base, via x402 (per call in USDC on algorand-mainnet or base-mainnet; the 402 response lists every active rail). The POST /v1/watch 7-day diagnostic tier pays the same per-call rail price as the 30-day watch.","operationId":"history_v1_history_get","parameters":[{"name":"address","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":300},{"type":"null"}],"description":"Merchant address (or base URL) exactly as tracked by LEGIT, e.g. ?address=ADDR. Optional: when omitted, the rank-1 merchant of the current default ranking is used and the choice is disclosed in defaults_applied.","title":"Address"},"description":"Merchant address (or base URL) exactly as tracked by LEGIT, e.g. ?address=ADDR. Optional: when omitted, the rank-1 merchant of the current default ranking is used and the choice is disclosed in defaults_applied.","examples":{"algorand_address":{"summary":"30-day history of one Algorand merchant","value":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"}}}],"responses":{"200":{"description":"The merchant's 30-day trust history and current snapshot.","content":{"application/json":{"schema":{"type":"object","title":"Response History V1 History Get"},"example":{"generated_at":"2026-08-10T00:00:00","address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","name":"AlgoPay Gateway","network":"algorand-mainnet","explorer_url":"https://allo.info/account/G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","tracked":true,"window_days":30,"current":{"score":97.4,"grade":"A+","provisional":false,"tier":"settling","uptime_pct_7d":99.8,"uptime_pct_30d":99.5,"latency_p50_ms":118.0,"sample_size":512,"last_probe_at":"2026-08-09T23:45:00"},"series":[{"day":"2026-08-09","sample_count":24,"ok_count":24,"uptime_pct":100.0,"latency_avg_ms":121.4,"latency_min_ms":98.0,"latency_max_ms":210.0,"score_avg":97.4,"score_min":97.1,"score_max":97.8,"grade":"A+","meta":{"coverage":"partial","provenance":{"measurements":"raw","score":"score_table"}}}],"backstop":{"queued":false,"note":"merchant is fresh for its probe tier"}}}}},"404":{"description":"The address is not tracked by LEGIT: an honest 404, never an invented series."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"Payment required: the body is an x402 PaymentRequired document (x402Version, error, resource, accepts) listing the USDC payment offers for every active rail; retry with a payment payload.","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.004"},"protocols":[{"x402":{}}]}}},"/v1/watch":{"post":{"summary":"Set a webhook-armed 7- or 30-day watch sentinel that fires on grade transitions","description":"Put a sentinel on one x402 merchant for 7 or 30 days.\n\nThe optional ``days`` field selects the duration tier: 7 (the\ndiagnostic tier) or 30 (the standard, also the default when days is\nomitted, overridable operator-side via LEGIT_WATCH_TTL_DAYS). The\ntier is a duration only: the 7-day diagnostic tier pays the same\nrail price as the 30-day watch; differentiated pricing requires a\npayments.py change (sealed).\n\nAfter every indexing cycle LEGIT compares the merchant's freshest\ntrust score and probe outcome against the watch's recorded state and\nrecords the real transitions: grade changes, score drops beyond the\nLEGIT_WATCH_SCORE_DROP threshold (default 10 points), outages (3 or\nmore probes attempted with zero successes) and recoveries. The\nreturned watch id is the bearer capability: whoever holds it reads\nstatus and the newest-first event feed FREE at\n/v1/watches/{watch_id} and /v1/watches/{watch_id}/events. Pass an\nhttps webhook_url to have every event POSTed to your agent the moment\nit fires (best effort, never retried). Untracked addresses get an\nhonest 404 with a pointer to /v1/check; when the active-watch cap is\nreached the answer is an honest 409, never a silently dropped watch. Paid: $0.004 on Algorand / $0.005 on Base, via x402 (per call in USDC on algorand-mainnet or base-mainnet; the 402 response lists every active rail). The POST /v1/watch 7-day diagnostic tier pays the same per-call rail price as the 30-day watch.","operationId":"create_watch_v1_watch_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","minLength":1,"maxLength":300,"description":"Merchant address to put a sentinel on. Untracked addresses are an honest 404 with a /v1/check pointer.","example":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"},"days":{"type":"integer","enum":[7,30],"description":"Optional duration tier: 7 (diagnostic) or 30 (standard, the default when omitted). Both tiers pay the same per-call rail price; the tier only sets the watch expiry.","example":30},"webhook_url":{"type":"string","maxLength":2000,"description":"Optional https:// URL: every watch event is POSTed to it the moment it fires (best effort, never retried).","example":"https://agent.example/hooks/legit"}},"required":["address"]},"examples":{"plain_watch":{"summary":"Watch one merchant, poll the free event feed","value":{"address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A"}},"webhook_watch":{"summary":"Watch one merchant with an https webhook","value":{"address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","webhook_url":"https://agent.example/hooks/legit"}},"diagnostic_watch":{"summary":"Watch one merchant for the 7-day diagnostic tier","value":{"address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","days":7}}}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Watch V1 Watch Post"},"example":{"watch_id":"9f1c2a4b6d8e4f0a1b3c5d7e9f0a1b2c","address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","network":"algorand-mainnet","created_at":"2026-08-10T00:00:00","expires_at":"2026-09-09T00:00:00","ttl_days":30,"webhook_configured":true,"initial":{"score":97.4,"grade":"A+"},"capability":"The watch id is the bearer capability: read status and events FREE at GET /v1/watches/{watch_id} and GET /v1/watches/{watch_id}/events."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"Payment required: the body is an x402 PaymentRequired document (x402Version, error, resource, accepts) listing the USDC payment offers for every active rail; retry with a payment payload.","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.004"},"protocols":[{"x402":{}}]}}},"/v1/watches/{watch_id}":{"get":{"summary":"Read watch status free with the bearer watch id","description":"Watch status, expiry and last known state (FREE).\n\nHonest 404 for an unknown id, including watches the garbage collector\nalready deleted (LEGIT_WATCH_GC_DAYS past expiry).","operationId":"watch_status_v1_watches__watch_id__get","parameters":[{"name":"watch_id","in":"path","required":true,"schema":{"type":"string","title":"Watch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Watch Status V1 Watches  Watch Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/watches/{watch_id}/events":{"get":{"summary":"Read the watch event feed, the source of truth","description":"Newest-first transition events of a watch, capped at 200 (FREE).\n\nEvents stay readable after the watch expires, until the garbage\ncollector deletes the watch and its events LEGIT_WATCH_GC_DAYS past\nexpiry (the read then 404s with the watch).","operationId":"watch_events_v1_watches__watch_id__events_get","parameters":[{"name":"watch_id","in":"path","required":true,"schema":{"type":"string","title":"Watch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Watch Events V1 Watches  Watch Id  Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/v1/deep-check":{"post":{"summary":"Run deep-check due diligence on up to 10 addresses","description":"Bulk due diligence for up to 10 x402 merchants in one call.\n\nEvery tracked address returns the full trust snapshot with the\ncomplete parsed score breakdown, a compact 30-day history (daily\nuptime, average score and modal grade), its rank percentile within\nits own network, first/last seen timestamps and its probe tier.\nUntracked addresses are listed honestly under \"untracked\"; nothing is\nsilently dropped and nothing is invented. Tracked merchants stale for\ntheir probe tier queue an on-demand re-probe each.\n\nWave 40 (La Voce, W5): Base merchants with at least one real USDC\nsettle found by LEGIT's independent eth_getLogs chain scan over the\nlast 7 days carry an additive \"evidence\" block\n({\"base_usdc_settles_7d\": n, \"evidence_source\":\n\"independent_chain_scan\"}). It is omitted for everyone else: absence\nof proof is not proof of absence. Metadata only, never a scoring\ninput; a scan failure omits the field, never an error. Paid: $0.004 on Algorand / $0.005 on Base, via x402 (per call in USDC on algorand-mainnet or base-mainnet; the 402 response lists every active rail). The POST /v1/watch 7-day diagnostic tier pays the same per-call rail price as the 30-day watch.","operationId":"deep_check_v1_deep_check_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"addresses":{"type":"array","items":{"type":"string","maxLength":300},"minItems":1,"maxItems":10,"description":"1 to 10 merchant addresses (LEGIT_DEEP_MAX) for bulk due diligence in one call. Untracked addresses are listed honestly under untracked.","example":["G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","ZQFL2SVFDQDKFAUCCE2WVXH6EF3LRUUJZLKJMDIED56LODOKW23JSKB7NT"]}},"required":["addresses"]},"examples":{"two_addresses":{"summary":"Deep-check two merchants before routing","value":{"addresses":["G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","ZQFL2SVFDQDKFAUCCE2WVXH6EF3LRUUJZLKJMDIED56LODOKW23JSKB7NT"]}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Deep Check V1 Deep Check Post"},"example":{"generated_at":"2026-08-10T00:00:00","max_addresses":10,"entries":[{"address":"G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","name":"AlgoPay Gateway","network":"algorand-mainnet","explorer_url":"https://allo.info/account/G7V7U7H6IYRP7BIZO2KV6ODGQPESMMRDCWBYT3GIMNHTNK3VCKWSSKD55A","tracked":true,"score":97.4,"grade":"A+","provisional":false,"breakdown":{"uptime_pct":99.8,"latency_p50_ms":118.0,"sample_size":512,"provisional":false},"tier":"settling","rank_percentile":92.3,"network_size":14,"first_seen":"2026-06-01T12:00:00","last_seen":"2026-08-09T23:45:00","last_probe_at":"2026-08-09T23:45:00","series":[{"day":"2026-08-09","sample_count":24,"uptime_pct":100.0,"score_avg":97.4,"grade":"A+"}]}],"untracked":["UNKNOWN_ADDRESS"]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"Payment required: the body is an x402 PaymentRequired document (x402Version, error, resource, accepts) listing the USDC payment offers for every active rail; retry with a payment payload.","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.004"},"protocols":[{"x402":{}}]}}},"/v1/referee/reproduce.py":{"get":{"summary":"Referee Reproduce Script","description":"The standalone referee reproduction script (stdlib + httpx) as a\ndownloadable artifact: the exact code that re-derives every published\nflag from the public chain indexer independently. An honest 404 when\nthe deployment ships without the script.","operationId":"referee_reproduce_script_v1_referee_reproduce_py_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[]}},"/v1/referee":{"get":{"summary":"Referee Report","description":"The referee audit as JSON: methodology, thresholds, limitations,\nper-merchant verdicts with their real chain evidence. The top-level\n``reproduce_script`` points at the standalone script that re-derives\nevery flag independently.","operationId":"referee_report_v1_referee_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Referee Report V1 Referee Get"}}}}},"security":[]}}},"components":{"schemas":{"BatchCheckRequest":{"properties":{"addresses":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Addresses"}},"type":"object","required":["addresses"],"title":"BatchCheckRequest","description":"POST /v1/batch-check body: 1..20 addresses, each validated like /v1/check."},"BatchReport":{"properties":{"generated_at":{"type":"string","title":"Generated At"},"results":{"items":{"$ref":"#/components/schemas/TrustReportLite"},"type":"array","title":"Results"},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["generated_at","results"],"title":"BatchReport"},"CompareEntry":{"properties":{"address":{"type":"string","title":"Address"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grade"},"provisional":{"type":"boolean","title":"Provisional","default":false},"uptime_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Uptime Pct"},"latency_p50_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latency P50 Ms"},"sample_size":{"type":"integer","title":"Sample Size","default":0},"settle_count":{"type":"integer","title":"Settle Count","default":0},"network":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Network"},"explorer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explorer Url"},"tracked":{"type":"boolean","title":"Tracked","default":true}},"type":"object","required":["address"],"title":"CompareEntry","description":"TrustReport-like summary of one address in a comparison."},"CompareResponse":{"properties":{"generated_at":{"type":"string","title":"Generated At"},"entries":{"items":{"$ref":"#/components/schemas/CompareEntry"},"type":"array","title":"Entries"},"winner":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winner"},"rationale":{"type":"string","title":"Rationale"}},"type":"object","required":["generated_at","entries","rationale"],"title":"CompareResponse"},"DeepCheckRequest":{"properties":{"addresses":{"items":{"type":"string"},"type":"array","title":"Addresses"}},"type":"object","required":["addresses"],"title":"DeepCheckRequest","description":"POST /v1/deep-check body: up to LEGIT_DEEP_MAX addresses."},"DeepReport":{"properties":{"address":{"type":"string","title":"Address"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"score":{"type":"number","title":"Score"},"grade":{"type":"string","title":"Grade"},"breakdown":{"$ref":"#/components/schemas/ScoreBreakdown"},"history":{"items":{"$ref":"#/components/schemas/ScorePoint"},"type":"array","title":"History"},"rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rank"},"percentile":{"type":"number","title":"Percentile","default":0.0},"networks_served":{"items":{"type":"string"},"type":"array","title":"Networks Served"},"generated_at":{"type":"string","title":"Generated At"},"measurement_window_days":{"type":"integer","title":"Measurement Window Days","default":30},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["address","score","grade","breakdown","generated_at"],"title":"DeepReport","description":"Deep trust report for one merchant (SPEC_V2 contract)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Leaderboard":{"properties":{"generated_at":{"type":"string","title":"Generated At"},"entries":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Entries"},"networks":{"items":{"type":"string"},"type":"array","title":"Networks"},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["generated_at","entries"],"title":"Leaderboard"},"LeaderboardEntry":{"properties":{"rank":{"type":"integer","title":"Rank"},"rank_global":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rank Global"},"address":{"type":"string","title":"Address"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"score":{"type":"number","title":"Score"},"grade":{"type":"string","title":"Grade"},"latency_p50_ms":{"type":"number","title":"Latency P50 Ms"},"uptime_pct":{"type":"number","title":"Uptime Pct"},"sample_size":{"type":"integer","title":"Sample Size"},"network":{"type":"string","title":"Network"},"source":{"type":"string","title":"Source","default":"goplausible"},"settle_count":{"type":"integer","title":"Settle Count","default":0},"verify_count":{"type":"integer","title":"Verify Count","default":0},"adoption":{"type":"number","title":"Adoption","default":0.0},"payments_observed":{"type":"boolean","title":"Payments Observed","default":false},"provisional":{"type":"boolean","title":"Provisional","default":false},"explorer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explorer Url"},"external_calls_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"External Calls 30D"},"external_payers_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"External Payers 30D"},"external_demand_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Demand Source"},"intel_avg_ticket":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Intel Avg Ticket"},"intel_verifies":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel Verifies"},"intel_first_seen":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel First Seen"},"intel_last_seen":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel Last Seen"},"intel_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intel Source"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"settles_7d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Settles 7D"},"volume_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Volume 7D"},"demo":{"type":"boolean","title":"Demo","default":false},"dormant":{"type":"boolean","title":"Dormant","default":false}},"type":"object","required":["rank","address","score","grade","latency_p50_ms","uptime_pct","sample_size","network"],"title":"LeaderboardEntry"},"ReceiptEntry":{"properties":{"txid":{"type":"string","title":"Txid"},"payer":{"type":"string","title":"Payer"},"amount_usd":{"type":"number","title":"Amount Usd"},"ts":{"type":"string","title":"Ts"},"network":{"type":"string","title":"Network"}},"type":"object","required":["txid","payer","amount_usd","ts","network"],"title":"ReceiptEntry","description":"Wave 46 (L'Arbitro Verificato): one on-chain payment receipt.\n\nA real settlement observed on a public chain indexer: the payer, the\namount in USD (amount_micro / 1e6), the naive-UTC timestamp, the\nnetwork slug and the on-chain transaction id as evidence. Never\nfabricated: only rows the indexer worker's chain-receipts pass wrote."},"ReceiptsResponse":{"properties":{"address":{"type":"string","title":"Address"},"network":{"type":"string","title":"Network"},"window_days":{"type":"integer","title":"Window Days","default":30},"generated_at":{"type":"string","title":"Generated At"},"provenance":{"type":"string","title":"Provenance","default":"algorand_indexer"},"verified_payers_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Verified Payers 30D"},"top_payer_share_30d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top Payer Share 30D"},"total_receipts":{"type":"integer","title":"Total Receipts"},"volume_usd":{"type":"number","title":"Volume Usd"},"receipts":{"items":{"$ref":"#/components/schemas/ReceiptEntry"},"type":"array","title":"Receipts"}},"type":"object","required":["address","network","generated_at","total_receipts","volume_usd"],"title":"ReceiptsResponse","description":"Wave 46 (L'Arbitro Verificato): the 30-day receipt ledger of one\ntracked merchant (GET /v1/receipts?address=ADDR).\n\n``verified_payers_30d`` is omitted entirely (never null) when no\nchain scan has covered the merchant yet; ``receipts`` is newest-first\nand capped at 100 entries while ``total_receipts`` and ``volume_usd``\nalways cover the full 30-day window. An empty window is an honest\nempty answer (total_receipts 0, receipts []), never invented rows."},"RouteResponse":{"properties":{"query":{"type":"string","title":"Query"},"chosen":{"anyOf":[{"$ref":"#/components/schemas/LeaderboardEntry"},{"type":"null"}]},"alternatives":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Alternatives"},"payment_hint":{"type":"object","title":"Payment Hint"},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["query","payment_hint"],"title":"RouteResponse"},"ScoreBreakdown":{"properties":{"uptime_pct":{"type":"number","title":"Uptime Pct"},"latency_p50_ms":{"type":"number","title":"Latency P50 Ms"},"success_rate":{"type":"number","title":"Success Rate"},"coherence":{"type":"number","title":"Coherence"},"sample_size":{"type":"integer","title":"Sample Size"},"score":{"type":"number","title":"Score"},"grade":{"type":"string","title":"Grade"},"explanation":{"items":{"type":"string"},"type":"array","title":"Explanation"},"adoption":{"type":"number","title":"Adoption","default":0.0},"provisional":{"type":"boolean","title":"Provisional","default":false}},"type":"object","required":["uptime_pct","latency_p50_ms","success_rate","coherence","sample_size","score","grade"],"title":"ScoreBreakdown"},"ScorePoint":{"properties":{"ts":{"type":"string","title":"Ts"},"score":{"type":"number","title":"Score"}},"type":"object","required":["ts","score"],"title":"ScorePoint","description":"One historical score snapshot."},"Stats":{"properties":{"merchants":{"type":"integer","title":"Merchants"},"merchants_testnet":{"type":"integer","title":"Merchants Testnet","default":0},"merchants_mainnet":{"type":"integer","title":"Merchants Mainnet","default":0},"merchants_active":{"type":"integer","title":"Merchants Active","default":0},"measurements":{"type":"integer","title":"Measurements"},"avg_score":{"type":"number","title":"Avg Score"},"storage":{"$ref":"#/components/schemas/StorageInfo"}},"type":"object","required":["merchants","measurements","avg_score","storage"],"title":"Stats"},"StorageInfo":{"properties":{"path":{"type":"string","title":"Path"},"persistent":{"type":"boolean","title":"Persistent"},"db_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Db Bytes"},"retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retention Days"},"tables":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Tables"},"tables_bytes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tables Bytes"}},"type":"object","required":["path","persistent"],"title":"StorageInfo","description":"Wave 8.6: verifiable storage facts (resolved SQLite path + whether it\nlives on the persistent volume).\n\nWave 40 (The Diet): disk observability -- ``db_bytes`` is the\non-disk size of the DB file (null when unreadable) and\n``retention_days`` the raw-measurement retention window actually in\nforce (older history survives as daily rollups, not raw rows).\n\nWave 41 (La Bellezza, W6): growth introspection -- ``tables`` maps\neach main table to its real row count (plus ``bytes`` when SQLite's\ndbstat virtual table is compiled in). ``tables_bytes`` names the\nbytes source (\"dbstat\") or is null, in which case entries honestly\ncarry row counts only.\n\nWave 43 (La Grande Dieta, D5): table entries additionally carry\n``index_bytes`` (that table's index pages via dbstat, additive) when\ndbstat is available -- ``bytes`` alone under-reported the real\non-disk cost per table by 1.4x-2.9x."},"Trending":{"properties":{"generated_at":{"type":"string","title":"Generated At"},"trending":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Trending"},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["generated_at","trending"],"title":"Trending"},"TrustReport":{"properties":{"address":{"type":"string","title":"Address"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"score":{"type":"number","title":"Score"},"grade":{"type":"string","title":"Grade"},"breakdown":{"$ref":"#/components/schemas/ScoreBreakdown"},"generated_at":{"type":"string","title":"Generated At"},"anchored_tx":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Anchored Tx"},"provisional":{"type":"boolean","title":"Provisional","default":false},"explorer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explorer Url"},"external_calls_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"External Calls 30D"},"external_payers_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"External Payers 30D"},"external_demand_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Demand Source"},"intel_avg_ticket":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Intel Avg Ticket"},"intel_verifies":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel Verifies"},"intel_first_seen":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel First Seen"},"intel_last_seen":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Intel Last Seen"},"intel_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intel Source"},"probe_queue":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Probe Queue"},"evidence":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Evidence"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"routing_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Routing Confidence"},"verified_payers_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Verified Payers 30D"},"receipts_provenance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Receipts Provenance"},"top_payer_share_30d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top Payer Share 30D"},"referee_flag":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Referee Flag"},"referee_verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referee Verdict"}},"type":"object","required":["address","score","grade","breakdown","generated_at"],"title":"TrustReport"},"TrustReportLite":{"properties":{"address":{"type":"string","title":"Address"},"score":{"type":"number","title":"Score"},"grade":{"type":"string","title":"Grade"},"latency_p50_ms":{"type":"number","title":"Latency P50 Ms"},"uptime_pct":{"type":"number","title":"Uptime Pct"},"demo":{"type":"boolean","title":"Demo","default":false}},"type":"object","required":["address","score","grade","latency_p50_ms","uptime_pct"],"title":"TrustReportLite","description":"Compact per-address result inside a BatchReport."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WatchCreateRequest":{"properties":{"address":{"type":"string","maxLength":300,"minLength":1,"title":"Address"},"days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Webhook Url"}},"type":"object","required":["address"],"title":"WatchCreateRequest","description":"POST /v1/watch body: one tracked address, an optional duration\ntier and an optional https webhook.\n\n``days`` selects the duration tier (7-day diagnostic or 30-day\nstandard; omitted means the LEGIT_WATCH_TTL_DAYS default of 30).\nThe tier only sets expires_at: the 7-day diagnostic tier pays the\nsame rail price as the 30-day watch; differentiated pricing\nrequires a payments.py change (sealed)."}}}}