## DEX tokens: what the endpoints share

The `/dex/*` endpoints serve on-chain tokens traded on decentralized exchanges — the data
behind DexScan on our website: three ranked lists (Trending, New and Gainers), shorter-window
versions of Trending and Gainers, the chains they cover, and one token at a time.

**Where the numbers come from.** The lists are rebuilt about every two minutes, mainly from
CoinMarketCap's DEX data. A token's market cap
and FDV are those of the asset we list for it (`asset_id`) when we have one, and the list's own
otherwise.

**Naming a token.** A token is named by `chain_slug` — a `slug` from `/dex/chains`, matched
exactly, so case matters — and `address`, its contract address. An address shaped `0x`
followed by 40 hexadecimal digits matches in any case and comes back lower-cased, whatever the
chain; any other address (Solana, Sui) matches only as written. URL-encode both: a slug such as
`bnb-smart-chain-(bep20)` carries parentheses, a Sui address carries `::`.

**Freshness.** `/dex/tokens` and `/dex/tokens/info` carry `data_time`, when the list that
supplied the data was built, and `stale`, `true` once that is more than two hours ago. A list
more than three hours old is not served: the endpoints answer `503` with code `50300` when we
have no **Trending** list younger than that (every `/dex` endpoint here but
`/dex/tokens/history` reads it first), and a New, Gainers or shorter-window list that old, or
missing, reads as empty.

**Field names, if you know our website's DEX API.** The data is the same; the names follow
this API:

| Website (`/api/v2/dex`) | Here |
|:--|:--|
| `chain` | `chain_slug` |
| `price_usd`, `liquidity_usd`, `market_cap_usd`, `fdv_usd` | `price`, `liquidity`, `market_cap`, `fdv` |
| `volume_usd` on a row | `volume_24h`; inside `windows`, `volume` |
| `change_5m`, `change_1h`, `change_4h`, `change_24h` | `percent_change` object, keys `5m`, `1h`, `4h`, `24h`; `change_6h` is not served |
| `launched_at`, `last_trade_at`, `updated_at` (Unix milliseconds) | `launch_time`, `last_trade_time`, `data_time` (RFC3339) |
| `txns`, `traders` (strings) | integers |
| `risk_level` `highRisk` | `high_risk` |
| `logo` missing: `null` | `""` |
| `rank` (position in the filtered list) | not served; `trending_rank` and `chain_rank` are |
| `sort_by` + `sort_order` (or the older `sort_type`), descending by default | `sort=<key>[:asc\|desc]`, keys named as here, ascending by default |
| `page_size` (or the older `size`), up to 200, larger values cut to 200 | `size` or `limit`, up to 100, larger values a `400` |
| filter `*_usd_min` / `*_usd_max`, `change_24h_*`, `change_*` | `*_min` / `*_max`, `percent_change_24h_*`, `percent_change_*` |
