{
  "openapi": "3.1.0",
  "info": {
    "title": "BlockReq Onchain Data API",
    "version": "0.4.0",
    "summary": "Prices, pools, trades and candles of the DEX pools BlockReq indexes on Ethereum, Base, BNB Chain, Arbitrum and Polygon.",
    "description": "Read-only market data from BlockReq's own index of whitelisted DEX pools.\n\nTwo sets of routes share the `/v1/dex` prefix:\n\n- **DEX API** (`/v1/dex/{chain}/...` and `POST /v1/dex/prices`): BlockReq's own format. Success is\n  `{\"data\": ...}`; an error is `{\"error\": {\"code\": \"...\", \"message\": \"...\"}}`.\n- **CoinGecko-compatible** (`/v1/dex/onchain/...`): the paths, parameters, JSON:API envelope and field names of\n  CoinGecko's on-chain (GeckoTerminal) API, so a client swaps `https://pro-api.coingecko.com/api/v3` for\n  `https://api.blockreq.com/v1/dex`. An error is `{\"errors\": [{\"status\": \"404\", \"title\": \"...\"}]}`. Values\n  BlockReq does not have (FDV, market cap, supply, images, CoinGecko coin ids, locked liquidity) are `null`.\n\nConventions:\n\n- Addresses in paths and bodies are `0x` and 40 hex digits in any case; responses give them in lowercase. A pool\n  is named by its address, or by its 64-digit pool id for Uniswap v4.\n- Integer parameters take plain decimal digits only (`16` or `016`); a sign, an exponent, a hex prefix, a fraction\n  or spaces (`+16`, `1.6e1`, `0x10`, `16.0`, ` 16`) answer 400.\n- Prices and USD amounts are decimal strings; raw token amounts are integer strings. A DEX API trade's raw\n  amounts (`amount0`, `amount1`) are in the pool's view: positive means the pool received it.\n- Hooked Uniswap v4 pools are never registered: looking one up answers 404, its trades and candles are empty, and\n  lists leave it out.\n- A successful GET is reused for one second: the same path and query parameters (in any order) within that\n  second get the same answer.\n- Error messages are English only. A path no route serves answers 404 (`no such endpoint`, or `Not Found` under\n  `/v1/dex/onchain`).\n- `503` means Postgres or ClickHouse cannot serve right now, or too many requests across all networks are\n  waiting (retry shortly); `504` means a query ran out of time (narrow the range). Both are worth retrying with\n  backoff; neither is the client's fault.\n\nEthereum, Base and Arbitrum are complete. `bsc` and `polygon` (`bsc` and `polygon_pos` under `/v1/dex/onchain`)\nare accepted while their history is still being filled in, so their prices and lists may be empty.\n\n**Authentication and limits.** The BlockReq gateway in front of the data service checks keys, rate-limits,\nenforces the quota and meters calls:\n\n- Send the key of an Onchain Data API endpoint in `X-API-Key` (or `Authorization: Bearer <key>`). A key anywhere\n  else (a query parameter, a cookie, another header, a path segment) is `401 invalid_key`. Without a key a\n  request is anonymous and limited per IP address, for trying the API.\n- Each plan has a request rate and a quota of calls per 30-day period, which starts with its first call; the\n  plans and their numbers are in the guide (https://blockreq.com/docs/build/onchain-data-api/).\n  `POST /v1/dex/prices` counts one call per 10 tokens, rounded up; every other request counts 1. The rate counts\n  requests, the quota counts calls. Each keyed response carries `X-BlockReq-Data-Api-Units`, the calls it counted\n  (`0` unless it succeeded).\n- `429` with `rate_limited` means over the rate; `429` with `quota_exceeded` means the period's quota is used up\n  (`X-BlockReq-Data-Api-Quota-Reset` is when it resets). Both carry `Retry-After`.\n- The gateway's errors use the DEX API shape `{\"error\": {\"code\": \"...\", \"message\": \"...\"}}` on every path,\n  `/v1/dex/onchain` included. Each route describes the gateway's 401, 403, 429 and 502, and its 503\n  `unavailable` and 504 `timeout` next to the data service's own; `POST /v1/dex/prices` also its 413. It may\n  also answer `404 not_found` for a path it does not forward and `405 method_not_allowed`.\n"
  },
  "x-blockreq-source": {
    "repository": "blockreq/liveapi",
    "path": "apps/api/openapi.yaml",
    "commit": "9be9e10"
  },
  "servers": [
    {
      "url": "https://api.blockreq.com",
      "description": "The BlockReq API gateway, which authenticates and meters calls and forwards /v1/dex/... to the data service."
    }
  ],
  "security": [
    {
      "ApiKey": []
    },
    {
      "BearerKey": []
    },
    {}
  ],
  "tags": [
    {
      "name": "DEX API",
      "description": "BlockReq's own routes. Chains are named `ethereum`, `base`, `bsc`, `arbitrum` and `polygon`."
    },
    {
      "name": "CoinGecko-compatible",
      "description": "CoinGecko on-chain (GeckoTerminal) API compatibility. Networks are named by CoinGecko's ids `eth`, `base`, `bsc`, `arbitrum` and `polygon_pos`; resource ids are `{network}_{address}`; dex ids and names are GeckoTerminal's (for example `uniswap-v4-ethereum` or `aerodrome-base`), as the dexes list gives them. Pool lists have 20 pools per page and at most 50 pages."
    }
  ],
  "paths": {
    "/v1/dex/{chain}/tokens/{address}": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getToken",
        "summary": "A token",
        "description": "The token's USD price and the pool it is read from, its 24-hour change and volume, and how many indexed pools hold it. The native coin's zero address is answered as the wrapped native token.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/TokenAddress"
          }
        ],
        "responses": {
          "200": {
            "description": "The token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Token"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/tokens/{address}/price": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getTokenPriceAt",
        "summary": "A token's USD price as of a moment",
        "description": "The latest of: the current price (if it was set by `at`), the reference pool's last trade within a day before `at`, and the close of the latest 1m, 5m, 15m or 1h candle that ended by `at` (within a month). Stablecoins are always 1. `price_usd`, `price_time` and `source` are null when none of those exist.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/TokenAddress"
          },
          {
            "name": "at",
            "in": "query",
            "description": "The moment, in Unix seconds; at most now. Defaults to now.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The price as of `at`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PriceAt"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/tokens/{address}/pools": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "listTokenPools",
        "summary": "Indexed pools holding a token",
        "description": "Deepest anchor side first. A token that is not indexed has no pools (an empty list, not 404).",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/TokenAddress"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Most pools returned.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The pools.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/tokens/{address}/holders": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getTokenHolders",
        "summary": "A token's largest holders",
        "description": "The top `limit` holders, counted from the token's ERC-20 Transfers. Burn addresses, Uniswap v4 PoolManagers and the pools holding the token are left out of the ranking and of the known total that `pct` is a share of. Only tracked tokens have a ranking: an anchor, a token in no indexed pool, a blocked token, or one not caught up to the Portal's head yet answers 404.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/TokenAddress"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Most holders returned.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "default": 5000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The ranking.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Holders"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/accounts/{address}/portfolio": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getAccountPortfolio",
        "summary": "An address's lightweight portfolio",
        "description": "The tokens an address holds on the chain, from two sources only: the balances the holder ranking stores (only tracked tokens whose top 5000 the address is in), and `balanceOf` from BlockReq's own node for the tokens `tokens` lists, which replaces the stored balance of those tokens (a zero drops the token). There is no full wallet index. Largest USD value first, holdings without one last. An address with nothing found answers 200 and an empty list.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "The holder's address, in any case.",
            "schema": {
              "$ref": "#/components/schemas/AddressInput"
            }
          },
          {
            "name": "tokens",
            "in": "query",
            "description": "Up to 50 comma-separated ERC-20 addresses (duplicates count once) to read with `balanceOf` from BlockReq's own node. The native coin's address is refused. On a chain without a node configured, listing any answers 503.",
            "schema": {
              "type": "string",
              "pattern": "^\\s*0x[0-9a-fA-F]{40}\\s*(,\\s*0x[0-9a-fA-F]{40}\\s*)*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The portfolio.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Portfolio"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "description": "Postgres cannot serve right now, `tokens` were listed on a chain without a node configured, or the node did not answer; the message says which. The gateway may also answer 503 here (see `GatewayUnavailableError`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "const": "unavailable"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "error": {
                    "code": "unavailable",
                    "message": "balance reads are not available on base; retry without tokens"
                  }
                }
              }
            }
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/tokens/{address}/ohlcv": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getTokenCandles",
        "summary": "A token's USD candles",
        "description": "Candles from `from` to `to` that have a price, oldest first; the latest `limit` of them.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/TokenAddress"
          },
          {
            "$ref": "#/components/parameters/Interval"
          },
          {
            "$ref": "#/components/parameters/CandleLimit"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "The candles.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Candle"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/pools/new": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "listNewPools",
        "summary": "The newest indexed pools",
        "description": "Newest first.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Most pools returned.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "min_liquidity_usd",
            "in": "query",
            "description": "Only pools whose anchor side held at least this many USD at the last screening.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The pools.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/pools/top": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "listTopPools",
        "summary": "The top indexed pools",
        "description": "By 24-hour USD volume or by the anchor side's liquidity.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "name": "sort",
            "in": "query",
            "description": "`volume` (24-hour USD volume) or `liquidity` (USD the anchor side held at the last screening).",
            "schema": {
              "type": "string",
              "enum": [
                "volume",
                "liquidity"
              ],
              "default": "volume"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Most pools returned.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The pools.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/pools/{id}": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getPool",
        "summary": "A pool",
        "description": "Both tokens, the current price (token1 per token0), 24-hour change, volume and trades. A registered pool that is not listed is served too, with `indexed` false and 24-hour figures from its candidate trades; a blocked pool answers 404.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/PoolId"
          }
        ],
        "responses": {
          "200": {
            "description": "The pool.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Pool"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/pools/{id}/ohlcv": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getPoolCandles",
        "summary": "A pool's candles",
        "description": "Candles from `from` to `to` that have a price, oldest first; the latest `limit` of them. A pool that is not listed gets candles computed from its candidate trades of the last 30 days (whole buckets only); a pool that is neither listed nor registered has none (an empty list).",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/PoolId"
          },
          {
            "name": "currency",
            "in": "query",
            "description": "`token`: `side`'s executed price in the other token. `usd`: `side`'s USD price.",
            "schema": {
              "type": "string",
              "enum": [
                "token",
                "usd"
              ],
              "default": "token"
            }
          },
          {
            "name": "side",
            "in": "query",
            "description": "The token priced; `token0` gives token1 per token0.",
            "schema": {
              "type": "string",
              "enum": [
                "token0",
                "token1"
              ],
              "default": "token0"
            }
          },
          {
            "$ref": "#/components/parameters/Interval"
          },
          {
            "$ref": "#/components/parameters/CandleLimit"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "The candles.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PoolCandle"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/{chain}/pools/{id}/trades": {
      "get": {
        "tags": [
          "DEX API"
        ],
        "operationId": "listPoolTrades",
        "summary": "A pool's trades",
        "description": "Newest first. A full page comes with `next_cursor`; pass it as `cursor` for the next page. A pool that is not listed serves its candidate trades of the last 30 days; an unknown pool has none (an empty list).",
        "parameters": [
          {
            "$ref": "#/components/parameters/Chain"
          },
          {
            "$ref": "#/components/parameters/PoolId"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Most trades per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of trades.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "next_cursor"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Trade"
                      }
                    },
                    "next_cursor": {
                      "description": "Where the next page starts; null when this page was the last (shorter than `limit`).",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/Cursor"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/prices": {
      "description": "Any method other than POST on this path answers 405 with the code `method_not_allowed`.",
      "post": {
        "tags": [
          "DEX API"
        ],
        "operationId": "getPrices",
        "summary": "Current USD prices of up to 50 tokens",
        "description": "Tokens across chains, answered in the order asked. A token without a price, or blocked, comes back with null `price_usd`.",
        "requestBody": {
          "required": true,
          "description": "JSON of at most 64 KiB (65,536 bytes).",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tokens"
                ],
                "properties": {
                  "tokens": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "object",
                      "required": [
                        "chain",
                        "address"
                      ],
                      "properties": {
                        "chain": {
                          "$ref": "#/components/schemas/ChainName"
                        },
                        "address": {
                          "$ref": "#/components/schemas/AddressInput"
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "tokens": [
                  {
                    "chain": "ethereum",
                    "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The prices, in the order asked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Price"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "description": "A token names a chain that is not served.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "413": {
            "description": "The body is over 64 KiB (65,536 bytes); the gateway or the data service refuses it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "const": "payload_too_large"
                        },
                        "message": {
                          "description": "`body must be under 64 KiB` when the gateway refuses the body before forwarding it, `body must be at most 64 KiB` from the data service.",
                          "type": "string",
                          "enum": [
                            "body must be under 64 KiB",
                            "body must be at most 64 KiB"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListNetworks",
        "summary": "Supported networks",
        "description": "Every network fits on page 1; later pages are empty.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "description": "The networks.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkResource"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/GatewayUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/new_pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListNewPoolsAllNetworks",
        "summary": "Pools created in the last 48 hours, across networks",
        "description": "Newest first, merged across every network; each pool names its network.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncludeCrossNetwork"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/trending_pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListTrendingPoolsAllNetworks",
        "summary": "Pools with the most trades, across networks",
        "description": "Most trades over `duration` first, merged across every network; each pool names its network.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncludeCrossNetwork"
          },
          {
            "$ref": "#/components/parameters/Duration"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/dexes": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListDexes",
        "summary": "Dexes of a network",
        "description": "Every dex fits on page 1; later pages are empty.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "description": "The dexes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DexResource"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/GatewayUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListTopPools",
        "summary": "Top pools of a network",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/TopPoolSort"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/dexes/{dex}/pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListDexPools",
        "summary": "Top pools of a dex",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "name": "dex",
            "in": "path",
            "required": true,
            "description": "A dex id from the network's dexes list; any other answers 404.",
            "schema": {
              "type": "string"
            },
            "example": "uniswap_v3"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/TopPoolSort"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/pools/multi/{addresses}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetPools",
        "summary": "Up to 50 pools",
        "description": "Pools that are not served are left out; the rest keep the order asked.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "name": "addresses",
            "in": "path",
            "required": true,
            "description": "Comma-separated pool addresses (or 64-digit v4 pool ids), 1 to 50 once repeats and empty entries are dropped.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/IncludeVolumeBreakdown"
          },
          {
            "$ref": "#/components/parameters/IncludeComposition"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/pools/{address}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetPool",
        "summary": "A pool",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainPoolAddress"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/IncludeVolumeBreakdown"
          },
          {
            "$ref": "#/components/parameters/IncludeComposition"
          }
        ],
        "responses": {
          "200": {
            "description": "The pool.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PoolResource"
                    },
                    "included": {
                      "$ref": "#/components/schemas/Included"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/pools/{address}/ohlcv/{timeframe}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetPoolOhlcv",
        "summary": "A pool's candles",
        "description": "Newest first, the open candle included. Listed pools' hour and day candles reach back to pool creation once their history is filled; minute candles are limited by retention (1m 90 days, 5m and 15m a year); pools that are not listed cover the last 30 days.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainPoolAddress"
          },
          {
            "$ref": "#/components/parameters/Timeframe"
          },
          {
            "$ref": "#/components/parameters/Aggregate"
          },
          {
            "$ref": "#/components/parameters/BeforeTimestamp"
          },
          {
            "$ref": "#/components/parameters/OhlcvLimit"
          },
          {
            "$ref": "#/components/parameters/OhlcvCurrency"
          },
          {
            "$ref": "#/components/parameters/TradeSide"
          },
          {
            "$ref": "#/components/parameters/IncludeEmptyIntervals"
          }
        ],
        "responses": {
          "200": {
            "description": "The candles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OhlcvDocument"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/pools/{address}/trades": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListPoolTrades",
        "summary": "A pool's trades",
        "description": "Newest first, over `trading_period`. A full page comes with `meta.next_cursor`; pass it as `cursor` for the next page (BlockReq's addition to CoinGecko's format).",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainPoolAddress"
          },
          {
            "name": "trading_period",
            "in": "query",
            "description": "How far back trades are served.",
            "schema": {
              "type": "string",
              "enum": [
                "1d",
                "7d",
                "30d"
              ],
              "default": "1d"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Most trades per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 300,
              "default": 300
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "trade_volume_in_usd_greater_than",
            "in": "query",
            "description": "Only trades worth more than this many USD.",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "$ref": "#/components/parameters/TradeSide"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of trades.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TradeResource"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "required": [
                        "next_cursor"
                      ],
                      "properties": {
                        "next_cursor": {
                          "description": "Where the next page starts; null when this page was the last (shorter than `per_page`).",
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/Cursor"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/tokens/multi/{addresses}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetTokens",
        "summary": "Up to 50 tokens",
        "description": "Tokens that are not served are left out; the rest keep the order asked.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "name": "addresses",
            "in": "path",
            "required": true,
            "description": "Comma-separated token addresses, 1 to 50 once repeats and empty entries are dropped.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IncludeTopPools"
          },
          {
            "$ref": "#/components/parameters/IncludeComposition"
          }
        ],
        "responses": {
          "200": {
            "description": "The tokens.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TokenDetailResource"
                      }
                    },
                    "included": {
                      "$ref": "#/components/schemas/IncludedTopPools"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/tokens/{address}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetToken",
        "summary": "A token",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainTokenAddress"
          },
          {
            "$ref": "#/components/parameters/IncludeTopPools"
          },
          {
            "$ref": "#/components/parameters/IncludeComposition"
          }
        ],
        "responses": {
          "200": {
            "description": "The token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TokenDetailResource"
                    },
                    "included": {
                      "$ref": "#/components/schemas/IncludedTopPools"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/tokens/{address}/pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListTokenPools",
        "summary": "A token's pools",
        "description": "Each pool comes with the token's price in it (`token_price_usd`) and its last trade.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainTokenAddress"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "name": "sort",
            "in": "query",
            "description": "`h24_volume_usd_liquidity_desc`: deepest first. `h24_tx_count_desc`: most 24-hour trades first. `h24_volume_usd_desc`: most 24-hour USD volume first.",
            "schema": {
              "type": "string",
              "enum": [
                "h24_volume_usd_liquidity_desc",
                "h24_tx_count_desc",
                "h24_volume_usd_desc"
              ],
              "default": "h24_volume_usd_liquidity_desc"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/tokens/{address}/ohlcv/{timeframe}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetTokenOhlcv",
        "summary": "A token's candles",
        "description": "`currency=usd` (the default) gives the token's own USD candles; `currency=token` gives its price in the other token of its deepest pool, and answers 404 when it has no pool. `meta.quote` is that other token, or null without a pool. Newest first, the open candle included.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/OnchainTokenAddress"
          },
          {
            "$ref": "#/components/parameters/Timeframe"
          },
          {
            "$ref": "#/components/parameters/Aggregate"
          },
          {
            "$ref": "#/components/parameters/BeforeTimestamp"
          },
          {
            "$ref": "#/components/parameters/OhlcvLimit"
          },
          {
            "$ref": "#/components/parameters/OhlcvCurrency"
          },
          {
            "$ref": "#/components/parameters/IncludeEmptyIntervals"
          }
        ],
        "responses": {
          "200": {
            "description": "The candles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OhlcvDocument"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/new_pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListNewPools",
        "summary": "Pools created in the last 48 hours",
        "description": "Newest first.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/networks/{network}/trending_pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainListTrendingPools",
        "summary": "Pools with the most trades",
        "description": "Most trades over `duration` first.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "$ref": "#/components/parameters/Include"
          },
          {
            "$ref": "#/components/parameters/Duration"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/simple/networks/{network}/token_price/{addresses}": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainGetSimpleTokenPrices",
        "summary": "USD prices of up to 100 tokens",
        "description": "Maps keyed by the addresses asked (lowercase). Tokens without a price are left out of every map.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Network"
          },
          {
            "name": "addresses",
            "in": "path",
            "required": true,
            "description": "Comma-separated token addresses, 1 to 100 once repeats and empty entries are dropped.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_market_cap",
            "in": "query",
            "description": "Adds `market_cap_usd` (always null).",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_24hr_vol",
            "in": "query",
            "description": "Adds `h24_volume_usd`.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_24hr_price_change",
            "in": "query",
            "description": "Adds `h24_price_change_percentage`.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_total_reserve_in_usd",
            "in": "query",
            "description": "Adds `total_reserve_in_usd`.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "mcap_fdv_fallback",
            "in": "query",
            "description": "Accepted for compatibility; changes nothing (BlockReq has no market cap or FDV).",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_inactive_source",
            "in": "query",
            "description": "Accepted for compatibility; changes nothing (an inactive token keeps the price of its last trade).",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The prices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimpleTokenPriceDocument"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    },
    "/v1/dex/onchain/search/pools": {
      "get": {
        "tags": [
          "CoinGecko-compatible"
        ],
        "operationId": "onchainSearchPools",
        "summary": "Search pools",
        "description": "By pool address, token address, symbol or name, on one network or all of them. Pools whose own address or a token's whole symbol matches come first, then deeper pools. Without `network` each pool names its network and `include` also takes `network`.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "What to search for; surrounding spaces are ignored. At least 2 characters, counted as a reader sees them (an emoji is one).",
            "schema": {
              "type": "string",
              "minLength": 2
            }
          },
          {
            "name": "network",
            "in": "query",
            "description": "One network to search; all of them when absent.",
            "schema": {
              "$ref": "#/components/schemas/NetworkId"
            }
          },
          {
            "$ref": "#/components/parameters/IncludeCrossNetwork"
          },
          {
            "$ref": "#/components/parameters/Page"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OnchainPools"
          },
          "400": {
            "$ref": "#/components/responses/OnchainInvalid"
          },
          "401": {
            "$ref": "#/components/responses/GatewayUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/GatewayForbidden"
          },
          "404": {
            "$ref": "#/components/responses/OnchainNotFound"
          },
          "429": {
            "$ref": "#/components/responses/GatewayRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/OnchainInternal"
          },
          "502": {
            "$ref": "#/components/responses/GatewayBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/OnchainUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/OnchainTimeout"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "The key of an Onchain Data API endpoint (Dashboard → Endpoints → Add Endpoint → Onchain Data API). Until 2026-12-03T00:00:00Z an RPC key is accepted too and counts against the same account's data API quota."
      },
      "BearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "The same key as `ApiKey`, sent as `Authorization: Bearer <key>`."
      }
    },
    "headers": {
      "RetryAfter": {
        "description": "Seconds to wait before sending the request again.",
        "required": true,
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "QuotaReset": {
        "description": "Only on `quota_exceeded`. When the current period ends and the quota resets, in Unix seconds.",
        "schema": {
          "type": "integer"
        }
      },
      "Units": {
        "description": "On every response to a request with a valid key: the calls this request counted against the quota. The units of a 2xx answer (1, or for `POST /v1/dex/prices` one per 10 tokens, rounded up); `0` on every other answer. Absent on anonymous requests and on an invalid key.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "parameters": {
      "Chain": {
        "name": "chain",
        "in": "path",
        "required": true,
        "description": "The chain. Any other name answers 404.",
        "schema": {
          "$ref": "#/components/schemas/ChainName"
        }
      },
      "TokenAddress": {
        "name": "address",
        "in": "path",
        "required": true,
        "description": "Token address, in any case.",
        "schema": {
          "$ref": "#/components/schemas/AddressInput"
        }
      },
      "PoolId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Pool address, or the 64-digit pool id of a Uniswap v4 pool, in any case.",
        "schema": {
          "$ref": "#/components/schemas/PoolIdInput"
        }
      },
      "Interval": {
        "name": "interval",
        "in": "query",
        "description": "Candle interval.",
        "schema": {
          "type": "string",
          "enum": [
            "1m",
            "5m",
            "15m",
            "1h",
            "4h",
            "1d"
          ],
          "default": "1h"
        }
      },
      "CandleLimit": {
        "name": "limit",
        "in": "query",
        "description": "Most candles returned.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000,
          "default": 300
        }
      },
      "From": {
        "name": "from",
        "in": "query",
        "description": "Start of the range in Unix seconds, inclusive; not after `to`. Defaults to `limit` intervals before `to`.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      },
      "To": {
        "name": "to",
        "in": "query",
        "description": "End of the range in Unix seconds. Defaults to now; a time past 2106-02-07 reads as that moment.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "The `next_cursor` of the previous page; any other value answers 400.",
        "schema": {
          "$ref": "#/components/schemas/Cursor"
        }
      },
      "Network": {
        "name": "network",
        "in": "path",
        "required": true,
        "description": "CoinGecko network id. Any other answers 404.",
        "schema": {
          "$ref": "#/components/schemas/NetworkId"
        }
      },
      "OnchainPoolAddress": {
        "name": "address",
        "in": "path",
        "required": true,
        "description": "Pool address, or the 64-digit pool id of a Uniswap v4 pool, in any case.",
        "schema": {
          "$ref": "#/components/schemas/PoolIdInput"
        }
      },
      "OnchainTokenAddress": {
        "name": "address",
        "in": "path",
        "required": true,
        "description": "Token address, in any case.",
        "schema": {
          "$ref": "#/components/schemas/AddressInput"
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "description": "Page number; 20 items per page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 50,
          "default": 1
        }
      },
      "Include": {
        "name": "include",
        "in": "query",
        "description": "Related resources to add under `included`, comma-separated; other values are ignored.",
        "style": "form",
        "explode": false,
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "base_token",
              "quote_token",
              "dex"
            ]
          }
        }
      },
      "IncludeCrossNetwork": {
        "name": "include",
        "in": "query",
        "description": "Related resources to add under `included`, comma-separated; other values are ignored.",
        "style": "form",
        "explode": false,
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "base_token",
              "quote_token",
              "dex",
              "network"
            ]
          }
        }
      },
      "IncludeTopPools": {
        "name": "include",
        "in": "query",
        "description": "`top_pools` adds the tokens' top pools under `included`; other values are ignored.",
        "style": "form",
        "explode": false,
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "top_pools"
            ]
          }
        }
      },
      "IncludeComposition": {
        "name": "include_composition",
        "in": "query",
        "description": "Adds each pool's token balances and their USD value (balances are known for v2-style pools only; null otherwise).",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "IncludeVolumeBreakdown": {
        "name": "include_volume_breakdown",
        "in": "query",
        "description": "Adds buy, sell and net buy USD volume per window.",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "IncludeEmptyIntervals": {
        "name": "include_empty_intervals",
        "in": "query",
        "description": "Serve the `limit` intervals up to the newest candle instead, filling those without trades at the previous close with no volume.",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "TopPoolSort": {
        "name": "sort",
        "in": "query",
        "description": "`h24_tx_count_desc`: most 24-hour trades first. `h24_volume_usd_desc`: most 24-hour USD volume first.",
        "schema": {
          "type": "string",
          "enum": [
            "h24_tx_count_desc",
            "h24_volume_usd_desc"
          ],
          "default": "h24_tx_count_desc"
        }
      },
      "Duration": {
        "name": "duration",
        "in": "query",
        "description": "The window trades are counted over.",
        "schema": {
          "type": "string",
          "enum": [
            "5m",
            "1h",
            "6h",
            "24h"
          ],
          "default": "24h"
        }
      },
      "Timeframe": {
        "name": "timeframe",
        "in": "path",
        "required": true,
        "description": "Candle timeframe; see `aggregate` for the sizes each one has.",
        "schema": {
          "type": "string",
          "enum": [
            "day",
            "hour",
            "minute"
          ]
        }
      },
      "Aggregate": {
        "name": "aggregate",
        "in": "query",
        "description": "Candle size in timeframe units: `day` takes 1; `hour` takes 1, 4 or 12; `minute` takes 1, 5 or 15. Any other combination answers 400.",
        "schema": {
          "type": "integer",
          "enum": [
            1,
            4,
            5,
            12,
            15
          ],
          "default": 1
        }
      },
      "BeforeTimestamp": {
        "name": "before_timestamp",
        "in": "query",
        "description": "Only candles before this moment, in Unix seconds (exclusive); a later one than now counts as now. A value in milliseconds (10^12 or more) answers 400.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 999999999999
        }
      },
      "OhlcvLimit": {
        "name": "limit",
        "in": "query",
        "description": "Most candles returned: the latest that exist, so stretches without trades take none (unless `include_empty_intervals`).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000,
          "default": 100
        }
      },
      "OhlcvCurrency": {
        "name": "currency",
        "in": "query",
        "description": "`usd`: USD prices and volume. `token`: prices and volume in the pool's other token.",
        "schema": {
          "type": "string",
          "enum": [
            "usd",
            "token"
          ],
          "default": "usd"
        }
      },
      "TradeSide": {
        "name": "token",
        "in": "query",
        "description": "The token whose side is taken: `base` (the default), `quote`, or one of the pool's token addresses. Any other value answers 400.",
        "schema": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "base",
                "quote"
              ]
            },
            {
              "$ref": "#/components/schemas/AddressInput"
            }
          ]
        }
      }
    },
    "responses": {
      "GatewayUnauthorized": {
        "description": "Answered by the gateway. The key is unknown or revoked, or it was sent somewhere other than the `X-API-Key` or `Authorization: Bearer` header (a query parameter, a cookie, another header or a path segment). An invalid key never falls back to anonymous access.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayUnauthorizedError"
            },
            "example": {
              "error": {
                "code": "invalid_key",
                "message": "Invalid API key. Get a key at blockreq.com and send it in the X-API-Key header."
              }
            }
          }
        }
      },
      "GatewayForbidden": {
        "description": "Answered by the gateway. The account is suspended, the key's Onchain Data API endpoints are all expired or do not allow the client IP, or the key has only RPC endpoints and the RPC-key transition (until 2026-12-03T00:00:00Z) is over.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayForbiddenError"
            },
            "examples": {
              "forbidden": {
                "summary": "Access denied",
                "value": {
                  "error": {
                    "code": "forbidden",
                    "message": "API key access denied"
                  }
                }
              },
              "rpc_only": {
                "summary": "An RPC key after the transition",
                "value": {
                  "error": {
                    "code": "forbidden",
                    "message": "This API key is for RPC only. Create an Onchain Data API endpoint at blockreq.com to get a data API key."
                  }
                }
              }
            }
          }
        }
      },
      "GatewayRateLimited": {
        "description": "Answered by the gateway. `rate_limited`: over the request rate (with a key, the plan's rate; without a key, the per-IP window); every request takes one token whatever its units, and `Retry-After` is 1 with a key. `quota_exceeded`: the plan's quota for the current 30-day period is used up; `Retry-After` is the seconds left in the period and `X-BlockReq-Data-Api-Quota-Reset` is when it ends. The quota is marked after settlement, so a few calls may still pass after it runs out.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "X-BlockReq-Data-Api-Quota-Reset": {
            "$ref": "#/components/headers/QuotaReset"
          },
          "X-BlockReq-Data-Api-Units": {
            "$ref": "#/components/headers/Units"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayRateLimitedError"
            },
            "examples": {
              "rate_limited": {
                "summary": "Over the plan's rate (with a key)",
                "value": {
                  "error": {
                    "code": "rate_limited",
                    "message": "Rate limit reached for this API key. See blockreq.com for higher limits."
                  }
                }
              },
              "rate_limited_anonymous": {
                "summary": "Over the per-IP window (without a key)",
                "value": {
                  "error": {
                    "code": "rate_limited",
                    "message": "Rate limit reached. Get a free API key at blockreq.com for a higher limit."
                  }
                }
              },
              "quota_exceeded": {
                "summary": "The period's quota is used up",
                "value": {
                  "error": {
                    "code": "quota_exceeded",
                    "message": "Data API quota reached for this period; it resets at 2026-12-01T08:00:00Z. See blockreq.com for higher limits."
                  }
                }
              }
            }
          }
        }
      },
      "GatewayBadGateway": {
        "description": "Answered by the gateway. The data service failed, did not answer in time (10 seconds), or answered more than the gateway relays (8 MiB). Worth retrying with backoff.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayBadGatewayError"
            },
            "example": {
              "error": {
                "code": "upstream_failed",
                "message": "upstream request failed"
              }
            }
          }
        }
      },
      "GatewayUnavailable": {
        "description": "Answered by the gateway: it cannot authenticate keys or record usage for a moment. Retry shortly. (This route is served from memory, so the data service itself never answers 503 here.)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayUnavailableError"
            }
          }
        }
      },
      "GatewayTimeout": {
        "description": "Answered by the gateway, which ran out of time for the whole request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayTimeoutError"
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "A parameter or the body is invalid; the message says which.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "const": "invalid_request"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "example": {
              "error": {
                "code": "invalid_request",
                "message": "limit must be an integer from 1 to 100"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "The chain is not served, or the token or pool is not indexed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/NotFoundError"
            },
            "example": {
              "error": {
                "code": "not_found",
                "message": "token is not indexed"
              }
            }
          }
        }
      },
      "Internal": {
        "description": "An unexpected failure.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "const": "internal"
                    },
                    "message": {
                      "const": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Unavailable": {
        "description": "Postgres or ClickHouse cannot serve right now (from the data service), or the gateway cannot authenticate keys or record usage for a moment. Retry shortly.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/UnavailableError"
                },
                {
                  "$ref": "#/components/schemas/GatewayUnavailableError"
                }
              ]
            }
          }
        }
      },
      "Timeout": {
        "description": "A query ran out of time (from the data service; narrow the range), or the gateway ran out of time for the whole request.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/TimeoutError"
                },
                {
                  "$ref": "#/components/schemas/GatewayTimeoutError"
                }
              ]
            }
          }
        }
      },
      "OnchainPools": {
        "description": "The pools.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "data"
              ],
              "properties": {
                "data": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PoolResource"
                  }
                },
                "included": {
                  "$ref": "#/components/schemas/Included"
                }
              }
            }
          }
        }
      },
      "OnchainInvalid": {
        "description": "A parameter is invalid; the title says which.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OnchainError"
            },
            "example": {
              "errors": [
                {
                  "status": "400",
                  "title": "Invalid duration. Allowed values: 5m, 1h, 6h, 24h"
                }
              ]
            }
          }
        }
      },
      "OnchainNotFound": {
        "description": "The network, dex, pool or token is not served.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OnchainError"
            },
            "example": {
              "errors": [
                {
                  "status": "404",
                  "title": "Specified network not found"
                }
              ]
            }
          }
        }
      },
      "OnchainInternal": {
        "description": "An unexpected failure.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "errors"
              ],
              "properties": {
                "errors": {
                  "type": "array",
                  "minItems": 1,
                  "maxItems": 1,
                  "items": {
                    "type": "object",
                    "required": [
                      "status",
                      "title"
                    ],
                    "properties": {
                      "status": {
                        "const": "500"
                      },
                      "title": {
                        "const": "Internal Server Error"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "OnchainUnavailable": {
        "description": "Postgres or ClickHouse cannot serve right now, in CoinGecko's format (from the data service), or the gateway cannot authenticate keys or record usage for a moment, in the gateway's `error` format. Retry shortly.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/OnchainUnavailableError"
                },
                {
                  "$ref": "#/components/schemas/GatewayUnavailableError"
                }
              ]
            }
          }
        }
      },
      "OnchainTimeout": {
        "description": "A query ran out of time, in CoinGecko's format (from the data service; narrow the range), or the gateway ran out of time for the whole request, in the gateway's `error` format.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/OnchainTimeoutError"
                },
                {
                  "$ref": "#/components/schemas/GatewayTimeoutError"
                }
              ]
            }
          }
        }
      }
    },
    "schemas": {
      "ChainName": {
        "description": "Chain name as the DEX API paths use it.",
        "type": "string",
        "enum": [
          "ethereum",
          "base",
          "bsc",
          "arbitrum",
          "polygon"
        ]
      },
      "NetworkId": {
        "description": "CoinGecko network id.",
        "type": "string",
        "enum": [
          "eth",
          "base",
          "bsc",
          "arbitrum",
          "polygon_pos"
        ]
      },
      "AddressInput": {
        "description": "`0x` and 40 hex digits, in any case.",
        "type": "string",
        "pattern": "^0x[0-9a-fA-F]{40}$"
      },
      "PoolIdInput": {
        "description": "`0x` and 40 hex digits (a pool address) or 64 (a Uniswap v4 pool id), in any case.",
        "type": "string",
        "pattern": "^0x([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$"
      },
      "Address": {
        "description": "`0x` and 40 lowercase hex digits.",
        "type": "string",
        "pattern": "^0x[0-9a-f]{40}$"
      },
      "PoolIdentifier": {
        "description": "Pool address, or a Uniswap v4 pool id (64 hex digits), lowercase.",
        "type": "string",
        "pattern": "^0x([0-9a-f]{40}|[0-9a-f]{64})$"
      },
      "TxHash": {
        "type": "string",
        "pattern": "^0x[0-9a-f]{64}$"
      },
      "Decimal": {
        "description": "A decimal number as a string, e.g. `\"2500.5\"`.",
        "type": "string"
      },
      "NullableDecimal": {
        "description": "A decimal number as a string, or null when unknown.",
        "type": [
          "string",
          "null"
        ]
      },
      "RawAmount": {
        "description": "A raw token amount (no decimals applied) as an integer string.",
        "type": "string",
        "pattern": "^-?[0-9]+$"
      },
      "Cursor": {
        "description": "An opaque page cursor this API returned.",
        "type": "string",
        "pattern": "^[0-9]{1,15}\\.[0-9]{1,12}\\.[0-9]{1,7}$"
      },
      "GatewayUnavailableError": {
        "description": "The gateway's 503.",
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "unavailable"
              },
              "message": {
                "type": "string",
                "enum": [
                  "API key authentication temporarily unavailable",
                  "temporarily unavailable; retry shortly"
                ]
              }
            }
          }
        }
      },
      "GatewayTimeoutError": {
        "description": "The gateway's 504.",
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "timeout"
              },
              "message": {
                "const": "gateway deadline exceeded"
              }
            }
          }
        }
      },
      "UnavailableError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "unavailable"
              },
              "message": {
                "const": "temporarily unavailable; retry shortly"
              }
            }
          }
        }
      },
      "TimeoutError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "timeout"
              },
              "message": {
                "const": "query took too long; narrow the range"
              }
            }
          }
        }
      },
      "OnchainUnavailableError": {
        "type": "object",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "type": "object",
              "required": [
                "status",
                "title"
              ],
              "properties": {
                "status": {
                  "const": "503"
                },
                "title": {
                  "const": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "OnchainTimeoutError": {
        "type": "object",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "type": "object",
              "required": [
                "status",
                "title"
              ],
              "properties": {
                "status": {
                  "const": "504"
                },
                "title": {
                  "const": "Query took too long; narrow the range"
                }
              }
            }
          }
        }
      },
      "GatewayUnauthorizedError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "invalid_key"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "GatewayForbiddenError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "forbidden"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "GatewayRateLimitedError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "description": "`rate_limited` over the request rate; `quota_exceeded` when the period's quota is used up. These are the only two codes a 429 carries (`quota_exhausted` is a field of the gateway's auth snapshot and a metric label, never a response code).",
                "type": "string",
                "enum": [
                  "rate_limited",
                  "quota_exceeded"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "GatewayBadGatewayError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "upstream_failed",
                  "response_too_large"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "NotFoundError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "const": "not_found"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "TokenRef": {
        "type": "object",
        "required": [
          "address",
          "symbol",
          "decimals"
        ],
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "symbol": {
            "type": [
              "string",
              "null"
            ]
          },
          "decimals": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "Token": {
        "type": "object",
        "required": [
          "chain",
          "address",
          "symbol",
          "name",
          "decimals",
          "flagged",
          "price_usd",
          "price_block",
          "price_time",
          "reference_pool",
          "reference_liquidity_usd",
          "price_change_24h",
          "volume_usd_24h",
          "pools",
          "low_liquidity",
          "stale"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "symbol": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "decimals": {
            "type": [
              "integer",
              "null"
            ]
          },
          "flagged": {
            "description": "True when the token's symbol imitates a stablecoin, a major token or the native coin.",
            "type": "boolean"
          },
          "price_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price_block": {
            "description": "Block of the trade that set the price.",
            "type": [
              "integer",
              "null"
            ]
          },
          "price_time": {
            "description": "When the price was set.",
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "reference_pool": {
            "description": "The pool the price is read from; null for a pegged stablecoin.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PoolIdentifier"
              },
              {
                "type": "null"
              }
            ]
          },
          "reference_liquidity_usd": {
            "description": "USD the reference pool's anchor side held at the last screening.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price_change_24h": {
            "description": "Relative change against the price about 24 hours ago, e.g. `\"-0.0125\"`; null without both prices.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "volume_usd_24h": {
            "$ref": "#/components/schemas/Decimal"
          },
          "pools": {
            "description": "Indexed pools holding the token.",
            "type": "integer"
          },
          "low_liquidity": {
            "description": "True when the reference pool's anchor side held under $10,000 at the last screening: a pool this shallow can hold a price nobody arbitrages. Null without a price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "stale": {
            "description": "True when the price was set more than 7 days ago (its reference pool has not traded since). Null without a price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "PriceAt": {
        "type": "object",
        "required": [
          "chain",
          "address",
          "at",
          "price_usd",
          "price_time",
          "source",
          "low_liquidity",
          "stale"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "at": {
            "description": "The moment asked about, Unix seconds.",
            "type": "integer"
          },
          "price_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price_time": {
            "description": "When that price was set (the trade, or the end of the candle), Unix seconds.",
            "type": [
              "integer",
              "null"
            ]
          },
          "source": {
            "description": "Where the price came from: the current price, a trade of the reference pool, or the close of a candle of that interval.",
            "enum": [
              "current",
              "trade",
              "1m",
              "5m",
              "15m",
              "1h",
              null
            ]
          },
          "low_liquidity": {
            "description": "Whether the token's current price rests on a reference pool whose anchor side held under $10,000 at the last screening, whatever moment was asked about. Null without a current price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "stale": {
            "description": "True when `price_time` is more than 7 days before `at`. Null without a price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "Price": {
        "type": "object",
        "required": [
          "chain",
          "address",
          "price_usd",
          "price_block",
          "price_time",
          "reference_liquidity_usd",
          "low_liquidity",
          "stale"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "price_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price_block": {
            "type": [
              "integer",
              "null"
            ]
          },
          "price_time": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "reference_liquidity_usd": {
            "description": "USD the reference pool's anchor side held at the last screening; null for a pegged stablecoin or without a price.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "low_liquidity": {
            "description": "True when the reference pool's anchor side held under $10,000 at the last screening: a pool this shallow can hold a price nobody arbitrages. Null without a price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "stale": {
            "description": "True when the price was set more than 7 days ago. Null without a price, false for a pegged stablecoin.",
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "Holders": {
        "type": "object",
        "required": [
          "chain",
          "address",
          "symbol",
          "decimals",
          "block",
          "known_total",
          "known_total_amount",
          "total_supply",
          "consistent",
          "excluded",
          "top"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "symbol": {
            "type": [
              "string",
              "null"
            ]
          },
          "decimals": {
            "type": [
              "integer",
              "null"
            ]
          },
          "block": {
            "description": "Transfers up to this block are counted.",
            "type": "integer"
          },
          "known_total": {
            "description": "Sum of every balance besides the excluded addresses', raw; the denominator of `pct`.",
            "$ref": "#/components/schemas/RawAmount"
          },
          "known_total_amount": {
            "description": "`known_total` in whole tokens; null when the decimals are unknown.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "total_supply": {
            "description": "The token's `totalSupply()` read from BlockReq's own node; null when it could not be read.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/RawAmount"
              },
              {
                "type": "null"
              }
            ]
          },
          "consistent": {
            "description": "Whether the Transfers add up to within 1% of `total_supply`; null without it. When false (a token that mints without a Transfer, rebases and the like) balances may be off and every `pct` is null.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "excluded": {
            "description": "Burn addresses, Uniswap v4 PoolManagers and the pools holding the token themselves, left out.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          },
          "top": {
            "description": "Largest balance first.",
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "rank",
                "address",
                "balance",
                "amount",
                "pct"
              ],
              "properties": {
                "rank": {
                  "description": "1 for the largest.",
                  "type": "integer"
                },
                "address": {
                  "$ref": "#/components/schemas/Address"
                },
                "balance": {
                  "$ref": "#/components/schemas/RawAmount"
                },
                "amount": {
                  "description": "The balance in whole tokens; null when the decimals are unknown.",
                  "$ref": "#/components/schemas/NullableDecimal"
                },
                "pct": {
                  "description": "Percent of `known_total`, to 6 decimals; null when the known total is 0 or `consistent` is false.",
                  "$ref": "#/components/schemas/NullableDecimal"
                }
              }
            }
          }
        }
      },
      "Portfolio": {
        "type": "object",
        "required": [
          "chain",
          "address",
          "total_value_usd",
          "holdings",
          "node_block",
          "failed"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "total_value_usd": {
            "description": "Sum of every `value_usd`, to 6 decimals; holdings without one are not counted.",
            "$ref": "#/components/schemas/Decimal"
          },
          "holdings": {
            "description": "Largest `value_usd` first, holdings without one last.",
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "token",
                "symbol",
                "name",
                "decimals",
                "balance",
                "amount",
                "price_usd",
                "value_usd",
                "source",
                "block"
              ],
              "properties": {
                "token": {
                  "$ref": "#/components/schemas/Address"
                },
                "symbol": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "decimals": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "balance": {
                  "$ref": "#/components/schemas/RawAmount"
                },
                "amount": {
                  "description": "The balance in whole tokens; null when the decimals are unknown.",
                  "$ref": "#/components/schemas/NullableDecimal"
                },
                "price_usd": {
                  "$ref": "#/components/schemas/NullableDecimal"
                },
                "value_usd": {
                  "description": "`amount` × `price_usd`, to 6 decimals; null when either is missing.",
                  "$ref": "#/components/schemas/NullableDecimal"
                },
                "source": {
                  "description": "`holders`: the holder ranking's stored balance; `node`: `balanceOf` on BlockReq's own node.",
                  "enum": [
                    "holders",
                    "node"
                  ]
                },
                "block": {
                  "description": "Block the balance is as of.",
                  "type": "integer"
                }
              }
            }
          },
          "node_block": {
            "description": "Block of the node's `balanceOf` reads; null when none was made.",
            "type": [
              "integer",
              "null"
            ]
          },
          "failed": {
            "description": "Listed tokens whose `balanceOf` failed; a stored balance is kept for them.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          }
        }
      },
      "Pool": {
        "type": "object",
        "required": [
          "chain",
          "id",
          "protocol",
          "family",
          "token0",
          "token1",
          "fee",
          "tick_spacing",
          "stable",
          "hooks",
          "created_block",
          "created_time",
          "indexed",
          "anchor_liquidity_usd",
          "price",
          "price_change_24h",
          "volume_usd_24h",
          "trades_24h"
        ],
        "properties": {
          "chain": {
            "$ref": "#/components/schemas/ChainName"
          },
          "id": {
            "$ref": "#/components/schemas/PoolIdentifier"
          },
          "protocol": {
            "description": "The dex's protocol label, e.g. `uniswap_v3`.",
            "type": "string"
          },
          "family": {
            "description": "The pool's contract family.",
            "type": "string",
            "enum": [
              "v2",
              "v3",
              "v4",
              "solidly"
            ]
          },
          "token0": {
            "$ref": "#/components/schemas/TokenRef"
          },
          "token1": {
            "$ref": "#/components/schemas/TokenRef"
          },
          "fee": {
            "description": "The fee the pool was created with, in hundredths of a basis point (500 = 0.05%); 8388608 marks a dynamic Uniswap v4 fee. Null for pools created without one.",
            "type": [
              "integer",
              "null"
            ]
          },
          "tick_spacing": {
            "type": [
              "integer",
              "null"
            ]
          },
          "stable": {
            "description": "Solidly pools only, whether the pool uses the stable curve.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "hooks": {
            "description": "Uniswap v4 pools only, the hooks address; served pools have none, so it is the zero address.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_block": {
            "type": "integer"
          },
          "created_time": {
            "type": "string",
            "format": "date-time"
          },
          "indexed": {
            "description": "Whether the pool is listed. A pool that is not has no stored candles and never prices a token; its 24-hour figures come from its candidate trades, and its USD volume counts only trades with a USD value.",
            "type": "boolean"
          },
          "anchor_liquidity_usd": {
            "description": "USD the anchor side held at the last screening.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price": {
            "description": "Whole token1 per whole token0 from the latest state.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price_change_24h": {
            "description": "Relative change against the price about 24 hours ago; null without both prices.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "volume_usd_24h": {
            "$ref": "#/components/schemas/Decimal"
          },
          "trades_24h": {
            "type": "integer"
          }
        }
      },
      "PoolList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Pool"
            }
          }
        }
      },
      "Trade": {
        "type": "object",
        "required": [
          "block_number",
          "log_index",
          "time",
          "tx_hash",
          "trader",
          "amount0",
          "amount1",
          "price",
          "amount_usd",
          "price0_usd",
          "price1_usd"
        ],
        "properties": {
          "block_number": {
            "type": "integer"
          },
          "log_index": {
            "type": "integer"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          },
          "tx_hash": {
            "$ref": "#/components/schemas/TxHash"
          },
          "trader": {
            "description": "The transaction's sender, when known.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "amount0": {
            "description": "Raw token0 amount in the pool's view (positive = the pool received it).",
            "$ref": "#/components/schemas/RawAmount"
          },
          "amount1": {
            "description": "Raw token1 amount in the pool's view (positive = the pool received it).",
            "$ref": "#/components/schemas/RawAmount"
          },
          "price": {
            "description": "Whole token1 per whole token0 this trade executed at.",
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "amount_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price0_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "price1_usd": {
            "$ref": "#/components/schemas/NullableDecimal"
          }
        }
      },
      "Candle": {
        "type": "object",
        "required": [
          "time",
          "open",
          "high",
          "low",
          "close",
          "volume_usd",
          "trades"
        ],
        "properties": {
          "time": {
            "description": "Bucket start, Unix seconds.",
            "type": "integer"
          },
          "open": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "high": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "low": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "close": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "volume_usd": {
            "$ref": "#/components/schemas/Decimal"
          },
          "trades": {
            "type": "integer"
          }
        }
      },
      "PoolCandle": {
        "description": "Prices in the currency and for the side asked; null when no trade in the bucket had one. Volumes are raw amounts of both tokens.",
        "type": "object",
        "required": [
          "time",
          "open",
          "high",
          "low",
          "close",
          "volume_usd",
          "trades",
          "volume0",
          "volume1"
        ],
        "properties": {
          "time": {
            "description": "Bucket start, Unix seconds.",
            "type": "integer"
          },
          "open": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "high": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "low": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "close": {
            "$ref": "#/components/schemas/NullableDecimal"
          },
          "volume_usd": {
            "$ref": "#/components/schemas/Decimal"
          },
          "trades": {
            "type": "integer"
          },
          "volume0": {
            "$ref": "#/components/schemas/RawAmount"
          },
          "volume1": {
            "$ref": "#/components/schemas/RawAmount"
          }
        }
      },
      "OnchainError": {
        "type": "object",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "type": "object",
              "required": [
                "status",
                "title"
              ],
              "properties": {
                "status": {
                  "description": "The HTTP status, as a string.",
                  "type": "string"
                },
                "title": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ResourceId": {
        "description": "`{network}_{address}`.",
        "type": "string",
        "pattern": "^(eth|base|bsc|arbitrum|polygon_pos)_0x([0-9a-f]{40}|[0-9a-f]{64})$"
      },
      "Relationship": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "token",
                  "dex",
                  "network",
                  "pool"
                ]
              }
            }
          }
        }
      },
      "WindowDecimals": {
        "description": "One value per rolling window, from 5 minutes to 24 hours.",
        "type": "object",
        "required": [
          "m5",
          "m15",
          "m30",
          "h1",
          "h6",
          "h24"
        ],
        "properties": {
          "m5": {
            "$ref": "#/components/schemas/Decimal"
          },
          "m15": {
            "$ref": "#/components/schemas/Decimal"
          },
          "m30": {
            "$ref": "#/components/schemas/Decimal"
          },
          "h1": {
            "$ref": "#/components/schemas/Decimal"
          },
          "h6": {
            "$ref": "#/components/schemas/Decimal"
          },
          "h24": {
            "$ref": "#/components/schemas/Decimal"
          }
        }
      },
      "WindowTransactions": {
        "type": "object",
        "required": [
          "buys",
          "sells",
          "buyers",
          "sellers"
        ],
        "properties": {
          "buys": {
            "type": "integer"
          },
          "sells": {
            "type": "integer"
          },
          "buyers": {
            "type": "integer"
          },
          "sellers": {
            "type": "integer"
          }
        }
      },
      "NetworkResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/NetworkId"
          },
          "type": {
            "const": "network"
          },
          "attributes": {
            "type": "object",
            "required": [
              "name",
              "coingecko_asset_platform_id"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "coingecko_asset_platform_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "DexResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes"
        ],
        "properties": {
          "id": {
            "description": "GeckoTerminal's dex id, e.g. `uniswap-v4-ethereum`.",
            "type": "string"
          },
          "type": {
            "const": "dex"
          },
          "attributes": {
            "type": "object",
            "required": [
              "name"
            ],
            "properties": {
              "name": {
                "type": "string"
              }
            }
          }
        }
      },
      "TokenResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ResourceId"
          },
          "type": {
            "const": "token"
          },
          "attributes": {
            "type": "object",
            "required": [
              "address",
              "name",
              "symbol",
              "decimals",
              "image_url",
              "coingecko_coin_id"
            ],
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "symbol": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "decimals": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "image_url": {
                "type": "null"
              },
              "coingecko_coin_id": {
                "type": "null"
              }
            }
          }
        }
      },
      "PoolResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes",
          "relationships"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ResourceId"
          },
          "type": {
            "const": "pool"
          },
          "attributes": {
            "type": "object",
            "required": [
              "base_token_price_usd",
              "base_token_price_native_currency",
              "quote_token_price_usd",
              "quote_token_price_native_currency",
              "base_token_price_quote_token",
              "quote_token_price_base_token",
              "address",
              "name",
              "pool_created_at",
              "fdv_usd",
              "market_cap_usd",
              "price_change_percentage",
              "transactions",
              "volume_usd",
              "reserve_in_usd"
            ],
            "properties": {
              "base_token_price_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "base_token_price_native_currency": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "quote_token_price_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "quote_token_price_native_currency": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "base_token_price_quote_token": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "quote_token_price_base_token": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "address": {
                "$ref": "#/components/schemas/PoolIdentifier"
              },
              "name": {
                "description": "`BASE / QUOTE`, followed by the fee (e.g. `0.05%`) when the pool has a fixed one.",
                "type": "string"
              },
              "pool_created_at": {
                "type": "string",
                "format": "date-time"
              },
              "fdv_usd": {
                "type": "null"
              },
              "market_cap_usd": {
                "type": "null"
              },
              "price_change_percentage": {
                "description": "The base token's price change per window, in percent; `\"0\"` with nothing to compare.",
                "$ref": "#/components/schemas/WindowDecimals"
              },
              "transactions": {
                "type": "object",
                "required": [
                  "m5",
                  "m15",
                  "m30",
                  "h1",
                  "h6",
                  "h24"
                ],
                "properties": {
                  "m5": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  },
                  "m15": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  },
                  "m30": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  },
                  "h1": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  },
                  "h6": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  },
                  "h24": {
                    "$ref": "#/components/schemas/WindowTransactions"
                  }
                }
              },
              "volume_usd": {
                "$ref": "#/components/schemas/WindowDecimals"
              },
              "reserve_in_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "pool_name": {
                "description": "Single-pool and multi-pool lookups only; the name without the fee.",
                "type": "string"
              },
              "pool_fee_percentage": {
                "description": "Single-pool and multi-pool lookups only; the fixed fee in percent, null without one.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "locked_liquidity_percentage": {
                "description": "Single-pool and multi-pool lookups only; always null.",
                "type": "null"
              },
              "base_token_balance": {
                "description": "With `include_composition`; whole base tokens the pool holds (v2-style pools only).",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "base_token_liquidity_usd": {
                "description": "With `include_composition`.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "quote_token_balance": {
                "description": "With `include_composition`; whole quote tokens the pool holds (v2-style pools only).",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "quote_token_liquidity_usd": {
                "description": "With `include_composition`.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "net_buy_volume_usd": {
                "description": "With `include_volume_breakdown`; buy minus sell USD volume.",
                "$ref": "#/components/schemas/WindowDecimals"
              },
              "buy_volume_usd": {
                "description": "With `include_volume_breakdown`.",
                "$ref": "#/components/schemas/WindowDecimals"
              },
              "sell_volume_usd": {
                "description": "With `include_volume_breakdown`.",
                "$ref": "#/components/schemas/WindowDecimals"
              },
              "token_price_usd": {
                "description": "A token's pools and top pools only; that token's USD price in this pool.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "last_trade_timestamp": {
                "description": "A token's pools and top pools only; the pool's last trade, Unix seconds as a string.",
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^[0-9]+$"
              }
            }
          },
          "relationships": {
            "type": "object",
            "required": [
              "base_token",
              "quote_token",
              "dex"
            ],
            "properties": {
              "base_token": {
                "$ref": "#/components/schemas/Relationship"
              },
              "quote_token": {
                "$ref": "#/components/schemas/Relationship"
              },
              "dex": {
                "$ref": "#/components/schemas/Relationship"
              },
              "network": {
                "description": "Lists across networks only.",
                "$ref": "#/components/schemas/Relationship"
              }
            }
          }
        }
      },
      "Included": {
        "description": "Present only when `include` names something; each resource once.",
        "type": "array",
        "items": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/TokenResource"
            },
            {
              "$ref": "#/components/schemas/DexResource"
            },
            {
              "$ref": "#/components/schemas/NetworkResource"
            }
          ]
        }
      },
      "IncludedTopPools": {
        "description": "Present only with `include=top_pools`; the tokens' top pools, each once.",
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/PoolResource"
        }
      },
      "TokenDetailResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes",
          "relationships"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ResourceId"
          },
          "type": {
            "const": "token"
          },
          "attributes": {
            "type": "object",
            "required": [
              "address",
              "name",
              "symbol",
              "decimals",
              "image_url",
              "coingecko_coin_id",
              "total_supply",
              "normalized_total_supply",
              "price_usd",
              "fdv_usd",
              "total_reserve_in_usd",
              "volume_usd",
              "market_cap_usd",
              "last_trade_timestamp"
            ],
            "properties": {
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "symbol": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "decimals": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "image_url": {
                "type": "null"
              },
              "coingecko_coin_id": {
                "type": "null"
              },
              "total_supply": {
                "type": "null"
              },
              "normalized_total_supply": {
                "type": "null"
              },
              "price_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "fdv_usd": {
                "type": "null"
              },
              "total_reserve_in_usd": {
                "description": "USD the anchor sides of its listed pools hold, added up.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "volume_usd": {
                "type": "object",
                "required": [
                  "h24"
                ],
                "properties": {
                  "h24": {
                    "$ref": "#/components/schemas/Decimal"
                  }
                }
              },
              "market_cap_usd": {
                "type": "null"
              },
              "last_trade_timestamp": {
                "description": "When the price last changed, Unix seconds as a string.",
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^[0-9]+$"
              }
            }
          },
          "relationships": {
            "type": "object",
            "required": [
              "top_pools"
            ],
            "properties": {
              "top_pools": {
                "description": "The token's deepest pools, at most 3.",
                "type": "object",
                "required": [
                  "data"
                ],
                "properties": {
                  "data": {
                    "type": "array",
                    "maxItems": 3,
                    "items": {
                      "type": "object",
                      "required": [
                        "id",
                        "type"
                      ],
                      "properties": {
                        "id": {
                          "$ref": "#/components/schemas/ResourceId"
                        },
                        "type": {
                          "const": "pool"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "MetaToken": {
        "type": "object",
        "required": [
          "name",
          "symbol",
          "coingecko_coin_id",
          "address"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "symbol": {
            "type": [
              "string",
              "null"
            ]
          },
          "coingecko_coin_id": {
            "type": "null"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          }
        }
      },
      "OhlcvDocument": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "id",
              "type",
              "attributes"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "type": {
                "const": "ohlcv_request_response"
              },
              "attributes": {
                "type": "object",
                "required": [
                  "ohlcv_list"
                ],
                "properties": {
                  "ohlcv_list": {
                    "description": "Newest first. Each row is `[time, open, high, low, close, volume]`: the bucket start in Unix seconds, the prices, and the volume: in USD, or with `currency=token` in whole units of the token the prices are in, as on GeckoTerminal.",
                    "type": "array",
                    "items": {
                      "type": "array",
                      "prefixItems": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "number"
                        }
                      ],
                      "minItems": 6,
                      "maxItems": 6
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "base",
              "quote"
            ],
            "properties": {
              "base": {
                "description": "The token priced.",
                "$ref": "#/components/schemas/MetaToken"
              },
              "quote": {
                "description": "The token it is priced against; null for a token's candles when it has no pool.",
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/MetaToken"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        }
      },
      "TradeResource": {
        "type": "object",
        "required": [
          "id",
          "type",
          "attributes"
        ],
        "properties": {
          "id": {
            "description": "`{network}_{block}_{tx_hash}_{log_index}_{unix_seconds}`.",
            "type": "string"
          },
          "type": {
            "const": "trade"
          },
          "attributes": {
            "type": "object",
            "required": [
              "block_number",
              "tx_hash",
              "tx_from_address",
              "from_token_amount",
              "to_token_amount",
              "price_from_in_currency_token",
              "price_to_in_currency_token",
              "price_from_in_usd",
              "price_to_in_usd",
              "block_timestamp",
              "kind",
              "volume_in_usd",
              "from_token_address",
              "to_token_address"
            ],
            "properties": {
              "block_number": {
                "type": "integer"
              },
              "tx_hash": {
                "$ref": "#/components/schemas/TxHash"
              },
              "tx_from_address": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Address"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "from_token_amount": {
                "description": "Whole tokens the trader paid.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "to_token_amount": {
                "description": "Whole tokens the trader received.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "price_from_in_currency_token": {
                "description": "Price in the native coin; null unless one side is the native coin or its wrapped token.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "price_to_in_currency_token": {
                "description": "Price in the native coin; null unless one side is the native coin or its wrapped token.",
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "price_from_in_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "price_to_in_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "block_timestamp": {
                "type": "string",
                "format": "date-time"
              },
              "kind": {
                "description": "Whether the trader bought or sold the side named by `token`.",
                "type": "string",
                "enum": [
                  "buy",
                  "sell"
                ]
              },
              "volume_in_usd": {
                "$ref": "#/components/schemas/NullableDecimal"
              },
              "from_token_address": {
                "$ref": "#/components/schemas/Address"
              },
              "to_token_address": {
                "$ref": "#/components/schemas/Address"
              }
            }
          }
        }
      },
      "AddressMap": {
        "description": "Keyed by the lowercase token addresses asked.",
        "type": "object",
        "propertyNames": {
          "$ref": "#/components/schemas/Address"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/Decimal"
        }
      },
      "SimpleTokenPriceDocument": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "id",
              "type",
              "attributes"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "type": {
                "const": "simple_token_price"
              },
              "attributes": {
                "type": "object",
                "required": [
                  "token_prices",
                  "last_trade_timestamp"
                ],
                "properties": {
                  "token_prices": {
                    "description": "USD price per token.",
                    "$ref": "#/components/schemas/AddressMap"
                  },
                  "market_cap_usd": {
                    "description": "With `include_market_cap`; null per token.",
                    "type": "object",
                    "propertyNames": {
                      "$ref": "#/components/schemas/Address"
                    },
                    "additionalProperties": {
                      "type": "null"
                    }
                  },
                  "h24_volume_usd": {
                    "description": "With `include_24hr_vol`.",
                    "$ref": "#/components/schemas/AddressMap"
                  },
                  "h24_price_change_percentage": {
                    "description": "With `include_24hr_price_change`; percent, `\"0\"` with nothing to compare.",
                    "$ref": "#/components/schemas/AddressMap"
                  },
                  "total_reserve_in_usd": {
                    "description": "With `include_total_reserve_in_usd`; tokens without a known reserve are left out.",
                    "$ref": "#/components/schemas/AddressMap"
                  },
                  "last_trade_timestamp": {
                    "description": "When each price last changed, Unix seconds as a string; tokens without one are left out.",
                    "type": "object",
                    "propertyNames": {
                      "$ref": "#/components/schemas/Address"
                    },
                    "additionalProperties": {
                      "type": "string",
                      "pattern": "^[0-9]+$"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
