TopazTOPAZDocs

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. Standard CORS headers are sent; the API can be called directly from a browser.

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

Snapshot model & caching

The data layer is snapshot-backed. A scheduled job runs every ~60 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.

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

Pools

GET/api/stats/poolsranked / filtered pool list

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

ParameterValueDescription
sorttvl | volume24h | fees24h | aprSort key (default: tvl).
typeall | v2 | v3Pool type filter (v3 = Slipstream concentrated liquidity). Default: all.
limitnumberCap the number of pools returned.
pairstringFilter to a specific tracked pair key (see /config for valid keys).
curl "https://www.topazdex.com/api/stats/pools?sort=volume24h&type=v3&limit=10"
GET/api/stats/pools/{poolId}per-pool detail + 168h history

Full snapshot for a single pool, plus the last 168 hourly snapshots (one week) for charting. 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...

Gauges

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

All live gauges, their pool address, pool type, total votes this epoch, and pending bribes. Read on-chain via bsc-rpc, snapshotted hourly.

curl https://www.topazdex.com/api/stats/gauges

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"

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