TopazDocs

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.

ParameterValueDescription
/api/stats/openapi.jsonOpenAPI 3.1Machine-readable spec. Feed it to openapi-typescript, openapi-generator, Postman, Insomnia, or any LLM tooling that consumes OpenAPI.
/api/stats/docsSwagger UIHuman-browsable docs with “Try it out” buttons that hit the live API. The URL to share with external integrators.
/.well-known/api-catalogRFC 9727 linksetStandardized discovery pointer — JSON linkset referencing the OpenAPI spec, the Swagger UI, and the agent skill manifest.
/skill.json + /skill.mdAgent skillTopaz 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-catalog

Response envelope

Every endpoint — success or failure — returns the same outer shape:

typescript
// 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 (/config and /competitors* every 300s).
  • 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).
Sustained polling
Don't poll faster than 60s — you'll just get cached responses. Use the snapshotAt timestamp to detect when a fresh snapshot has actually landed.

Error codes

ParameterValueDescription
invalid_pool_id400Pool path parameter is not a 0x-prefixed 40-char hex address.
*_query_failed500The underlying snapshot query threw — usually transient. Retry with backoff.
live_dynamic_fees_failed500RPC call for live dynamic-fee data failed. Falls back to the snapshot if you call /api/stats/dynamic-fees instead.
health endpoint unhealthy503Returned 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

GET/api/stats/protocollatest protocol snapshot

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/protocol
GET/api/stats/protocol/historysnapshot-resolution time-series

All successful 15-min snapshots within the window. Chronological; feed it straight to a chart library. Returns snapshotAt, tvlUsd (v2 + v3), volume24hUsd, fees24hUsd, and topazPriceUsd.

ParameterValueDescription
days1-365Lookback window (default: 30).
curl "https://www.topazdex.com/api/stats/protocol/history?days=7"
GET/api/stats/protocol/dailydaily volume & fee rollups

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.

ParameterValueDescription
days1-365Lookback window (default: 30).
curl "https://www.topazdex.com/api/stats/protocol/daily?days=30"

Pools

GET/api/stats/poolsranked / filtered pool list

Every v2 and Slipstream pool, with TVL, 24h volume, 24h fees, fee APR, gauge APR, and pool-type metadata. Default sort is tvl descending.

ParameterValueDescription
sorttvl | volume24h | fees24h | apr | gaugeAprSort key (default: tvl).
typeall | v2 | v3Pool type filter (v3 = Slipstream concentrated liquidity). Default: all.
limit1-500Cap the number of pools returned (default: 50).
pairstring (e.g. WBNB-USDT)Filter to a specific token-symbol pair. Either order works.
token0x addressFilter to pools where the given token sits on either side of the pair.
minTvlUSD floatDrop pools below this TVL — useful for dapp pickers to hide dust.
incentivizedtrue | 1Only 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"
GET/api/stats/pools/{poolId}per-pool detail + 168h history

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...
GET/api/stats/pools/{poolId}/bribesbribes routed to this pool's gauge

Path-style alias for /bribes?pool=… — same response shape, easier to compose from resource URLs.

ParameterValueDescription
limit1-1000Cap rows returned (default: 100).
epochunix secondsFilter to a single epoch start.
foundationOnlytrue | 1Only foundation-funded bribes.
curl "https://www.topazdex.com/api/stats/pools/0xabcd.../bribes?limit=50"
GET/api/stats/pools/{poolId}/dailylong-horizon daily candles

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.

ParameterValueDescription
days1-365Lookback window (default: 90).
curl "https://www.topazdex.com/api/stats/pools/0xabcd.../daily?days=90"

Gauges

GET/api/stats/gaugesevery active gauge with vote weights

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/gauges
GET/api/stats/gauges/{gaugeAddress}gauge detail + APR history

Current 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...
GET/api/stats/gauges/{gaugeAddress}/bribesbribes deposited on this gauge

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.../bribes
GET/api/stats/gauges/{gaugeAddress}/kpisfoundation ROI / classification history

Per-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.../kpis
GET/api/stats/gauges/{gaugeAddress}/rewardsper-epoch reward token breakdown

Token-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?”

ParameterValueDescription
limit1-200Cap rows returned (default: 12).
curl https://www.topazdex.com/api/stats/gauges/0xabcd.../rewards

veTOPAZ

GET/api/stats/veveTOPAZ supply & lock stats

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/ve

Votes

GET/api/stats/votesfoundation votes by epoch / veNFT / pool

Per-vote records: which veNFT voted, which pool, weight allocated, and the epoch it was cast in. Defaults to the latest epoch only.

ParameterValueDescription
epochunix secondsEpoch start timestamp. Filter votes cast in this epoch.
venftIdnumberFilter to a single veNFT token ID.
pool0x addressFilter to votes for a specific pool address.
latestOnlytrue | falseReturn 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

GET/api/stats/bribesbribes deposited per pool / epoch

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.

ParameterValueDescription
pool0x addressFilter to bribes for a specific pool.
foundationOnlytrue | 1Limit to bribes that intersect the foundation's vote allocation.
epochunix secondsFilter to a specific epoch.
limitnumberCap the number of bribes returned.
curl "https://www.topazdex.com/api/stats/bribes?pool=0xabcd...&limit=50"
GET/api/stats/bribes/totalsfoundation bribe spend per epoch

Aggregated foundation bribe spend, one row per epoch (up to 52). Returns { epochStart, totalUsd, count }.

curl https://www.topazdex.com/api/stats/bribes/totals

Tokens

GET/api/stats/tokenstokens priced in the latest snapshot

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.

ParameterValueDescription
limit1-500Cap rows returned (default: 100).
curl https://www.topazdex.com/api/stats/tokens
GET/api/stats/tokens/{address}per-token current + price history

Returns { 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/0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c

Epochs

GET/api/stats/epochsrecent epoch summaries

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.

ParameterValueDescription
limit1-52How many recent epochs to return (default: 12).
curl "https://www.topazdex.com/api/stats/epochs?limit=8"
GET/api/stats/epochs/{epochStart}single-epoch detail (votes, bribes, KPIs)

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/1779321600

Markets

GET/api/stats/markets/bribescurrent bribe markets ($/vote)

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.

ParameterValueDescription
epochunix secondsFilter to a specific epoch.
minUsdUSD floatDrop gauges with total reward USD below this floor (default: 0).
limit1-500Cap rows returned (default: 100).
curl "https://www.topazdex.com/api/stats/markets/bribes?minUsd=100&limit=25"

Foundation

GET/api/stats/foundationfoundation summary (positions + activity)

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/foundation
GET/api/stats/foundation/votesfoundation-only vote records

Same vote data as /votes but scoped to the foundation's veNFTs. Defaults to the latest epoch.

ParameterValueDescription
epochunix secondsFilter to a specific epoch.
latestOnlytrue | falseDefault true. Set false for full history.
curl https://www.topazdex.com/api/stats/foundation/votes
GET/api/stats/foundation/bribesfoundation-claimed bribes

Bribes the foundation has claimed, with token, USD value at claim time, source pool, and epoch.

ParameterValueDescription
limitnumberCap rows returned.
epochunix secondsFilter to one epoch.
pool0x addressFilter to bribes from a specific pool.
curl "https://www.topazdex.com/api/stats/foundation/bribes?limit=100"
GET/api/stats/foundation/kpisper-gauge effectiveness classification

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.).

ParameterValueDescription
epochunix secondsFilter to a specific epoch.
pool0x addressFilter to a single pool.
limitnumberCap rows returned.
curl https://www.topazdex.com/api/stats/foundation/kpis

Dynamic fees

GET/api/stats/dynamic-feesCL pools with dynamic fees enabled

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-fees
GET/api/stats/live/dynamic-feeslive RPC read (short cache)

Bypasses 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-fees

Competitors

GET/api/stats/competitorscompetitor comparison index

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/competitors
GET/api/stats/competitors/{pair}per-pair competitor data

Same 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-usdt

Config

GET/api/stats/configpublished configuration & contract addresses

The transparency manifest. Returns:

  • chainId — always 56.
  • methodologyVersion — version pin matching the methodology page.
  • snapshotIntervalMinutes — cadence of the snapshot job.
  • foundation.wallet and foundation.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/config

Health

GET/api/stats/healthsnapshot freshness probe

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/health

Stability

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