{"openapi":"3.1.0","info":{"title":"TokenPrices API","version":"1.2.0","summary":"Onchain token prices computed directly from DEX liquidity.","description":"Chain- and contract-specific USD prices computed from raw DEX pool state read via JSON-RPC at a\npinned, finality-tagged block (EVM chains), a finalized slot (Solana) or a closed (final) ledger (Stellar). Every response identifies the pool route, block, basis and quality.\nWhen a price cannot be qualified, `price_usd` is `null` and `reason` explains why (HTTP 200).\nPrices and large numbers are decimal strings; times are ISO 8601 UTC. JSON bodies are served as\n`Content-Type: application/json; charset=utf-8`.\n\nAddresses: EVM chains take 20-byte hex (any case, normalized to lowercase) and return EIP-55 token\naddresses and lowercase pool ids. Solana takes and returns base58 public keys exactly (case-sensitive,\nnever transformed). Stellar takes a Soroban contract id (`C…`, any case), a classic asset as `CODE:ISSUER`\n(or `CODE-ISSUER`, `native`/`XLM`), or a classic liquidity-pool id (64 hex); classic assets resolve to their\nStellar Asset Contract id, which is what every response returns (upper case). An address of the wrong family for\nthe chain is 400 `INVALID_ADDRESS`.\n\nEvery `/v1/*` response that passed the rate limiter (successes, 400/404/5xx errors and 429) carries\n`RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`; a 429 adds `Retry-After`. Only 405,\nOPTIONS preflights and 401 `INVALID_API_KEY` (rejected before counting) omit them.\n","license":{"name":"Proprietary"}},"servers":[{"url":"https://api.tokenprices.xyz","description":"Production"},{"url":"http://127.0.0.1:8788","description":"Local wrangler dev"}],"security":[{},{"ApiKey":[]}],"tags":[{"name":"meta"},{"name":"prices"},{"name":"catalogue"}],"paths":{"/v1/health":{"get":{"tags":["meta"],"operationId":"getHealth","summary":"Service and sampler health","responses":{"200":{"description":"Healthy or degraded","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"description":"Database unavailable (status down). Never SERVICE_PAUSED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthDownResponse"}}}}}}},"/v1/chains":{"get":{"tags":["catalogue"],"operationId":"listChains","summary":"Supported chains with anchors, protocols and last sample","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChainsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}":{"get":{"tags":["prices"],"operationId":"getPrices","summary":"Batch prices for up to 50 contracts, or every sampled token on the chain (paginated)","description":"Two modes, both one database read, both costing **5 rate-limit units**:\n\n- **Batch** (`contracts` given): up to 50 comma-separated addresses, validated for the chain's family\n  (EVM hex in any case, normalized to lowercase; Solana base58 exactly). `prices` has one item per\n  requested address, **in request order** (duplicates kept). Unknown addresses are included with\n  `quality: UNSUPPORTED_TOKEN`. `limit` and `offset` are `null`; `total` is the number of items.\n- **List** (no `contracts`): every active token on the chain that has been sampled at least once,\n  ordered by canonical address, paginated by `limit` (≤ 200, default 100) and `offset`; `total` is the\n  number of such tokens. A dashboard can refresh every chain with one request per chain.\n\nEach item is exactly the `getPrice` response for that address with the same `mode`, `notional_usd`,\n`min_quality`, `allow_stale` and `finality`.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"name":"contracts","in":"query","description":"Comma-separated addresses (1–50, no empty items). An invalid item is 400 `INVALID_ADDRESS` with `details.param = contracts` and `details.index`; more than 50 is 400 `INVALID_PARAMETER`.","schema":{"type":"string"},"example":"0x4200000000000000000000000000000000000006,0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},{"name":"mode","in":"query","schema":{"type":"string","enum":["spot","indicative"],"default":"spot"}},{"$ref":"#/components/parameters/NotionalUsd"},{"$ref":"#/components/parameters/MinQuality"},{"name":"allow_stale","in":"query","schema":{"type":"boolean","default":false}},{"$ref":"#/components/parameters/Finality"},{"name":"limit","in":"query","description":"List mode only (ignored with `contracts`).","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"offset","in":"query","description":"List mode only (ignored with `contracts`).","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}}],"responses":{"200":{"description":"Price items (each a `PriceResponse`).","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}/{contract}":{"get":{"tags":["prices"],"operationId":"getPrice","summary":"Current spot or indicative USD price for a token","description":"`finality=latest` (default) serves the real-time engine's newest snapshot (EVM `latest`, Solana `confirmed`);\n`as_of.age_ms` says how old the block is and `as_of.source` where the price came from (`stream`/`poll`:\nengine; `snapshot`/`sampler`: database fallback, flagged `REALTIME_DEGRADED`). `finality=safe` serves the\ncron sampler's `safe`/`finalized` row (`as_of.source = sampler`). Cache: `max-age=1` for `latest`,\n`max-age=30, stale-while-revalidate=60` for `safe`.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"$ref":"#/components/parameters/Finality"},{"name":"mode","in":"query","schema":{"type":"string","enum":["spot","indicative"],"default":"spot"}},{"$ref":"#/components/parameters/NotionalUsd"},{"$ref":"#/components/parameters/MinQuality"},{"name":"allow_stale","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Price response. `price_usd` is null when the token is unsupported, unpriceable, below\n`min_quality`, or stale (without `allow_stale`).\n","headers":{"Server-Timing":{"$ref":"#/components/headers/ServerTiming"},"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceResponse"},"examples":{"qualified":{"summary":"Base WETH (live shape; anchors that are not USD-pegged carry no USD_PEG_ASSUMED)","value":{"chain":"base","contract":"0x4200000000000000000000000000000000000006","symbol":"WETH","asset_id":"crypto:ETH","asset_class":"crypto","mode":"spot","price_usd":"3012.4","currency":"USD","basis":"onchain_spot","quality":"QUALIFIED","reason":null,"reasons":[],"estimated_usd_anchor":"USDC≈USD","as_of":{"block_number":"56411862","block_hash":"0x069016f3d0e360f3915cb1026eb999b1ea03ef12f1add437ca341a7c24d0d546","timestamp":"2026-11-12T08:39:08Z","observed_at":"2026-11-12T08:41:11Z","age_s":185,"age_ms":308000,"finality":"safe","source":"sampler"},"source":{"protocol":"uniswap-v3","pool":"0x6c561b446416e1a00e8e93e221854d6ea4171372","quote_token":{"symbol":"USDC","address":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},"route":["WETH/USDC"],"hops":[{"pool":"0x6c561b446416e1a00e8e93e221854d6ea4171372","protocol":"uniswap-v3","token_in":"0x4200000000000000000000000000000000000006","token_out":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","fee_ppm":3000}],"fee_ppm":3000,"anchor_peg":{"symbol":"USDC","implied_usd":"0.99994","deviation_bps":-0.6,"status":"ok"}},"depth":{"notional_usd":"100","estimated_cost_bps":30,"liquidity_usd":"83511870.221166"},"shares_per_token":null,"price_usd_per_ui_unit":null,"warnings":[]}},"solana_xstock":{"summary":"Solana Token-2022 ScaledUiAmount stock token (synthetic addresses). price_usd is per 1 whole raw token; price_usd_per_ui_unit = price_usd / shares_per_token.value is per UI unit (what wallets show).","value":{"chain":"solana","contract":"ByiEzw92Qd9BprKRys3XV7YZtD4LcmpEGb9iFHinwtV8","symbol":"XSTKx","asset_id":"equity:US:XSTK","asset_class":"equity","mode":"spot","price_usd":"262.5","currency":"USD","basis":"onchain_spot","quality":"QUALIFIED","reason":null,"reasons":[],"estimated_usd_anchor":"USDC≈USD","as_of":{"block_number":"312345678","block_hash":"7XfRHCaFZx5HSih4GFa5kL8jxVdXo6RLrDdChBQ3LgNT","timestamp":"2026-11-12T08:39:08Z","observed_at":"2026-11-12T08:39:31Z","age_s":120,"age_ms":143000,"finality":"finalized","source":"sampler"},"source":{"protocol":"raydium-cpmm","pool":"FXGgbPYSbpQTTbJQg5VFFjA8QhjwHgV2bMqdvXkNWKx9","quote_token":{"symbol":"USDC","address":"4oMB13ikzEoCTGUZypGd8cD1G843rLM9YvuzXekKcjDW"},"route":["XSTKx/USDC"],"hops":[{"pool":"FXGgbPYSbpQTTbJQg5VFFjA8QhjwHgV2bMqdvXkNWKx9","protocol":"raydium-cpmm","token_in":"ByiEzw92Qd9BprKRys3XV7YZtD4LcmpEGb9iFHinwtV8","token_out":"4oMB13ikzEoCTGUZypGd8cD1G843rLM9YvuzXekKcjDW","fee_ppm":2500}],"fee_ppm":2500,"anchor_peg":{"symbol":"USDC","implied_usd":"1.00002","deviation_bps":0.2,"status":"ok"}},"depth":{"notional_usd":"100","estimated_cost_bps":31,"liquidity_usd":"412000.5"},"shares_per_token":{"value":"1.05","source":"onchain","as_of":{"timestamp":"2026-11-12T08:39:08Z","block_number":"312345678"},"next":{"value":"1.1","effective_at":"2026-11-20T00:00:00Z"}},"price_usd_per_ui_unit":"250","warnings":["REBASING_OR_WRAPPED_TOKEN","PERMANENT_DELEGATE","PAUSABLE","MULTIPLIER_CHANGE_PENDING"]}},"unsupported":{"value":{"chain":"base","contract":"0x000000000000000000000000000000000000dead","symbol":null,"asset_id":null,"asset_class":null,"mode":"spot","price_usd":null,"currency":"USD","basis":null,"quality":"UNSUPPORTED_TOKEN","reason":"TOKEN_NOT_IN_REGISTRY","reasons":["TOKEN_NOT_IN_REGISTRY"],"estimated_usd_anchor":null,"as_of":null,"source":null,"depth":null,"shares_per_token":null,"price_usd_per_ui_unit":null,"warnings":[]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}/{contract}/history":{"get":{"tags":["prices"],"operationId":"getPriceHistory","summary":"Stored price history: 5m samples, 1h/1d OHLC bars (live and archive backfill)","description":"One database read, 5 rate-limit units. Maximum range per request: `5m` ≤ 7 days (2,016 points),\n`1h` ≤ 90 days (2,160 points; page with `from`/`to` to reach the stored year), `1d` ≤ 2,190 days. A larger\nrange is 400 `INVALID_PARAMETER` naming the limit. Default `from`: `to − 24h` (5m), `to − 7d` (1h),\n`to − 365d` (1d); for 1h/1d `from` is floored to the interval. An unknown token is 200 with no points.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"name":"from","in":"query","description":"ISO 8601 UTC or unix seconds. Default `to - 24h`.","schema":{"type":"string"}},{"name":"to","in":"query","description":"ISO 8601 UTC or unix seconds. Default now.","schema":{"type":"string"}},{"name":"interval","in":"query","description":"`5m` samples (O=H=L=C), or `1h`/`1d` OHLC bars. Max range: 7 days (5m), 90 days (1h), 2,190 days (1d).","schema":{"type":"string","enum":["5m","1h","1d"],"default":"5m"}},{"$ref":"#/components/parameters/MinQuality"}],"responses":{"200":{"description":"History (possibly empty)","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}/{contract}/chart":{"get":{"tags":["prices"],"operationId":"getPriceChart","summary":"Fixed-range chart series (history at the range's natural interval)","description":"`24h` → 5m (288 points), `7d` → 1h (168), `30d` → 1h (720), `90d` → 1h (2,160), `1y` → 1d (365),\n`max` → 1d from the first daily bar (≤ 2,190). Same query, serializer and rate cost (5 units) as history;\nthe response is `HistoryResponse` plus `range`.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"name":"range","in":"query","schema":{"type":"string","enum":["24h","7d","30d","90d","1y","max"],"default":"7d"}},{"$ref":"#/components/parameters/MinQuality"}],"responses":{"200":{"description":"Chart series (possibly empty)","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}/{contract}/depth":{"get":{"tags":["prices"],"operationId":"getPriceDepth","summary":"Order-book-style depth of a token's DEX liquidity (cumulative bids/asks over ±range%) and an impact ladder","description":"AMM liquidity, not resting orders: liquidity providers can add or withdraw at any time. For each of `buckets`\nprice levels per side over ±`range`% around the served USD price, the cumulative amount of the token the\npools absorb (bids, price falling) or release (asks, price rising), and its USD value at each pool's quote-token\nspot. Exact swap maths per pool (constant product, concentrated liquidity over initialized ticks, DLMM bins),\nsummed as an optimal router splits a trade. `impact` gives the fee-inclusive trade size that moves the price\n0.5 / 1 / 2 / 5%. A level whose `complete` is false is a lower bound (a pool's tick map ends before it).\n5 rate-limit units. Served by the real-time engine; when it is unavailable the last stored default book\n(`range=10`, `buckets=50`) is served with `REALTIME_DEGRADED` and `served_range_pct` / `served_buckets`;\nwith neither, 404 with `error.details.reason = DEPTH_UNAVAILABLE`. A token below `min_quality` is 200 with\nempty `bids` / `asks` / `pools` and `reason`.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"name":"range","in":"query","description":"Half-width of the book in percent (0.1 … 20, at most one decimal).","schema":{"type":"string","pattern":"^[0-9]{1,2}(\\.[0-9])?$","default":"10"}},{"name":"buckets","in":"query","description":"Price levels per side.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"min_quality","in":"query","description":"Quality gate for the token's price (default `indicative` for depth).","schema":{"type":"string","enum":["qualified","indicative"],"default":"indicative"}}],"responses":{"200":{"description":"Depth book (possibly empty when gated)","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepthResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/prices/{chain}/{contract}/ticks":{"get":{"tags":["prices"],"operationId":"getPriceTicks","summary":"Recent per-swap (EVM) / per-state (Solana) price ticks from the real-time engine (≤ 60 min)","description":"Memory-only and best effort: a restart of the real-time engine empties its ring, and `coverage.from` then\nstarts at the oldest tick held. 5 rate-limit units. A token below `min_quality` is 200 with `ticks: []`\nand `reason`; when the engine is unavailable it is 200 with `ticks: []` and `reason: ENGINE_UNAVAILABLE`.\nSolana ticks have `kind: state`, `log_index: null`, `tx_hash: null`.\n","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"name":"since","in":"query","description":"ISO 8601 UTC or unix seconds; default now − 10 min; must be within the last 60 minutes.","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"$ref":"#/components/parameters/MinQuality"}],"responses":{"200":{"description":"Ticks (possibly empty)","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicksResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Internal"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/pools":{"get":{"tags":["catalogue"],"operationId":"listPools","summary":"Registered pools with their latest evaluated state (active pools unless include_inactive=true)","parameters":[{"name":"chain","in":"query","required":true,"schema":{"$ref":"#/components/schemas/ChainKey"}},{"name":"token","in":"query","schema":{"$ref":"#/components/schemas/AddressInput"}},{"name":"protocol","in":"query","schema":{"$ref":"#/components/schemas/Protocol"}},{"name":"eligible_only","in":"query","schema":{"type":"boolean","default":false}},{"name":"include_inactive","in":"query","description":"Also list pools with `active: false` (seeded but not sampled, e.g. hooked v4 pools or pools over the per-chain cap). Default `false`: active pools only, so `total` matches `/v1/chains` `counts.pools`.","schema":{"type":"boolean","default":false}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/assets":{"get":{"tags":["catalogue"],"operationId":"listAssets","summary":"Curated asset directory (may be broader than priceable tokens)","parameters":[{"name":"type","in":"query","deprecated":true,"description":"Filter by the deprecated `asset_type` alias; prefer `class`.","schema":{"type":"string","pattern":"^[a-z_]{1,32}$"}},{"name":"class","in":"query","description":"Filter by `asset_class`.","schema":{"$ref":"#/components/schemas/AssetClass"}},{"name":"tokenized","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"form","in":"query","schema":{"$ref":"#/components/schemas/AssetForm"}},{"name":"issuer","in":"query","schema":{"type":"string","maxLength":64}},{"name":"q","in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/assets/{id}":{"get":{"tags":["catalogue"],"operationId":"getAsset","summary":"One curated asset with its tokens","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9:._@-]{1,96}$"}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/tokens/search":{"get":{"tags":["catalogue"],"operationId":"searchTokens","summary":"Search curated tokens by address, symbol, name or asset ticker","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"chain","in":"query","schema":{"$ref":"#/components/schemas/ChainKey"}},{"name":"class","in":"query","description":"Only tokens whose asset has this `asset_class`.","schema":{"$ref":"#/components/schemas/AssetClass"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenSearchResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/tokens/{chain}/{contract}":{"get":{"tags":["catalogue"],"operationId":"getToken","summary":"Token metadata, price summary and pools","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenDetailResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/icons/chain/{chain}":{"get":{"tags":["catalogue"],"operationId":"getChainIcon","summary":"Icon of a chain","description":"One entity's icon (`{kind, id, icon}`), or with `redirect=1` a 302 to the WebP image on the icons host (`size` 32, 64 or 128; default 64; the largest available size when the requested one does not exist). 1 rate unit, `Cache-Control: public, max-age=3600`. For many icons at once use the catalogue `icon` fields or the static `manifest.json` on the icons host. 404 `NOT_FOUND` when the entity has no icon.","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/IconRedirect"},{"$ref":"#/components/parameters/IconSize"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IconResponse"}}}},"302":{"description":"`redirect=1`: the image URL on the icons host.","headers":{"Location":{"description":"Image URL","schema":{"type":"string","format":"uri"}},"Cache-Control":{"$ref":"#/components/headers/CacheControl"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/icons/protocol/{protocol}":{"get":{"tags":["catalogue"],"operationId":"getProtocolIcon","summary":"Icon of a DEX protocol","description":"One entity's icon (`{kind, id, icon}`), or with `redirect=1` a 302 to the WebP image on the icons host (`size` 32, 64 or 128; default 64; the largest available size when the requested one does not exist). 1 rate unit, `Cache-Control: public, max-age=3600`. For many icons at once use the catalogue `icon` fields or the static `manifest.json` on the icons host. 404 `NOT_FOUND` when the entity has no icon.","parameters":[{"name":"protocol","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Protocol"}},{"$ref":"#/components/parameters/IconRedirect"},{"$ref":"#/components/parameters/IconSize"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IconResponse"}}}},"302":{"description":"`redirect=1`: the image URL on the icons host.","headers":{"Location":{"description":"Image URL","schema":{"type":"string","format":"uri"}},"Cache-Control":{"$ref":"#/components/headers/CacheControl"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/icons/asset/{id}":{"get":{"tags":["catalogue"],"operationId":"getAssetIcon","summary":"Icon of a curated asset","description":"One entity's icon (`{kind, id, icon}`), or with `redirect=1` a 302 to the WebP image on the icons host (`size` 32, 64 or 128; default 64; the largest available size when the requested one does not exist). 1 rate unit, `Cache-Control: public, max-age=3600`. For many icons at once use the catalogue `icon` fields or the static `manifest.json` on the icons host. 404 `NOT_FOUND` when the entity has no icon.","parameters":[{"name":"id","in":"path","required":true,"description":"Asset id, URL-encoded (e.g. `equity%3AUS%3AAAPL%40xstocks`).","schema":{"type":"string","pattern":"^[A-Za-z0-9:._@-]{1,96}$"}},{"$ref":"#/components/parameters/IconRedirect"},{"$ref":"#/components/parameters/IconSize"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IconResponse"}}}},"302":{"description":"`redirect=1`: the image URL on the icons host.","headers":{"Location":{"description":"Image URL","schema":{"type":"string","format":"uri"}},"Cache-Control":{"$ref":"#/components/headers/CacheControl"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/v1/icons/token/{chain}/{contract}":{"get":{"tags":["catalogue"],"operationId":"getTokenIcon","summary":"Icon of a token","description":"One entity's icon (`{kind, id, icon}`), or with `redirect=1` a 302 to the WebP image on the icons host (`size` 32, 64 or 128; default 64; the largest available size when the requested one does not exist). 1 rate unit, `Cache-Control: public, max-age=3600`. For many icons at once use the catalogue `icon` fields or the static `manifest.json` on the icons host. 404 `NOT_FOUND` when the entity has no icon.","parameters":[{"$ref":"#/components/parameters/ChainPath"},{"$ref":"#/components/parameters/ContractPath"},{"$ref":"#/components/parameters/IconRedirect"},{"$ref":"#/components/parameters/IconSize"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IconResponse"}}}},"302":{"description":"`redirect=1`: the image URL on the icons host.","headers":{"Location":{"description":"Image URL","schema":{"type":"string","format":"uri"}},"Cache-Control":{"$ref":"#/components/headers/CacheControl"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServicePaused"}}}},"/openapi.json":{"get":{"tags":["meta"],"operationId":"getOpenApi","summary":"This OpenAPI document as JSON","responses":{"200":{"description":"This document as JSON","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Optional. Raises the rate limit from 60 to the key's limit (default 600 units/min)."}},"headers":{"CacheControl":{"schema":{"type":"string"},"description":"See 04-api.md §1.1"},"RequestId":{"schema":{"type":"string"}},"RateLimitLimit":{"schema":{"type":"integer"},"description":"Rate units allowed per 60 s window for this caller (anonymous per IP, or the API key's limit). Sent on every rate-limited /v1 response."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Units left in the current window. Sent on every rate-limited /v1 response."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until the window resets. Sent on every rate-limited /v1 response."},"RetryAfter":{"schema":{"type":"integer"},"description":"Seconds until the caller may retry (429), or until the service resumes (503 `SERVICE_PAUSED`)."},"ServerTiming":{"schema":{"type":"string"},"description":"`engine;dur=<ms>, refresh;dur=<ms>` on `finality=latest` responses: time spent in the real-time engine call, and in an inline read-through refresh (0 when the engine snapshot was fresh enough or the isolate micro-cache answered). Observability only."}},"parameters":{"IconRedirect":{"name":"redirect","in":"query","description":"`1` (or `true`): answer 302 to the image instead of JSON.","schema":{"type":"string","enum":["0","1","true","false"]}},"IconSize":{"name":"size","in":"query","description":"Image size in px for `redirect=1` (default 64).","schema":{"type":"string","enum":["32","64","128"]}},"ChainPath":{"name":"chain","in":"path","required":true,"schema":{"$ref":"#/components/schemas/ChainKey"}},"ContractPath":{"name":"contract","in":"path","required":true,"schema":{"$ref":"#/components/schemas/AddressInput"}},"NotionalUsd":{"name":"notional_usd","in":"query","schema":{"type":"integer","enum":[100,1000,10000],"default":100}},"MinQuality":{"name":"min_quality","in":"query","schema":{"type":"string","enum":["qualified","indicative"],"default":"qualified"}},"Finality":{"name":"finality","in":"query","description":"`latest` (default): the real-time engine (EVM `latest` block, Solana `confirmed` slot), with a database fallback flagged `REALTIME_DEGRADED`. `safe`: the cron sampler's `safe`/`finalized` row.","schema":{"type":"string","enum":["latest","safe"],"default":"latest"}},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},"Offset":{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}},"responses":{"BadRequest":{"description":"Invalid parameter, address or notional","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Unsupported chain, unknown route or resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"RateLimited":{"description":"Rate limit exceeded","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Internal":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServicePaused":{"description":"`SERVICE_PAUSED`: the daily usage ceiling was reached (billing circuit breaker, levels `soft`/`hard`); every public operation except `/v1/health` answers 503 until `details.resumes_at` (00:00 UTC) or an operator reset, with `Retry-After` = seconds until then and `details.reason` naming the counter that tripped. The same status is also used for `DB_UNAVAILABLE` (database unreachable; no `Retry-After`). Caching: `SERVICE_PAUSED` is sent with `Cache-Control: public, max-age=60` on purpose (a short shared cache absorbs retry floods while paused); `DB_UNAVAILABLE` and every other 5xx are `no-store`.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"paused":{"value":{"error":{"code":"SERVICE_PAUSED","message":"Daily usage ceiling reached; service resumes at 00:00 UTC","details":{"resumes_at":"2026-11-13T00:00:00Z","reason":"requests"}},"request_id":"4f1c2b7e-0d5a-4c1e-9a77-6b0f0c3a9e21"}}}}}}},"schemas":{"ChainKey":{"type":"string","enum":["ethereum","base","arbitrum","robinhood","bnb","avalanche","solana","stellar"]},"ChainFamily":{"type":"string","enum":["evm","svm","stellar"],"description":"`evm` (Ethereum, Base, Arbitrum, Robinhood Chain, BNB Chain, Avalanche C-Chain), `svm` (Solana) or `stellar` (Stellar pubnet)."},"Protocol":{"type":"string","enum":["uniswap-v2","uniswap-v3","aerodrome-volatile","aerodrome-stable","aerodrome-slipstream","uniswap-v4","pancakeswap-v3","pancakeswap-v2","raydium-amm-v4","raydium-cpmm","raydium-clmm","orca-whirlpool","meteora-dlmm","stellar-classic-amm","aquarius-cp","aquarius-stable","sushi-v3-stellar"]},"AddressInput":{"description":"EVM chains: 20-byte hex (any case). Solana: base58 public key, case-sensitive. Stellar: contract id (C…, any case), classic asset `CODE:ISSUER` / `CODE-ISSUER` / `native` / `XLM`, or a classic pool id (64 hex). The chain decides which form is valid.","oneOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"},{"type":"string","pattern":"^[Cc][A-Za-z2-7]{55}$"},{"type":"string","pattern":"^([A-Za-z0-9]{1,12}[:-][Gg][A-Za-z2-7]{55}|native|XLM|xlm)$"},{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}]},"Address":{"description":"EVM: EIP-55 checksummed (tokens) or lowercase hex. Solana: base58 public key exactly as stored (case-sensitive). Stellar: the token's Soroban contract id (classic assets: their Stellar Asset Contract id), upper case.","oneOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"},{"type":"string","pattern":"^C[A-Z2-7]{55}$"}]},"PoolId":{"description":"EVM: pool contract address (lowercase), or for uniswap-v4 the bytes32 PoolId (no pool contract exists). Solana: the pool account's base58 public key, exact. Stellar: the pool contract id (Soroban AMMs, upper case) or the classic liquidity-pool id (64 lowercase hex).","oneOf":[{"type":"string","pattern":"^0x([0-9a-fA-F]{40}|[0-9a-f]{64})$"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"},{"type":"string","pattern":"^(C[A-Z2-7]{55}|[0-9a-f]{64})$"}]},"BlockHash":{"description":"EVM lowercase 0x block hash; Solana base58 blockhash (exact); Stellar ledger hash (64 lowercase hex).","oneOf":[{"type":"string","pattern":"^0x[0-9a-f]{64}$"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"},{"type":"string","pattern":"^[0-9a-f]{64}$"}]},"DecimalString":{"type":"string","pattern":"^(0|[1-9][0-9]*)(\\.[0-9]*[1-9])?$","description":"Non-negative decimal, no exponent, no trailing fractional zeros"},"IntegerString":{"type":"string","pattern":"^(0|[1-9][0-9]*)$"},"Timestamp":{"type":"string","format":"date-time","pattern":"Z$"},"TimestampMs":{"description":"ISO 8601 UTC with milliseconds (`YYYY-MM-DDTHH:MM:SS.sssZ`). Used by the ticks endpoint, whose Solana times are sub-second estimates.","type":"string","format":"date-time","pattern":"\\.\\d{3}Z$"},"QualityStatus":{"type":"string","enum":["QUALIFIED","INDICATIVE_LOW_LIQUIDITY","INDICATIVE_DIVERGENT","INDICATIVE_UNITS_UNVERIFIED","STALE","NO_RELIABLE_MARKET","ANCHOR_UNAVAILABLE","NOT_YET_SAMPLED","UNSUPPORTED_TOKEN"]},"ReasonCode":{"type":"string","enum":["NO_POOLS","NO_ROUTE_TO_ANCHOR","POOL_READ_FAILED","ZERO_LIQUIDITY","LIQUIDITY_BELOW_MINIMUM","LIQUIDITY_BELOW_QUALIFIED","PRICE_IMPACT_TOO_HIGH","PRICE_IMPACT_ABOVE_QUALIFIED","INSUFFICIENT_DEPTH","ANCHOR_UNAVAILABLE","PRICE_OUT_OF_BOUNDS","DIVERGENT_MARKETS","STALE_SAMPLE","BLOCK_TOO_OLD","REORGED","NOT_YET_SAMPLED","TOKEN_NOT_IN_REGISTRY","TOKEN_INACTIVE","CHAIN_INACTIVE","BELOW_MIN_QUALITY","QUOTE_UNAVAILABLE","PROBE_TOO_LARGE","DECODE_ERROR","UNKNOWN_FACTORY","UNKNOWN_PROGRAM","POOL_ACCOUNT_MISMATCH","MINT_READ_FAILED","TOKEN_PAUSED","TRANSFER_HOOK_UNSUPPORTED","TOKEN_EXTENSION_UNSUPPORTED","ANCHOR_DEPEGGED","DEPTH_UNAVAILABLE","ISSUER_AUTH_REQUIRED","ISSUER_READ_FAILED"]},"WarningCode":{"type":"string","enum":["USD_PEG_ASSUMED","ANCHOR_DEPEG_SUSPECTED","QUOTE_UNAVAILABLE","PROVISIONAL_FINALITY","FINALITY_TAG_FALLBACK","REBASING_OR_WRAPPED_TOKEN","STALE_SERVED","INDICATIVE_SERVED","DEPTH_ESTIMATED","TRANSFER_FEE","TRANSFER_HOOK_PRESENT","PERMANENT_DELEGATE","PAUSABLE","MULTIPLIER_CHANGE_PENDING","ANCHOR_PEG_UNVERIFIED","REALTIME_DEGRADED","DEPTH_INCOMPLETE","DEPTH_STALE","AUTH_REVOCABLE","CLAWBACK_ENABLED"]},"Finality":{"type":"string","enum":["finalized","safe","latest","confirmed","confirmations"]},"PoolTier":{"type":"string","enum":["A","B","X"]},"ErrorResponse":{"type":"object","required":["error","request_id"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["INVALID_PARAMETER","INVALID_ADDRESS","UNSUPPORTED_NOTIONAL","INVALID_API_KEY","UNAUTHORIZED","UNSUPPORTED_CHAIN","NOT_FOUND","METHOD_NOT_ALLOWED","RATE_LIMITED","INTERNAL","DB_UNAVAILABLE","SERVICE_PAUSED"]},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}},"request_id":{"type":"string"}}},"AsOf":{"type":"object","description":"The pinned block of the sample. On Solana `block_number` is the slot and `block_hash` the base58 blockhash; every read is at `finalized` commitment, all accounts of a pool are read at the same slot, and pools may differ by a few slots within a run. On Stellar `block_number` is the ledger sequence and `block_hash` the ledger hash: one `getLedgerEntries` call returns every pool at the same closed (final) ledger.","required":["block_number","block_hash","timestamp","observed_at","age_s","finality"],"properties":{"block_number":{"$ref":"#/components/schemas/IntegerString"},"block_hash":{"description":"Null only for `finality=latest` engine prices whose block hash is not known yet (L2 polls, Solana).","oneOf":[{"$ref":"#/components/schemas/BlockHash"},{"type":"null"}]},"timestamp":{"$ref":"#/components/schemas/Timestamp"},"observed_at":{"$ref":"#/components/schemas/Timestamp"},"age_s":{"type":"integer","minimum":0,"description":"Seconds since `observed_at` (when our system read the state); kept for compatibility."},"age_ms":{"type":"integer","minimum":0,"description":"Milliseconds since the block's timestamp (`now − block.timestamp × 1000`). EVM timestamps are whole seconds, so this overstates age by up to 1 s; Solana engine snapshots use an estimated block time (`timestamp_estimated`). Always present on `/v1/prices` responses (with `source`); absent on the price embedded in `/v1/tokens/{chain}/{contract}`, which is the sampler row."},"source":{"type":"string","enum":["stream","poll","snapshot","sampler"],"description":"`stream` (engine, push-fed), `poll` (engine, polled), `snapshot` (database live snapshot; fallback), `sampler` (cron `safe`/`finalized` row; `finality=safe`, or the last fallback)."},"timestamp_estimated":{"type":"boolean","description":"True when `timestamp` / `age_ms` use an estimated block time (Solana engine snapshots)."},"finality":{"$ref":"#/components/schemas/Finality"}}},"SharesPerToken":{"type":"object","description":"Issuer share multiplier: shares of the underlying per 1 whole token (e.g. ERC-8056 `uiMultiplier()` / 1e18 for Robinhood stock tokens). Informational only; it is never applied to `price_usd`, which is already USD per 1 whole token as traded on the DEX. `source: onchain` = read at the price's pinned block (`as_of.block_number` is that block); `source: issuer_metadata` = issuer API snapshot taken at seed time (`as_of.block_number` null).","required":["value","source","as_of"],"properties":{"value":{"$ref":"#/components/schemas/DecimalString"},"source":{"type":"string","enum":["onchain","issuer_metadata"]},"as_of":{"type":"object","required":["timestamp","block_number"],"properties":{"timestamp":{"$ref":"#/components/schemas/Timestamp"},"block_number":{"oneOf":[{"$ref":"#/components/schemas/IntegerString"},{"type":"null"}]}}},"next":{"description":"A pending onchain multiplier change (Solana Token-2022 ScaledUiAmount `new_multiplier` and its effective time), or null when none. Always null for `source: issuer_metadata`.","oneOf":[{"type":"object","required":["value","effective_at"],"properties":{"value":{"$ref":"#/components/schemas/DecimalString"},"effective_at":{"$ref":"#/components/schemas/Timestamp"}}},{"type":"null"}]}}},"TokenRef":{"type":"object","required":["symbol","address"],"properties":{"symbol":{"type":"string"},"address":{"$ref":"#/components/schemas/Address"}}},"Hop":{"type":"object","required":["pool","protocol","token_in","token_out","fee_ppm"],"properties":{"pool":{"$ref":"#/components/schemas/PoolId"},"protocol":{"$ref":"#/components/schemas/Protocol"},"token_in":{"$ref":"#/components/schemas/Address"},"token_out":{"$ref":"#/components/schemas/Address"},"fee_ppm":{"type":["integer","null"],"description":"Total swap fee charged on this hop at the sampled block, in parts per million (3000 = 0.30%), as used for the impact/cost maths. For uniswap-v4 this is the LP fee **plus** the protocol fee (the larger of the two directions), so it can exceed the pool's `fee_ppm` in `/v1/pools` (e.g. 3000 LP + 500 protocol = 3500). For other protocols it equals the pool's fee. Null when unknown."}}},"PegStatus":{"type":"string","enum":["ok","degraded","unverified"],"description":"Stablecoin peg check of a USD anchor (USDC, USDT, USDG, ...), per chain and per sample. `ok`: independent tier-A markets put its implied value within `PEG_DEVIATION_BPS` (50 bps) of $1, so it is used as $1. `degraded`: a majority of the chain's stablecoins disagree with it by more than 50 bps (it recovers below 30 bps); it is no longer used as $1, routes through it are repriced at its implied value and capped at indicative, and its own price is served from markets with reason `ANCHOR_DEPEGGED`. `unverified`: too little independent data (a single stablecoin) or no majority; it stays $1 and prices through it carry the warning `ANCHOR_PEG_UNVERIFIED`."},"AnchorPeg":{"type":"object","required":["symbol","implied_usd","deviation_bps","status"],"properties":{"symbol":{"type":"string","examples":["USDC"]},"implied_usd":{"description":"Implied USD value of 1 unit of the anchor from independent markets; null when it could not be measured.","oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"deviation_bps":{"type":["number","null"],"description":"Signed `(implied_usd − 1) × 10,000`, rounded to 0.01 bps; null when not measured.","examples":[-1.25]},"status":{"$ref":"#/components/schemas/PegStatus"}}},"Source":{"type":"object","required":["protocol","pool","quote_token","route","hops","fee_ppm","anchor_peg"],"properties":{"anchor_peg":{"description":"Peg check of the USD anchor at the end of `route`, from the same sample as the price. Null when the route does not end at a USD anchor.","oneOf":[{"$ref":"#/components/schemas/AnchorPeg"},{"type":"null"}]},"protocol":{"$ref":"#/components/schemas/Protocol"},"pool":{"$ref":"#/components/schemas/PoolId"},"quote_token":{"$ref":"#/components/schemas/TokenRef"},"route":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":2},"hops":{"type":"array","items":{"$ref":"#/components/schemas/Hop"},"minItems":1,"maxItems":2},"fee_ppm":{"type":["integer","null"],"description":"The first hop's `fee_ppm` (same semantics as `Hop.fee_ppm`, including the v4 protocol fee)."}}},"Depth":{"type":"object","required":["notional_usd","estimated_cost_bps","liquidity_usd"],"properties":{"notional_usd":{"type":"string","enum":["100","1000","10000"]},"estimated_cost_bps":{"type":["integer","null"],"minimum":0,"maximum":10000},"liquidity_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]}}},"PriceResponse":{"type":"object","required":["chain","contract","symbol","asset_id","asset_class","mode","price_usd","currency","basis","quality","reason","reasons","estimated_usd_anchor","as_of","source","depth","price_usd_per_ui_unit","warnings"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"contract":{"$ref":"#/components/schemas/Address"},"symbol":{"type":["string","null"]},"asset_id":{"type":["string","null"]},"asset_class":{"description":"Taxonomy class of the token's asset; null for tokens outside the registry.","oneOf":[{"$ref":"#/components/schemas/AssetClass"},{"type":"null"}]},"mode":{"type":"string","enum":["spot","indicative"]},"price_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"currency":{"type":"string","const":"USD"},"basis":{"oneOf":[{"type":"string","enum":["onchain_spot","onchain_indicative","usd_peg_assumption"]},{"type":"null"}]},"quality":{"$ref":"#/components/schemas/QualityStatus"},"reason":{"oneOf":[{"$ref":"#/components/schemas/ReasonCode"},{"type":"null"}]},"reasons":{"type":"array","items":{"$ref":"#/components/schemas/ReasonCode"}},"estimated_usd_anchor":{"type":["string","null"],"examples":["USDC≈USD"]},"as_of":{"oneOf":[{"$ref":"#/components/schemas/AsOf"},{"type":"null"}]},"source":{"oneOf":[{"$ref":"#/components/schemas/Source"},{"type":"null"}]},"depth":{"oneOf":[{"$ref":"#/components/schemas/Depth"},{"type":"null"}]},"shares_per_token":{"description":"Issuer share multiplier (null when unknown). Never applied to `price_usd`.","oneOf":[{"$ref":"#/components/schemas/SharesPerToken"},{"type":"null"}]},"price_usd_per_ui_unit":{"description":"USD per UI unit: the served `price_usd` divided by `shares_per_token.value` (exact, ≤ 18 significant digits) when a price is served and the multiplier was read onchain; otherwise null. Follows `mode` and the quality gate. Solana wallets show UI amounts (raw amount × multiplier): value a wallet balance as `ui_amount × price_usd_per_ui_unit` (= raw whole tokens × `price_usd`); never multiply a UI amount by `price_usd`.","oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/WarningCode"}}}},"HistoryPoint":{"type":"object","required":["t","open_usd","high_usd","low_usd","close_usd","price_usd","quality","samples","source","block_number","open_block","close_block"],"properties":{"t":{"$ref":"#/components/schemas/Timestamp"},"open_usd":{"$ref":"#/components/schemas/DecimalString"},"high_usd":{"$ref":"#/components/schemas/DecimalString"},"low_usd":{"$ref":"#/components/schemas/DecimalString"},"close_usd":{"$ref":"#/components/schemas/DecimalString"},"price_usd":{"allOf":[{"$ref":"#/components/schemas/DecimalString"}],"description":"Equals `close_usd` (compatibility)."},"quality":{"allOf":[{"$ref":"#/components/schemas/QualityStatus"}],"description":"The worst quality in the served bar."},"samples":{"type":"integer","minimum":1},"source":{"$ref":"#/components/schemas/HistorySource"},"block_number":{"allOf":[{"$ref":"#/components/schemas/IntegerString"}],"description":"Equals `close_block` (compatibility)."},"open_block":{"allOf":[{"$ref":"#/components/schemas/IntegerString"}],"description":"Block number (EVM) or slot (Solana) of the bar's first sample."},"close_block":{"allOf":[{"$ref":"#/components/schemas/IntegerString"}],"description":"Block number (EVM) or slot (Solana) of the bar's last sample."},"partial":{"type":"boolean","description":"The bucket is still open (contains now). Omitted otherwise."}}},"HistorySource":{"type":"string","enum":["live","backfill","mixed"],"description":"`live` (cron/engine samples), `backfill` (archive backfill), `mixed` (both in one bar)."},"HistoryResponse":{"type":"object","required":["chain","contract","symbol","interval","from","to","points","coverage","note"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"contract":{"$ref":"#/components/schemas/Address"},"symbol":{"type":["string","null"]},"interval":{"type":"string","enum":["5m","1h","1d"]},"from":{"$ref":"#/components/schemas/Timestamp"},"to":{"$ref":"#/components/schemas/Timestamp"},"points":{"type":"array","maxItems":2200,"items":{"$ref":"#/components/schemas/HistoryPoint"}},"coverage":{"type":"object","required":["first_sample","last_sample","expected_points","returned_points","gap_count","gaps","sources","backfill"],"properties":{"first_sample":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"last_sample":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"expected_points":{"type":"integer","minimum":0},"returned_points":{"type":"integer","minimum":0},"gap_count":{"type":"integer","minimum":0,"description":"Runs of missing buckets after gating, within `[max(from, first_sample), min(to, now))`."},"gaps":{"type":"array","maxItems":20,"description":"The first 20 gap runs.","items":{"type":"object","required":["from","to","missing_points"],"properties":{"from":{"$ref":"#/components/schemas/Timestamp"},"to":{"$ref":"#/components/schemas/Timestamp"},"missing_points":{"type":"integer","minimum":1}}}},"sources":{"type":"object","required":["live","backfill","mixed"],"description":"Returned points by `source`.","properties":{"live":{"type":"integer","minimum":0},"backfill":{"type":"integer","minimum":0},"mixed":{"type":"integer","minimum":0}}},"backfill":{"type":"object","required":["status","covered_from","hourly_from"],"description":"The chain's archive backfill job.","properties":{"status":{"type":"string","enum":["not_supported","not_started","running","paused","blocked","error","complete"],"description":"`not_supported` for non-EVM chains and chains not configured for backfill. Stellar RPC serves current ledger state only (no historical state reads), so Stellar history starts at the first sample and is never backfilled."},"covered_from":{"description":"Oldest bucket the backfill has filled so far; null when nothing is filled yet.","oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"hourly_from":{"description":"Hourly bars are kept from here; older history is daily. Null when no job exists.","oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}}}}},"note":{"type":"string"}}},"ChartResponse":{"allOf":[{"$ref":"#/components/schemas/HistoryResponse"},{"type":"object","required":["range"],"properties":{"range":{"type":"string","enum":["24h","7d","30d","90d","1y","max"]}}}]},"Tick":{"type":"object","required":["timestamp","block_number","log_index","tx_hash","pool","price_usd","kind","end_of_block"],"properties":{"timestamp":{"$ref":"#/components/schemas/TimestampMs"},"block_number":{"allOf":[{"$ref":"#/components/schemas/IntegerString"}],"description":"Block number (EVM) or slot (Solana)."},"log_index":{"type":["integer","null"],"minimum":0,"description":"Null for Solana."},"tx_hash":{"description":"Null for Solana.","oneOf":[{"type":"string","pattern":"^0x[0-9a-f]{64}$"},{"type":"null"}]},"pool":{"$ref":"#/components/schemas/PoolId"},"price_usd":{"$ref":"#/components/schemas/DecimalString"},"kind":{"type":"string","enum":["swap","state"]},"end_of_block":{"type":"boolean","description":"The last price event of its block for this token."}}},"TicksResponse":{"type":"object","required":["chain","contract","symbol","route","quality","coverage","ticks"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"contract":{"$ref":"#/components/schemas/Address"},"symbol":{"type":["string","null"]},"route":{"type":"array","description":"Token path of the selected route (token, …, USD anchor); empty when unpriced.","items":{"$ref":"#/components/schemas/Address"}},"quality":{"$ref":"#/components/schemas/QualityStatus"},"coverage":{"type":"object","required":["from","to","delay_s"],"properties":{"from":{"$ref":"#/components/schemas/TimestampMs"},"to":{"$ref":"#/components/schemas/TimestampMs"},"delay_s":{"type":["integer","null"],"minimum":0}}},"ticks":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/Tick"}},"reason":{"type":"string","description":"Why `ticks` is empty (a ReasonCode such as `BELOW_MIN_QUALITY`, or `ENGINE_UNAVAILABLE`)."}}},"DepthLevel":{"type":"object","required":["price_usd","offset_pct","cum_base","cum_usd","base","usd","complete"],"properties":{"price_usd":{"$ref":"#/components/schemas/DecimalString"},"offset_pct":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]*[1-9])?$","description":"Level offset from the spot in percent (negative for bids)."},"cum_base":{"$ref":"#/components/schemas/DecimalString"},"cum_usd":{"$ref":"#/components/schemas/DecimalString"},"base":{"$ref":"#/components/schemas/DecimalString"},"usd":{"$ref":"#/components/schemas/DecimalString"},"complete":{"type":"boolean","description":"False when a pool's covered range ended before this level (the cumulative is a lower bound)."}}},"DepthPool":{"type":"object","required":["pool","protocol","fee_ppm","quote_symbol","quote_usd","price_usd","bid_usd","ask_usd","bid_share_pct","ask_share_pct","complete","estimated","flags"],"properties":{"pool":{"type":"string","description":"Pool address, uniswap-v4 PoolId (bytes32) or Solana pool pubkey"},"protocol":{"type":"string"},"fee_ppm":{"type":"integer","minimum":0},"quote_symbol":{"type":["string","null"]},"quote_usd":{"$ref":"#/components/schemas/DecimalString"},"price_usd":{"allOf":[{"$ref":"#/components/schemas/DecimalString"}],"description":"The pool's own price of the token in USD (its spot × quote_usd)."},"bid_usd":{"$ref":"#/components/schemas/DecimalString"},"ask_usd":{"$ref":"#/components/schemas/DecimalString"},"bid_share_pct":{"$ref":"#/components/schemas/DecimalString"},"ask_share_pct":{"$ref":"#/components/schemas/DecimalString"},"complete":{"type":"boolean"},"estimated":{"type":"boolean","description":"Curve is an estimate (Solana Phase A); see DEPTH_ESTIMATED"},"flags":{"type":"array","items":{"type":"string"}},"bid_cum_base":{"type":"array","description":"Cumulative base per bid level (same indices as `bids`). Absent on the D1 fallback.","items":{"$ref":"#/components/schemas/DecimalString"}},"ask_cum_base":{"type":"array","description":"Cumulative base per ask level (same indices as `asks`). Absent on the D1 fallback.","items":{"$ref":"#/components/schemas/DecimalString"}}}},"DepthImpact":{"type":"object","required":["move_pct","sell_usd","sell_base","buy_usd","buy_base","complete"],"properties":{"move_pct":{"$ref":"#/components/schemas/DecimalString"},"sell_usd":{"allOf":[{"$ref":"#/components/schemas/DecimalString"}],"description":"Base sold incl. LP fees, valued at the spot"},"sell_base":{"$ref":"#/components/schemas/DecimalString"},"buy_usd":{"allOf":[{"$ref":"#/components/schemas/DecimalString"}],"description":"USD paid incl. LP fees"},"buy_base":{"$ref":"#/components/schemas/DecimalString"},"complete":{"type":"boolean"}}},"DepthResponse":{"type":"object","required":["chain","contract","symbol","decimals","price_usd","quality","as_of","range_pct","buckets","bucket_pct","bids","asks","totals","impact","pools","excluded","warnings","notice"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"contract":{"$ref":"#/components/schemas/Address"},"symbol":{"type":["string","null"]},"decimals":{"type":["integer","null"]},"price_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"quality":{"$ref":"#/components/schemas/QualityStatus"},"as_of":{"oneOf":[{"type":"null"},{"type":"object","required":["block_number","timestamp","age_ms","source","ticks_block_number","ticks_age_ms"],"properties":{"block_number":{"$ref":"#/components/schemas/IntegerString"},"timestamp":{"$ref":"#/components/schemas/Timestamp"},"age_ms":{"type":["integer","null"],"minimum":0},"source":{"type":"string","enum":["stream","poll","snapshot"]},"ticks_block_number":{"oneOf":[{"$ref":"#/components/schemas/IntegerString"},{"type":"null"}]},"ticks_age_ms":{"type":["integer","null"],"minimum":0}}}]},"range_pct":{"$ref":"#/components/schemas/DecimalString"},"buckets":{"type":"integer","minimum":1,"maximum":200},"bucket_pct":{"$ref":"#/components/schemas/DecimalString"},"served_range_pct":{"$ref":"#/components/schemas/DecimalString"},"served_buckets":{"type":"integer","minimum":1,"maximum":200},"bids":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/DepthLevel"}},"asks":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/DepthLevel"}},"totals":{"oneOf":[{"type":"null"},{"type":"object","required":["bid_base","bid_usd","ask_base","ask_usd","complete"],"properties":{"bid_base":{"$ref":"#/components/schemas/DecimalString"},"bid_usd":{"$ref":"#/components/schemas/DecimalString"},"ask_base":{"$ref":"#/components/schemas/DecimalString"},"ask_usd":{"$ref":"#/components/schemas/DecimalString"},"complete":{"type":"boolean"}}}]},"impact":{"type":"array","items":{"$ref":"#/components/schemas/DepthImpact"}},"pools":{"type":"array","items":{"$ref":"#/components/schemas/DepthPool"}},"excluded":{"type":"array","items":{"type":"object","required":["pool","protocol","reason"],"properties":{"pool":{"type":"string"},"protocol":{"type":"string"},"reason":{"type":"string","enum":["hooked_v4","inactive","unqualified","unsupported_curve","no_quote_usd","no_state","no_coverage"]}}}},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/WarningCode"}},"notice":{"type":"string"},"reason":{"type":"string","description":"Why the book is empty (a ReasonCode such as `BELOW_MIN_QUALITY`)."}}},"PoolToken":{"type":"object","required":["address","symbol","decimals"],"properties":{"address":{"$ref":"#/components/schemas/Address"},"symbol":{"type":"string"},"decimals":{"type":"integer","minimum":0,"maximum":36}}},"CostBps":{"type":"object","properties":{"100":{"type":["integer","null"]},"1000":{"type":["integer","null"]},"10000":{"type":["integer","null"]}}},"PoolState":{"type":"object","required":["price_token0_in_token1","price_token1_in_token0","liquidity_usd","cost_bps","tier","reasons","block_number","observed_at"],"properties":{"price_token0_in_token1":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"price_token1_in_token0":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"liquidity_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"cost_bps":{"$ref":"#/components/schemas/CostBps"},"tier":{"$ref":"#/components/schemas/PoolTier"},"reasons":{"type":"array","items":{"$ref":"#/components/schemas/ReasonCode"}},"block_number":{"$ref":"#/components/schemas/IntegerString"},"observed_at":{"$ref":"#/components/schemas/Timestamp"}}},"Icon":{"type":"object","required":["url","sizes","svg_url","source","license_note"],"description":"Logos and icons are trademarks of their respective owners. TokenPrices shows them unaltered, only to identify the chain, protocol or token concerned. Their display does not imply any affiliation with or endorsement by the owner. To request removal, contact `legal@tokenprices.xyz`. `url` is the 64 px WebP (the largest available size if 64 px does not exist). Other sizes are at the same URL with `64.webp` replaced by `<size>.webp`, for each value in `sizes`. URLs are content-addressed and immutable. Attributions: see the docs page footer (\"Attributions & removal\").","properties":{"url":{"type":"string","format":"uri","example":"https://icons.tokenprices.xyz/i/3f9a1c0e5b7d2a41c0ffee00d15ea5e1/64.webp"},"sizes":{"type":"array","minItems":1,"items":{"type":"integer","enum":[32,64,128]}},"svg_url":{"type":["string","null"],"format":"uri","description":"Sanitised SVG; null unless SVG serving is enabled."},"source":{"$ref":"#/components/schemas/IconSource"},"license_note":{"type":"string","maxLength":100}}},"IconSource":{"type":"string","description":"Where the image comes from. `generated` is a TokenPrices badge with no third-party logo (used for every tokenized stock and ETF). Price aggregators are never a source.","enum":["override","brand_kit","issuer","onchain_metadata","token_list","community","official_site","generated"]},"NullableIcon":{"description":"The entity's icon; null when the deployment serves no icons or the entity has none.","oneOf":[{"$ref":"#/components/schemas/Icon"},{"type":"null"}]},"ProtocolInfo":{"type":"object","required":["key","name","brand","icon"],"description":"A DEX protocol exposed by at least one active chain, with its display name, brand and icon.","properties":{"key":{"$ref":"#/components/schemas/Protocol"},"name":{"type":"string","example":"Uniswap v3"},"brand":{"type":"string","example":"Uniswap"},"icon":{"$ref":"#/components/schemas/NullableIcon"}}},"IconResponse":{"type":"object","required":["kind","id","icon"],"properties":{"kind":{"type":"string","enum":["chain","protocol","asset","token"]},"id":{"type":"string","description":"Entity id. Token ids are `<chain>:<address>` (EVM lowercase, Solana base58 exact)."},"icon":{"$ref":"#/components/schemas/Icon"}}},"Pool":{"type":"object","required":["pool","protocol","protocol_icon","protocol_version","token0","token1","fee_ppm","tick_spacing","stable","is_anchor_pool","active","state"],"properties":{"pool":{"$ref":"#/components/schemas/PoolId"},"protocol":{"$ref":"#/components/schemas/Protocol"},"protocol_icon":{"$ref":"#/components/schemas/NullableIcon"},"protocol_version":{"type":["string","null"]},"token0":{"$ref":"#/components/schemas/PoolToken"},"token1":{"$ref":"#/components/schemas/PoolToken"},"fee_ppm":{"type":["integer","null"],"description":"The pool's LP fee tier in parts per million (3000 = 0.30%) from the registry: the v2/v3/Aerodrome fee, or the uniswap-v4 PoolKey fee. It excludes any v4 protocol fee, which route hops (`Hop.fee_ppm`) include. For v4 dynamic-fee pools (PoolKey fee flag 0x800000) it is the last sampled total fee, or null if the pool has not been sampled."},"tick_spacing":{"type":["integer","null"],"description":"Concentrated-liquidity tick spacing; null for constant-product and Meteora DLMM pools."},"bin_step":{"type":["integer","null"],"description":"Meteora DLMM bin step (basis points per bin); null for every other pool."},"stable":{"type":"boolean"},"is_anchor_pool":{"type":"boolean"},"active":{"type":"boolean"},"state":{"oneOf":[{"$ref":"#/components/schemas/PoolState"},{"type":"null"}]}}},"Page":{"type":"object","required":["limit","offset","total"],"properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}},"PricesResponse":{"type":"object","required":["chain","prices","total","limit","offset"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"prices":{"type":"array","items":{"$ref":"#/components/schemas/PriceResponse"}},"total":{"type":"integer","minimum":0,"description":"Batch mode - number of items. List mode - number of sampled active tokens on the chain."},"limit":{"type":["integer","null"],"description":"List mode page size; null in batch mode."},"offset":{"type":["integer","null"],"description":"List mode offset; null in batch mode."}}},"PoolsResponse":{"allOf":[{"$ref":"#/components/schemas/Page"},{"type":"object","required":["chain","pools"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"pools":{"type":"array","items":{"$ref":"#/components/schemas/Pool"}}}}]},"AssetToken":{"type":"object","required":["chain","address","symbol","verified","form","market","quality","icon"],"properties":{"chain":{"$ref":"#/components/schemas/ChainKey"},"address":{"$ref":"#/components/schemas/Address"},"symbol":{"type":"string"},"form":{"description":"Token-level form (e.g. an OFT copy of a native asset is `bridged`).","oneOf":[{"$ref":"#/components/schemas/AssetForm"},{"type":"null"}]},"market":{"type":"string","enum":["dex","catalogue_only"]},"verified":{"type":"boolean"},"quality":{"$ref":"#/components/schemas/QualityStatus"},"icon":{"$ref":"#/components/schemas/NullableIcon"},"shares_per_token":{"oneOf":[{"$ref":"#/components/schemas/SharesPerToken"},{"type":"null"}]}}},"AssetClass":{"type":"string","description":"What the asset is economically (closed enum). `tokenized` says whether the token represents an off-chain asset held by an issuer or custodian.","enum":["crypto","stablecoin","equity","etf","commodity","treasury","fund","real_estate","other"]},"AssetForm":{"type":"string","description":"How the token holds the asset: `native` (issuer-native), `wrapped`, `bridged` (lock/mint or OFT copy), `liquid_staking`, `yield_bearing` (value or supply accrues yield), `rebasing` (balances change).","enum":["native","wrapped","bridged","liquid_staking","yield_bearing","rebasing"]},"AssetPeg":{"type":"object","description":"Stablecoins only. Only `currency: USD` stablecoins can be USD anchors or USD peg voters; every other peg (EUR, XAU, …) is priced from its own markets, never assumed.","required":["currency","backing"],"properties":{"currency":{"type":"string","pattern":"^[A-Z]{3}$","examples":["USD","EUR","XAU"]},"backing":{"type":"string","enum":["fiat","crypto","commodity","synthetic"]}}},"LegacyAssetType":{"type":"string","deprecated":true,"description":"Deprecated alias of `asset_class`, kept for back-compat: crypto → `crypto`, stablecoin → `stablecoin`, equity → `tokenized_stock`, etf → `tokenized_etf`, commodity → `tokenized_commodity`, treasury → `tokenized_treasury`, fund → `tokenized_fund`, real_estate → `tokenized_real_estate`, other → `other`.","enum":["crypto","stablecoin","tokenized_stock","tokenized_etf","tokenized_commodity","tokenized_treasury","tokenized_fund","tokenized_real_estate","other"]},"Asset":{"type":"object","required":["id","name","ticker","asset_class","tokenized","form","peg","asset_type","issuer","underlying_id","verification","icon","tokens"],"properties":{"id":{"type":"string"},"icon":{"$ref":"#/components/schemas/NullableIcon"},"name":{"type":"string"},"ticker":{"type":["string","null"]},"asset_class":{"$ref":"#/components/schemas/AssetClass"},"tokenized":{"type":"boolean"},"form":{"$ref":"#/components/schemas/AssetForm"},"peg":{"oneOf":[{"$ref":"#/components/schemas/AssetPeg"},{"type":"null"}]},"asset_type":{"$ref":"#/components/schemas/LegacyAssetType"},"issuer":{"type":["string","null"]},"underlying_id":{"type":["string","null"]},"verification":{"type":["string","null"]},"tokens":{"type":"array","items":{"$ref":"#/components/schemas/AssetToken"}}}},"AssetsResponse":{"allOf":[{"$ref":"#/components/schemas/Page"},{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}}}}]},"TokenSearchResult":{"type":"object","required":["chain","address","symbol","name","decimals","asset_id","asset_class","form","verified","active","is_anchor","quality","price_usd","icon"],"properties":{"icon":{"$ref":"#/components/schemas/NullableIcon"},"asset_class":{"oneOf":[{"$ref":"#/components/schemas/AssetClass"},{"type":"null"}]},"form":{"oneOf":[{"$ref":"#/components/schemas/AssetForm"},{"type":"null"}]},"chain":{"$ref":"#/components/schemas/ChainKey"},"address":{"$ref":"#/components/schemas/Address"},"symbol":{"type":"string"},"name":{"type":["string","null"],"description":"Token name: the seed's token name if any, otherwise the name of its curated asset (e.g. \"Ether\" for WETH, \"Apple (Robinhood Assets tokenized)\" for Robinhood AAPL); null for tokens with neither."},"decimals":{"type":"integer"},"asset_id":{"type":["string","null"]},"verified":{"type":"boolean"},"active":{"type":"boolean"},"is_anchor":{"type":"boolean"},"quality":{"$ref":"#/components/schemas/QualityStatus"},"price_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]}}},"TokenSearchResponse":{"type":"object","required":["query","results"],"properties":{"query":{"type":"string"},"results":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/TokenSearchResult"}}}},"TokenDetailResponse":{"type":"object","required":["token","price","pools"],"properties":{"token":{"type":"object","required":["chain","address","symbol","name","decimals","asset_id","verified","active","is_anchor","rebase_type","wrapper_type","asset_class","form","market","transfer_restrictions","metadata_source","icon"],"properties":{"icon":{"$ref":"#/components/schemas/NullableIcon"},"asset_class":{"oneOf":[{"$ref":"#/components/schemas/AssetClass"},{"type":"null"}]},"form":{"oneOf":[{"$ref":"#/components/schemas/AssetForm"},{"type":"null"}]},"market":{"type":"string","enum":["dex","catalogue_only"],"description":"`catalogue_only`: listed with no DEX market on a supported venue (e.g. permissioned treasury funds). Never sampled; its price is always `null` with NO_RELIABLE_MARKET / NO_POOLS. We never publish an issuer NAV."},"transfer_restrictions":{"description":"`permissioned` (allow-listed holders only) or `blocklist` (issuer can block holders); null otherwise.","oneOf":[{"type":"string","enum":["blocklist","permissioned"]},{"type":"null"}]},"chain":{"$ref":"#/components/schemas/ChainKey"},"address":{"$ref":"#/components/schemas/Address"},"symbol":{"type":"string"},"name":{"type":["string","null"],"description":"Same as `TokenSearchResult.name` (token name, else its asset's name, else null)."},"decimals":{"type":"integer"},"asset_id":{"type":["string","null"]},"verified":{"type":"boolean"},"active":{"type":"boolean"},"is_anchor":{"type":"boolean"},"rebase_type":{"type":["string","null"]},"wrapper_type":{"type":["string","null"]},"metadata_source":{"type":["string","null"]},"shares_per_token":{"oneOf":[{"$ref":"#/components/schemas/SharesPerToken"},{"type":"null"}]},"token_program":{"description":"Solana token program of the mint; null on EVM chains.","oneOf":[{"type":"string","enum":["spl-token","token-2022"]},{"type":"null"}]},"token_extensions":{"type":"array","description":"Sorted names of the Token-2022 extensions flagged in the registry snapshot of the mint (e.g. `scaled_ui_amount`, `permanent_delegate`, `pausable`, `transfer_fee`, `transfer_hook`); `[]` on EVM and for classic SPL mints. Live extension state is applied at sampling time (warnings/reasons).","items":{"type":"string"}}}},"price":{"type":"object","required":["price_usd","quality","reason","as_of"],"properties":{"price_usd":{"oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"quality":{"$ref":"#/components/schemas/QualityStatus"},"reason":{"oneOf":[{"$ref":"#/components/schemas/ReasonCode"},{"type":"null"}]},"as_of":{"oneOf":[{"$ref":"#/components/schemas/AsOf"},{"type":"null"}]}}},"pools":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/Pool"}}}},"ChainInfo":{"type":"object","required":["key","family","chain_id","status","icon","finality_tag","sample_interval_s","protocols","anchors","counts","last_sample","realtime"],"properties":{"icon":{"$ref":"#/components/schemas/NullableIcon"},"realtime":{"$ref":"#/components/schemas/ChainRealtime"},"key":{"$ref":"#/components/schemas/ChainKey"},"family":{"$ref":"#/components/schemas/ChainFamily"},"chain_id":{"type":["integer","null"],"description":"EVM chain id; null for Solana and Stellar (no chain id)."},"status":{"type":"string"},"finality_tag":{"type":"string","enum":["finalized","safe","latest"],"description":"The finality of the block the sampler actually pins for this chain (matches `as_of.finality` of its prices). A sampler override wins over the registry tag: Robinhood is pinned at `latest − 30` blocks, so it reports `latest` with `confirmations: 30`. Solana reads every account at `finalized` commitment; Stellar ledgers are final when they close (`finalized`)."},"confirmations":{"type":["integer","null"],"minimum":0,"description":"Blocks behind the chain head the sampler pins when `finality_tag` is `latest` (e.g. 30 on Robinhood); null when a finality tag (`safe`/`finalized`) is used directly."},"sample_interval_s":{"type":"integer"},"protocols":{"type":"array","items":{"$ref":"#/components/schemas/Protocol"}},"anchors":{"type":"array","items":{"type":"object","required":["symbol","address","usd_peg","implied_usd","deviation_bps","status","checked_at"],"properties":{"symbol":{"type":"string"},"address":{"$ref":"#/components/schemas/Address"},"usd_peg":{"type":"boolean"},"implied_usd":{"description":"USD anchors only: implied USD value from independent tier-A markets in the latest sample (stable vs stable pools and native/stable prices compared across stablecoins; the majority defines $1). Null for non-USD anchors and when it could not be measured.","oneOf":[{"$ref":"#/components/schemas/DecimalString"},{"type":"null"}]},"deviation_bps":{"type":["number","null"],"description":"Signed `(implied_usd − 1) × 10,000`, rounded to 0.01 bps; null when not measured."},"status":{"description":"USD anchors only (null otherwise). Not yet sampled reports `unverified`.","oneOf":[{"$ref":"#/components/schemas/PegStatus"},{"type":"null"}]},"checked_at":{"description":"Observation time of the sample the peg status comes from; null if never sampled or not a USD anchor.","oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}}}},"counts":{"type":"object","required":["tokens","pools","qualified","indicative","unavailable"],"description":"Active tokens and active pools (the default `/v1/pools` listing has the same `total`), plus the active tokens split by current quality after read-time freshness: `qualified` (QUALIFIED), `indicative` (INDICATIVE_*), `unavailable` (everything else, including STALE and not yet sampled). `qualified + indicative + unavailable = tokens`. Like the rest of this response, cached for up to 60 s.","properties":{"tokens":{"type":"integer","minimum":0},"pools":{"type":"integer","minimum":0},"qualified":{"type":"integer","minimum":0},"indicative":{"type":"integer","minimum":0},"unavailable":{"type":"integer","minimum":0}}},"last_sample":{"oneOf":[{"type":"object","required":["at","status","block_number"],"properties":{"at":{"$ref":"#/components/schemas/Timestamp"},"status":{"type":"string","enum":["ok","partial","failed","skipped"]},"block_number":{"oneOf":[{"$ref":"#/components/schemas/IntegerString"},{"type":"null"}]}}},{"type":"null"}]}}},"ChainsResponse":{"type":"object","required":["chains","protocols"],"properties":{"chains":{"type":"array","items":{"$ref":"#/components/schemas/ChainInfo"}},"protocols":{"type":"array","description":"Every protocol exposed by any active chain, once, sorted by key. `ChainInfo.protocols` stays a key list.","items":{"$ref":"#/components/schemas/ProtocolInfo"}}}},"HealthResponse":{"type":"object","required":["status","version","time","db","chains","service"],"properties":{"service":{"type":"object","required":["state","reason","resumes_at"],"description":"Billing circuit breaker. `/v1/health` is never paused; any state other than `ok` makes `status` `degraded`. `soft`/`hard`: public operations answer 503 `SERVICE_PAUSED`; `writes`: database writes are paused.","properties":{"state":{"type":"string","enum":["ok","soft","writes","hard"]},"reason":{"type":["string","null"]},"resumes_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}}},"status":{"type":"string","enum":["ok","degraded","down"]},"version":{"type":"string"},"time":{"$ref":"#/components/schemas/Timestamp"},"db":{"type":"string","enum":["ok","error"]},"chains":{"type":"object","additionalProperties":{"type":"object","required":["status","last_run_at","last_run_status","age_s","block_number"],"properties":{"status":{"type":"string"},"last_run_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"last_run_status":{"oneOf":[{"type":"string","enum":["ok","partial","failed","skipped"]},{"type":"null"}]},"age_s":{"type":["integer","null"]},"block_number":{"oneOf":[{"$ref":"#/components/schemas/IntegerString"},{"type":"null"}]},"engine":{"$ref":"#/components/schemas/EngineHealth"}}}}}},"HealthDownResponse":{"type":"object","required":["status","version","time","db","chains"],"properties":{"status":{"type":"string","enum":["down"]},"version":{"type":"string"},"time":{"$ref":"#/components/schemas/Timestamp"},"db":{"type":"string","enum":["error"]},"chains":{"type":"object","maxProperties":0}}},"ChainRealtime":{"type":"object","required":["commitment","target_age_ms"],"description":"Real-time engine settings for `finality=latest` prices on this chain.","properties":{"commitment":{"type":"string","enum":["latest","confirmed","finalized"],"description":"EVM chains read the `latest` block; Solana the `confirmed` slot; Stellar the latest closed ledger, which is final (`finalized`)."},"target_age_ms":{"type":"integer","minimum":0,"description":"Freshness target for `as_of.age_ms`; a slower response carries `REALTIME_DEGRADED`."}}},"EngineHealth":{"type":"object","description":"Real-time engine status for the chain (one engine call per shard, 500 ms; a failed or timed-out call reports `state: down`). Omitted when the deployment has no engine. An active chain whose engine is `down`, or whose `head_age_ms` exceeds 3 × its target for 60 s, makes the overall status `degraded`.","required":["state","mode","source","head_block","head_age_ms","last_snapshot_at","ws","reorgs_24h","governor","cu_today"],"properties":{"state":{"type":"string","enum":["starting","running","paused","down"]},"mode":{"type":"string","enum":["hot","idle"]},"source":{"type":["string","null"],"enum":["stream","poll",null]},"head_block":{"oneOf":[{"$ref":"#/components/schemas/IntegerString"},{"type":"null"}]},"head_age_ms":{"type":["integer","null"],"minimum":0},"last_snapshot_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"ws":{"type":"string","enum":["connected","reconnecting","n/a"]},"reorgs_24h":{"type":"integer","minimum":0},"governor":{"type":"string","enum":["ok","throttled","floor"]},"cu_today":{"type":"integer","minimum":0}}}}}}