sifting/io
GET/v1/last/tvl/:chain/:pair

Aggregated TVL · per chain, per pair

Total value locked for a specific token pair on a specific chain. Sums across every pool MarketEngine tracks for that pair on that chain (concentrated-liquidity AMMs across fee tiers, stable-pair AMMs, etc.).

Format
JSON

Example

request · shell
curl -H "X-API-Key: $KEY" \
  "https://api.sifting.io/v1/last/tvl/polygon/WETH-USDC"
200OKapplication/json
{  "chain": "polygon",  "pair": "WETH-USDC",  "usd": "231543.82179",  "r0": "153.96483",  "r1": "231543.82179",  "n": 1,  "v": 1,  "t": 1777813200526}
Loading runner…
First load only

Parameters

Parameter
chainrequiredenum · path
eth | base | arbitrum | bsc | polygon, see chain whitelist above.
pairrequiredstring · path
TOKEN0-TOKEN1, single hyphen separator. Each leg is 3–10 uppercase alphanumeric (e.g. WETH-USDC).

Response fields

Field
chainstring
Echoed chain segment.
pairstring
Echoed pair.
usdstring
Total USD value locked across all contributing pools, full precision.
r0 / r1string
Summed reserves of token0 / token1, raw token units.
ninteger
Number of pools contributing to this aggregation.
vinteger
Schema version.
tint64 (epoch ms)
Timestamp, Unix epoch milliseconds.

Reference

TVL and reserves are strings, cast before math
Why
usd, r0, and r1 come back as JSON strings to preserve full precision. n, v, and t are numbers.
The trap
Math on the raw fields breaks: Python raises TypeError, JavaScript + silently joins the strings instead of adding.
Python
tvl = float(data["usd"])
JavaScript
const tvl = Number(data.usd);
cURL / jq
Cast in jq too: jq '.usd | tonumber'
Historical bars differ
Bars from /v1/hist/* already return t, o, h, l, c, v as plain numbers, do not cast those.

Error responses

  • 503stale_snapshot

    TVL snapshot is older than the staleness threshold.

    {  "error": "stale_snapshot",  "last_t": 1777813100000,  "server_now": 1777813300000}

More in Live market data

See all