Developers
Data API
Every metric on the Topaz stats dashboard is exposed as a public, typed JSON API. Build dashboards, monitors, vaults, or risk tools against the same data the protocol publishes for itself — no indexer, no API key, no rate limits beyond standard CDN caching.
Base URL & format
All endpoints are GET, return JSON, and live under a single base path:
https://www.topazdex.com/api/stats/...Chain context is fixed: every response includes meta.chainId: 56 (BNB Chain mainnet). No authentication is required. Access-Control-Allow-Origin: * is sent on every response; the API can be called directly from a browser.
Discovery & machine-readable docs
The full API surface is published as an OpenAPI 3.1 specification so you can generate clients in any language, browse interactively, or point agent runtimes at the catalog without hand-coding.
| Parameter | Value | Description |
|---|---|---|
| /api/stats/openapi.json | OpenAPI 3.1 | Machine-readable spec. Feed it to openapi-typescript, openapi-generator, Postman, Insomnia, or any LLM tooling that consumes OpenAPI. |
| /api/stats/docs | Swagger UI | Human-browsable docs with “Try it out” buttons that hit the live API. The URL to share with external integrators. |
| /.well-known/api-catalog | RFC 9727 linkset | Standardized discovery pointer — JSON linkset referencing the OpenAPI spec, the Swagger UI, and the agent skill manifest. |
| /skill.json + /skill.md | Agent skill | Topaz agent skill manifest. Each fetch now includes an analytics_api block enumerating every endpoint. |
# Generate a typed TS client from the spec
npx openapi-typescript https://www.topazdex.com/api/stats/openapi.json -o topaz-api.ts
# Browse interactively
open https://www.topazdex.com/api/stats/docs
# Discover programmatically
curl https://www.topazdex.com/.well-known/api-catalogResponse envelope
Every endpoint — success or failure — returns the same outer shape:
// Success
{
"ok": true,
"data": T, // endpoint-specific payload
"meta": {
"chainId": 56,
"generatedAt": "2026-05-22T18:00:00.000Z",
"snapshotAt": "2026-05-22T17:00:00.000Z", // when present
"source": ["topaz-subgraph-v3", "bsc-rpc"],
"cacheTtlSeconds": 60
}
}
// Failure
{
"ok": false,
"error": { "code": "pools_query_failed", "message": "..." },
"meta": { "chainId": 56, "generatedAt": "...", "source": [...] }
}The discriminant is the boolean ok field. HTTP status mirrors the envelope: 200 for success, 4xx/5xx for failure (with 503 reserved for the health endpoint when snapshots are stale).
Every snapshot-backed response carries a weak ETag derived from meta.snapshotAt (e.g. W/"snap-2026-05-28T18:15:43.500Z"). The header is emitted regardless of whether the client sent If-None-Match — so HTTP caches, proxies, and clients can short-circuit unchanged payloads.
Snapshot model & caching
The data layer is snapshot-backed. A scheduled job runs every 15 minutes, reads the Topaz v2 and Slipstream subgraphs plus on-chain state, and writes versioned snapshot rows. All endpoints (except /live/*) read from snapshot tables — so two callers hitting the API back-to-back see identical numbers until the next snapshot lands.
Caching is layered:
- Next.js ISR — most routes are revalidated every
60s(/configand/competitors*every300s). - snapshotAt — the actual data is only as fresh as the most recent successful snapshot, reported via
meta.snapshotAt. - Live endpoints —
/live/*bypass snapshots and read RPC with a short edge cache (stale-while-revalidate=30).
snapshotAt timestamp to detect when a fresh snapshot has actually landed.Error codes
| Parameter | Value | Description |
|---|---|---|
| invalid_pool_id | 400 | Pool path parameter is not a 0x-prefixed 40-char hex address. |
| *_query_failed | 500 | The underlying snapshot query threw — usually transient. Retry with backoff. |
| live_dynamic_fees_failed | 500 | RPC call for live dynamic-fee data failed. Falls back to the snapshot if you call /api/stats/dynamic-fees instead. |
| health endpoint unhealthy | 503 | Returned by /api/stats/health when the most recent snapshot is stale or failing. |
Endpoints
Grouped by what they describe. Every endpoint shares the envelope above; the per-endpoint notes below cover query parameters, examples, and what's in data. For full request schemas, response types, and an interactive “Try it out” surface, see /api/stats/docs (Swagger UI over the OpenAPI 3.1 spec).
Protocol
Protocol-wide aggregates: TVL (v2 + Slipstream), 24h / 7d / 30d volume and fees, active gauges, emissions this epoch, total veTOPAZ supply and voting power. Returns the most recent successful snapshot row.
curl https://www.topazdex.com/api/stats/protocolAll successful 15-min snapshots within the window. Chronological; feed it straight to a chart library. Returns snapshotAt, tvlUsd (v2 + v3), volume24hUsd, fees24hUsd, and topazPriceUsd.
| Parameter | Value | Description |
|---|---|---|
| days | 1-365 | Lookback window (default: 30). |
curl "https://www.topazdex.com/api/stats/protocol/history?days=7"One row per UTC day with the closed daily volume and fees totals. The current UTC day is in-progress and marked partial: true so charts can render it differently. Use this instead of /historyfor daily bar charts — it dedupes the subgraph's running daily total.
| Parameter | Value | Description |
|---|---|---|
| days | 1-365 | Lookback window (default: 30). |
curl "https://www.topazdex.com/api/stats/protocol/daily?days=30"Pools
Every v2 and Slipstream pool, with TVL, 24h volume, 24h fees, fee APR, gauge APR, and pool-type metadata. Default sort is tvl descending.
| Parameter | Value | Description |
|---|---|---|
| sort | tvl | volume24h | fees24h | apr | gaugeApr | Sort key (default: tvl). |
| type | all | v2 | v3 | Pool type filter (v3 = Slipstream concentrated liquidity). Default: all. |
| limit | 1-500 | Cap the number of pools returned (default: 50). |
| pair | string (e.g. WBNB-USDT) | Filter to a specific token-symbol pair. Either order works. |
| token | 0x address | Filter to pools where the given token sits on either side of the pair. |
| minTvl | USD float | Drop pools below this TVL — useful for dapp pickers to hide dust. |
| incentivized | true | 1 | Only pools whose gauge is alive and currently emitting TOPAZ. |
curl "https://www.topazdex.com/api/stats/pools?sort=gaugeApr&incentivized=true&minTvl=10000&limit=20"Full snapshot for a single pool, the last 672 snapshots (~1 week at 15-min cadence), and — in the same response — the associated gauge plus its APR history. The payload shape is { current, history, gauge, gaugeHistory }. poolId must be a 0x-prefixed 40-char hex address; an invalid_pool_id error is returned otherwise.
curl https://www.topazdex.com/api/stats/pools/0x1234abcd...Path-style alias for /bribes?pool=… — same response shape, easier to compose from resource URLs.
| Parameter | Value | Description |
|---|---|---|
| limit | 1-1000 | Cap rows returned (default: 100). |
| epoch | unix seconds | Filter to a single epoch start. |
| foundationOnly | true | 1 | Only foundation-funded bribes. |
curl "https://www.topazdex.com/api/stats/pools/0xabcd.../bribes?limit=50"One row per UTC day with volumeUsd, feesUsd, and end-of-day tvlUsdClose. Backed by its own table seeded from subgraph day-data each snapshot, so the window can extend well past the 7-day rolling snapshot window.
| Parameter | Value | Description |
|---|---|---|
| days | 1-365 | Lookback window (default: 90). |
curl "https://www.topazdex.com/api/stats/pools/0xabcd.../daily?days=90"Gauges
All live gauges, their pool address, pool type, total votes this epoch, foundation vote share, and APR breakdown (emission, fee, bribe, total). Read on-chain via bsc-rpc, snapshotted every 15 minutes.
curl https://www.topazdex.com/api/stats/gaugesCurrent snapshot plus history of the APR breakdown over time (emission, fee, bribe, total). Same { current, history } shape as the pool detail endpoint.
curl https://www.topazdex.com/api/stats/gauges/0xabcd...Event log of every bribe deposit routed to this gauge, newest first. Mirrors the pool bribes endpoint at the gauge level — same query params apply.
curl https://www.topazdex.com/api/stats/gauges/0xabcd.../bribesPer-epoch foundation KPI rows for this gauge: vote weight, bribe cost, emissions directed, TVL/volume/fee deltas, and the scale / repeat / monitor / reduce / stop classification.
curl https://www.topazdex.com/api/stats/gauges/0xabcd.../kpisToken-by-token bribe and fee reward amounts per epoch, USD-priced at deposit time. Use this to answer “which tokens has this gauge been bribed with over the last N weeks?”
| Parameter | Value | Description |
|---|---|---|
| limit | 1-200 | Cap rows returned (default: 12). |
curl https://www.topazdex.com/api/stats/gauges/0xabcd.../rewardsveTOPAZ
Aggregate veTOPAZ statistics: total locked TOPAZ, total voting power, average lock duration, count of locks, permanent vs decaying breakdown.
curl https://www.topazdex.com/api/stats/veVotes
Per-vote records: which veNFT voted, which pool, weight allocated, and the epoch it was cast in. Defaults to the latest epoch only.
| Parameter | Value | Description |
|---|---|---|
| epoch | unix seconds | Epoch start timestamp. Filter votes cast in this epoch. |
| venftId | number | Filter to a single veNFT token ID. |
| pool | 0x address | Filter to votes for a specific pool address. |
| latestOnly | true | false | Return only the most recent epoch (default: true). Set to false for the full history. |
curl "https://www.topazdex.com/api/stats/votes?latestOnly=false&venftId=9"Bribes
Bribe deposits with token, USD value at deposit (priced block-accurately at deposit time), epoch, and target pool. Supports filtering to foundation-claimed bribes only.
| Parameter | Value | Description |
|---|---|---|
| pool | 0x address | Filter to bribes for a specific pool. |
| foundationOnly | true | 1 | Limit to bribes that intersect the foundation's vote allocation. |
| epoch | unix seconds | Filter to a specific epoch. |
| limit | number | Cap the number of bribes returned. |
curl "https://www.topazdex.com/api/stats/bribes?pool=0xabcd...&limit=50"Aggregated foundation bribe spend, one row per epoch (up to 52). Returns { epochStart, totalUsd, count }.
curl https://www.topazdex.com/api/stats/bribes/totalsTokens
Every token referenced by a tracked v2 or v3 pool, with symbol, decimals, current priceUsd, and the subgraph's derivedEth ratio. Sorted by USD price descending. Use this to avoid round-tripping the subgraph for token-level pricing.
| Parameter | Value | Description |
|---|---|---|
| limit | 1-500 | Cap rows returned (default: 100). |
curl https://www.topazdex.com/api/stats/tokensReturns { current, history } with up to 672 historical price points (~7 days at 15-min cadence) for charting token price.
curl https://www.topazdex.com/api/stats/tokens/0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095cEpochs
One row per epoch (newest first) with total bribes deposited, foundation bribe spend, foundation vote share, gauge count, and the top-voted gauges in that epoch (with token symbols joined). Use this for epoch-countdown UIs and weekly recap dashboards.
| Parameter | Value | Description |
|---|---|---|
| limit | 1-52 | How many recent epochs to return (default: 12). |
curl "https://www.topazdex.com/api/stats/epochs?limit=8"All foundation votes, bribe deposits, and KPI rows for one epoch. Vote and KPI lists are restricted to a representative snapshot within the epoch so payload size stays bounded. epochStart is Unix seconds (epochs are 7-day Thursday-aligned in BNB Chain UTC).
curl https://www.topazdex.com/api/stats/epochs/1779321600Markets
Per-gauge reward state for an epoch: total bribes deposited, total fees accrued, current vote weight, and derived dollarPerVote. Sorted by total reward USD descending so the highest-yield gauges surface first. Defaults to the most recent epoch with rewards data.
| Parameter | Value | Description |
|---|---|---|
| epoch | unix seconds | Filter to a specific epoch. |
| minUsd | USD float | Drop gauges with total reward USD below this floor (default: 0). |
| limit | 1-500 | Cap rows returned (default: 100). |
curl "https://www.topazdex.com/api/stats/markets/bribes?minUsd=100&limit=25"Foundation
Top-level foundation view: total veTOPAZ held, voting power, current epoch vote allocation, lifetime bribes / fees claimed. Mirrors what renders on the Foundation stats page.
curl https://www.topazdex.com/api/stats/foundationSame vote data as /votes but scoped to the foundation's veNFTs. Defaults to the latest epoch.
| Parameter | Value | Description |
|---|---|---|
| epoch | unix seconds | Filter to a specific epoch. |
| latestOnly | true | false | Default true. Set false for full history. |
curl https://www.topazdex.com/api/stats/foundation/votesBribes the foundation has claimed, with token, USD value at claim time, source pool, and epoch.
| Parameter | Value | Description |
|---|---|---|
| limit | number | Cap rows returned. |
| epoch | unix seconds | Filter to one epoch. |
| pool | 0x address | Filter to bribes from a specific pool. |
curl "https://www.topazdex.com/api/stats/foundation/bribes?limit=100"For each gauge the foundation has voted on, classifies vote ROI as one of scale, repeat, monitor, reduce, stop, or insufficient_data, with the supporting metrics (bribes earned vs vote weight, fees generated, etc.).
| Parameter | Value | Description |
|---|---|---|
| epoch | unix seconds | Filter to a specific epoch. |
| pool | 0x address | Filter to a single pool. |
| limit | number | Cap rows returned. |
curl https://www.topazdex.com/api/stats/foundation/kpisDynamic fees
Every Slipstream pool that has dynamic fees turned on, with current fee level, baseline, and how often the fee has flexed. Snapshot-backed.
curl https://www.topazdex.com/api/stats/dynamic-feesBypasses snapshots and reads the current fee pips directly from each pool via RPC. Edge-cached for a few seconds with stale-while-revalidate=30. Use this when you need real-time fee values; use /dynamic-fees for everything else.
curl https://www.topazdex.com/api/stats/live/dynamic-feesCompetitors
Reserved for cross-DEX benchmarking on tracked pairs. Currently returns { available: false } — the endpoint surface is stable so integrators can poll without breaking once data lands.
curl https://www.topazdex.com/api/stats/competitorsSame as above, scoped to a single tracked pair key. The response reports whether the pair is recognized so you can validate keys before the data is wired up.
curl https://www.topazdex.com/api/stats/competitors/wbnb-usdtConfig
The transparency manifest. Returns:
chainId— always 56.methodologyVersion— version pin matching the methodology page.snapshotIntervalMinutes— cadence of the snapshot job.foundation.walletandfoundation.veNftIds— the foundation wallet and the veNFT IDs it holds.trackedPairs— the canonical pair keys used for filtering.contracts— full Topaz contract address book (also rendered at /docs/contracts).lastSuccessfulSnapshot— id + timestamp of the most recent snapshot run.
curl https://www.topazdex.com/api/stats/configHealth
Designed for uptime monitors. Returns 200 with { healthy: true, ... } when snapshots are fresh, or 503 when stale. Marked dynamic = "force-dynamic" so it's never cached.
curl -i https://www.topazdex.com/api/stats/healthStability
The endpoint surface and response envelope are stable. Fields inside data may be added over time; field removals or shape changes will be versioned via the methodologyVersion in /api/stats/config.
The OpenAPI spec is the contract. Generate clients from it, validate responses against it, or feed it to an agent. Any breaking change will bump the spec version and be flagged in the changelog before it lands in production.
The internal snapshot trigger (/api/cron/analytics-snapshot) is Bearer-authenticated and not for public use — it's listed only so integrators understand where the snapshots come from.
Continue reading
Swagger UI →
Interactive docs with Try-it-out buttons over the OpenAPI spec.
OpenAPI spec →
Machine-readable contract. Feed it to openapi-typescript or any client generator.
Stats Overview →
What the dashboards show and how the data is produced.
Methodology (live) →
Per-metric definitions, sources, and known caveats. Versioned.
Foundation Dashboard (live) →
Live view of the data exposed by /api/stats/foundation.
Contracts →
Every Topaz contract address — also returned in /api/stats/config.
