Funding Rates
Funding rates are the periodic payments exchanged between long and short traders on perpetual futures contracts. The Sharpe API aggregates funding rates from 32 exchanges (centralized venues and perp DEXs) into a unified format through a single endpoint with a type parameter. GET /api/funding/rates returns the authoritative venue set: every distinct exchange value in that response is queryable.
The funding book is not crypto-only. Tokenized equity, commodity, index and FX
perps trade on the same venues and are returned by default. Every row carries
an asset_class; pass asset_class=crypto to exclude the rest.
rate is a fraction, not a percent, and it is charged once per
interval_hours. Annualize with rate × (24 / interval_hours) × 365.
Intervals differ per contract. The live book contains 1h, 2h, 4h, 8h and 24h
contracts, and the same venue runs different intervals on different symbols.
Never assume 8 hours.
coin names an asset (since 2026-09-27). It used to match the base_coin
string, so coin=PEPE missed every PEPE contract a venue lists as
1000PEPE or KPEPE; it now returns all of them, and coin=1000PEPE
returns the same set. Rows carry asset_id, asset_symbol,
lot_multiplier, instrument_status and is_live from Sharpe's instrument
master, so a client never has to parse a symbol to tell a lot contract or a
halted market apart. The five fields are null for a contract the master
does not know yet. rate is a fraction of notional, so lot contracts compare
with the rest without rescaling.
Get funding rates
A single endpoint that returns current snapshots, accumulated sums, or historical time series depending on the type parameter.
Query parameters
- Name
type- Type
- string
- Description
The kind of funding rate data to return. One of
current,accumulated,history. Defaults tocurrent.
- Name
coin- Type
- string
- Description
The coin: a ticker (
BTC,ETH,PEPE), a lot or venue spelling (1000PEPE,kPEPE) or the coin's full name (bitcoinresolves toBTC). Case-insensitive, one coin per request.coinnames an asset, not abase_coinstring: every contract of the asset comes back whatever itsbase_coinspelling, soPEPE,1000PEPEandkpepeall return the PEPE contracts listed asPEPE,1000PEPEandKPEPE(readlot_multiplier). A ticker two assets share (BBis BounceBit and BlackBerry) returns both; narrow withasset_class. Optional forcurrentandaccumulated. Required forhistory. A value no perpetual has ever settled returns a 400 error naming what was tried, rather than an empty result set that reads as "this coin has no funding data"; a coin delisted from every venue still resolves, so its history stays queryable.GET /v1/funding/coinslists every ticker carried.
- Name
days- Type
- integer
- Description
Lookback window in days for
type=history. Integer from1to1095. Defaults to30. Ignored for other types.
- Name
exchange- Type
- string
- Description
Narrows the response to one venue. Accepts the slug (
gate-io), the display name exactly as returned in theexchangefield (Gate.io), or the ccxt id. Every venue Sharpe fetches is addressable. The registry is not frozen, so read the current list from an unfiltered response rather than hardcoding one. An unrecognized value returns a 400 error.
- Name
asset_class- Type
- string
- Description
Narrows the response to one underlying category. One of
crypto,equity,commodity,fx,index. Unfiltered by default, so the response carries tokenized equity, commodity, index and FX perps alongside crypto. Applies to type=current and type=accumulated; ignored for type=history. An unrecognized value returns a 400 error.
- Name
margin- Type
- string
- Description
Narrows the response to one collateral convention:
linearfor quote-margined contracts,inversefor coin-margined ones. Unfiltered by default. Applies to type=current and type=accumulated; ignored for type=history. An unrecognized value returns a 400 error.
- Name
limit- Type
- integer
- Description
Maximum number of results per page.
1to5000. When provided, the response includes apaginationobject with cursor-based paging.
- Name
cursor- Type
- string
- Description
Opaque cursor for fetching the next page. Returned in the
pagination.cursorfield of paginated responses.
Request
curl -G https://www.sharpe.ai/api/v1/funding/rates \
-H "Authorization: Bearer sk_live_your_key_here" \
-d type=current
type=current
Returns the latest funding rate snapshot for every exchange-symbol pair. Stale entries older than 6 hours are automatically excluded.
Response fields
- Name
exchange- Type
- string
- Description
The venue's display name, in its exact stored casing:
Binance,Bybit,OKX,Gate.io,Crypto.com,WhiteBIT,edgeX,tradeXYZ. Match on these values, not lowercase slugs.
- Name
symbol- Type
- string
- Description
The trading pair symbol on the exchange (e.g.,
BTCUSDT,ETHUSDT).
- Name
base_coin- Type
- string
- Description
The base ticker as stored for this contract (e.g.,
BTC,ETH). Lot spellings are kept (1000PEPE,KPEPE), so one asset can appear under several; group contracts byasset_id.
- Name
rate- Type
- number
- Description
The current funding rate as a fraction charged once per
interval_hours(e.g.,0.0001= 0.01% per interval). Not a percentage and not annualized.
- Name
predicted_rate- Type
- number | null
- Description
The venue's predicted next funding rate when published; otherwise
null.
- Name
interval_hours- Type
- number
- Description
Hours between funding settlements for this specific contract. The live book contains
1,2,4,8and24; a single venue can run several intervals across its symbols, so read this per row rather than assuming8.
- Name
next_funding_time- Type
- string | null
- Description
ISO 8601 timestamp of the next scheduled funding settlement.
nullon venues that do not publish one.
- Name
updated_at- Type
- string
- Description
ISO 8601 timestamp when this rate was last refreshed.
- Name
margin_type- Type
- string
- Description
Collateral convention for the contract:
linear(quote-margined) orinverse(coin-margined).
- Name
asset_class- Type
- string
- Description
Underlying category:
crypto,equity,commodity,fxorindex. Tokenized-equity perps such as BybitTSLLareequity, notcrypto.
- Name
open_interest- Type
- number | null
- Description
Latest one-sided USD open interest (each contract counted once) for the
(exchange, base_coin)pair when a matching futures row exists.nullwhen no open-interest row matched. That is most rows, since open-interest coverage is narrower than funding coverage. Never0as a stand-in for missing.
- Name
market_cap_rank- Type
- integer | null
- Description
Market-cap rank of the base coin, where
1is the largest.nullwhen the coin is unranked. Sort unranked rows last rather than treatingnullas a rank.
- Name
age_seconds- Type
- number | null
- Description
Age of the row when the response was generated.
nullmeans the source timestamp was invalid or unavailable.
- Name
data_source- Type
- string
- Description
Snapshot provenance. Current database responses use
supabase.
- Name
freshness_sla_seconds- Type
- number
- Description
Operational stale threshold for current rates. The writer runs every 5 minutes and allows a 5-minute grace window, so this is currently
600seconds.
- Name
is_stale- Type
- boolean
- Description
truewhen the row is older than the published freshness target. Rows up to the backwards-compatible six-hour cutoff can therefore be returned while explicitly marked stale.
- Name
asset_id- Type
- string | null
- Description
The asset this contract belongs to in Sharpe's instrument master: the CoinGecko id when the asset was resolved strictly (
bitcoin,pepe), otherwise<class>:<ticker>(equity:bbfor BlackBerry). Every contract of one asset carries the same id whatever itsbase_coinspelling, so group or join on this, never onbase_coin.nullwhen the master does not know the contract yet.
- Name
asset_symbol- Type
- string | null
- Description
The asset's ticker as a trader reads it:
PEPEon the1000PEPEandKPEPEcontracts too.nullwhen the master does not know the contract.
- Name
lot_multiplier- Type
- number | null
- Description
Units of the asset per unit the contract quotes:
1000for Binance1000PEPEUSDT(its price and size are per 1,000 PEPE) and for Coinbase1000PEPE-PERP, whosebase_coinisPEPE;1for Gate.ioPEPE_USDT. Taken from the venue or a checked alias, never parsed from the symbol.rateneeds no scaling.nullwhen unknown.
- Name
instrument_status- Type
- string | null
- Description
The venue's own status for the contract as Sharpe's instruments sync last read it:
trading,halted,delisted,settlingorpre_launch.nullwhen the master does not know the contract.
- Name
is_live- Type
- boolean | null
- Description
truewhen the contract is trading and the venue's contract list was read in the last 30 minutes;falsewhen it was read and the contract is not trading (halted, settling, delisted or not launched);nullwhen that is unknown: no read in 30 minutes, a status value Sharpe could not interpret, or a contract the master does not know. Readnullas unknown, never as halted.
Response (type=current)
{
"data": [
{
"exchange": "Binance",
"symbol": "BTCUSDT",
"base_coin": "BTC",
"rate": 0.0001,
"predicted_rate": 0.00011,
"interval_hours": 4,
"next_funding_time": "2026-03-27T08:00:00Z",
"updated_at": "2026-03-27T07:45:00Z",
"margin_type": "linear",
"asset_class": "crypto",
"open_interest": 1284000000,
"market_cap_rank": 1,
"age_seconds": 0,
"data_source": "supabase",
"freshness_sla_seconds": 600,
"is_stale": false,
"asset_id": "bitcoin",
"asset_symbol": "BTC",
"lot_multiplier": 1,
"instrument_status": "trading",
"is_live": true
},
{
"exchange": "Gate.io",
"symbol": "BTC_USDT",
"base_coin": "BTC",
"rate": 0.00012,
"predicted_rate": null,
"interval_hours": 8,
"next_funding_time": "2026-03-27T08:00:00Z",
"updated_at": "2026-03-27T07:44:30Z",
"margin_type": "linear",
"asset_class": "crypto",
"open_interest": null,
"market_cap_rank": 1,
"age_seconds": 30,
"data_source": "supabase",
"freshness_sla_seconds": 600,
"is_stale": false,
"asset_id": "bitcoin",
"asset_symbol": "BTC",
"lot_multiplier": 1,
"instrument_status": "trading",
"is_live": true
}
],
"meta": {
"request_id": "req_abc123def456ghij",
"timestamp": "2026-03-27T07:45:00Z",
"elapsed_ms": 12
}
}
type=accumulated
Returns pre-computed cumulative funding rate sums and settlement counts across multiple time windows. Useful for calculating net funding cost or income without aggregating history yourself.
The response carries X-Data-As-Of, X-Data-Stale, and X-Freshness-Sla-Seconds from the accumulated pipeline itself. Use each settlements_* field with the contract's native interval_hours before comparing annualized results; the terminal only labels a window complete after at least 90% of its expected settlements are present.
Response fields
- Name
base_coin- Type
- string
- Description
The base asset ticker.
- Name
exchange- Type
- string
- Description
The venue's display name, in its exact stored casing (e.g.
Binance,Gate.io).
- Name
symbol- Type
- string
- Description
The trading pair symbol.
- Name
acc_1d- Type
- number
- Description
Accumulated funding rate over the last 1 day.
- Name
acc_7d- Type
- number
- Description
Accumulated funding rate over the last 7 days.
- Name
acc_30d- Type
- number
- Description
Accumulated funding rate over the last 30 days.
- Name
acc_90d- Type
- number
- Description
Accumulated funding rate over the last 90 days.
- Name
acc_1y- Type
- number
- Description
Accumulated funding rate over the last 1 year.
- Name
settlements_1d- Type
- integer
- Description
Number of funding settlements in the last 1 day.
- Name
settlements_7d- Type
- integer
- Description
Number of funding settlements in the last 7 days.
- Name
settlements_30d- Type
- integer
- Description
Number of funding settlements in the last 30 days.
- Name
settlements_90d- Type
- integer
- Description
Number of funding settlements in the last 90 days.
- Name
settlements_1y- Type
- integer
- Description
Number of funding settlements in the last 1 year.
- Name
interval_hours- Type
- number | null
- Description
The contract's own settlement interval, joined in from the live contract book.
nullwhen no live contract matches(exchange, symbol). Expected settlements for a window areceil(window_hours / interval_hours). Comparesettlements_*against that, never against a fixed 8-hour assumption.
- Name
asset_class- Type
- string | null
- Description
Underlying category, joined in from the live contract book.
nullwhen no live contract matches, rather than being defaulted tocrypto.
- Name
margin_type- Type
- string | null
- Description
Collateral convention, joined in from the live contract book.
nullwhen no live contract matches.
- Name
is_active- Type
- boolean
- Description
falsewhen the accumulated identity has no live contract behind it, meaning a delisted or renamed pair. Those rows keep their accumulated history but carrynullmetadata.
- Name
asset_id- Type
- string | null
- Description
The contract's asset in Sharpe's instrument master, as on
type=currentrows.nullwhen no live contract matches or the master does not know it.
- Name
asset_symbol- Type
- string | null
- Description
The asset's ticker, as on
type=currentrows.
- Name
lot_multiplier- Type
- number | null
- Description
Units of the asset per unit the contract quotes, as on
type=currentrows. Accumulated sums are fractions of notional and need no scaling.
- Name
instrument_status- Type
- string | null
- Description
The venue's own status for the contract, as on
type=currentrows.
- Name
is_live- Type
- boolean | null
- Description
Whether the contract is trading now, as on
type=currentrows;nullis unknown.
Request
curl -G https://www.sharpe.ai/api/v1/funding/rates \
-H "Authorization: Bearer sk_live_your_key_here" \
-d type=accumulated
Response (type=accumulated)
{
"data": [
{
"base_coin": "BTC",
"exchange": "Binance",
"symbol": "BTCUSDT",
"acc_1d": 0.000312,
"acc_7d": 0.002184,
"acc_30d": 0.009360,
"acc_90d": 0.028080,
"acc_1y": 0.112320,
"settlements_1d": 6,
"settlements_7d": 42,
"settlements_30d": 180,
"settlements_90d": 540,
"settlements_1y": 2190,
"interval_hours": 4,
"asset_class": "crypto",
"margin_type": "linear",
"is_active": true,
"asset_id": "bitcoin",
"asset_symbol": "BTC",
"lot_multiplier": 1,
"instrument_status": "trading",
"is_live": true
}
],
"meta": {
"request_id": "req_def456ghi789jklm",
"timestamp": "2026-03-27T07:45:00Z",
"elapsed_ms": 12
}
}
type=history
Returns a time series of individual funding rate payments for a specific coin. Use this for charting, backtesting, or building your own accumulation logic. Results are ordered by settled_at ascending.
A window is served whether or not the coin has that much history: asking for days=1095 on a contract listed 17 months ago is still a 200. Four response headers state what the body actually covers, all derived from the returned rows: X-Requested-Start (the window asked for), X-Coverage-Start (oldest settlement returned, absent when the window returned nothing), X-Data-As-Of (newest settlement returned), and X-Coverage-Complete (false when coverage starts more than seven days after the requested start, or when no rows came back). X-Days-Clamped is always false here because /v1 rejects a days above 1095 with a 400 instead of shortening the window; the unauthenticated /api/funding/rates clamps and reports true.
The coin parameter is required when type=history. Omitting it returns a missing_parameter error.
Response fields
- Name
exchange- Type
- string
- Description
The venue's display name, in its exact stored casing (e.g.
Binance,Gate.io).
- Name
symbol- Type
- string
- Description
The contract that settled. One coin spans several contracts per venue at times (a USDT and a USDC perp, or
PEPEnext to1000PEPElots), so series are per(exchange, symbol). History rows carry no other contract metadata; jointype=currentrows on(exchange, symbol)forasset_id,lot_multiplierand status.
- Name
rate- Type
- number
- Description
The funding rate at settlement time, as a fraction charged once over
interval_hours.
- Name
interval_hours- Type
- number
- Description
Hours the settlement covered for this contract. It can change over the series when a venue re-tiers a symbol, so accumulate per row rather than multiplying by a single interval.
- Name
settled_at- Type
- string
- Description
ISO 8601 timestamp when the funding payment was settled.
Request
curl -G https://www.sharpe.ai/api/v1/funding/rates \
-H "Authorization: Bearer sk_live_your_key_here" \
-d type=history \
-d coin=BTC \
-d days=7
Response (type=history)
{
"data": [
{
"exchange": "Binance",
"rate": 0.000095,
"interval_hours": 4,
"settled_at": "2026-03-20T00:00:00Z"
},
{
"exchange": "Binance",
"rate": 0.000110,
"interval_hours": 4,
"settled_at": "2026-03-20T04:00:00Z"
},
{
"exchange": "Hyperliquid",
"rate": 0.0000125,
"interval_hours": 1,
"settled_at": "2026-03-20T00:00:00Z"
},
{
"exchange": "Gate.io",
"rate": 0.000120,
"interval_hours": 8,
"settled_at": "2026-03-20T08:00:00Z"
}
],
"meta": {
"request_id": "req_ghi789jkl012mnop",
"timestamp": "2026-03-27T07:45:00Z",
"elapsed_ms": 12
}
}
Get funding fee settlement
Returns how many dollars actually changed hands at funding settlement, and which side paid it: fee_usd = open_interest_usd × rate, priced at the one-sided open interest (each contract counted once: the side that pays) recorded at or before each settlement. window=current is the next (forward-looking) settlement, priced live and labelled estimated; 1d/3d/7d are realised windows. Every window reports long_paid and short_paid alongside net — a $0 net can conceal $50M flowing each way, so no consumer is given net alone.
The response carries a totals block scoped to the selected class, in the same shape as a row. crypto + rwa reconciles exactly to all, in every window, for net, long_paid and short_paid.
Query parameters
- Name
window- Type
- string
- Description
Settlement window. One of
current,1d,3d,7d. Defaults tocurrent.
- Name
class- Type
- string
- Description
Asset-class scope. One of
all,crypto,rwa, where rwa means every non-crypto asset class: equity, commodity, fx, index. Defaults toall. Not a narrower filter on the underlying asset class — this plus the per-row asset_class field on each row answers every question a second parameter could.
- Name
coin- Type
- string
- Description
Comma-separated base coin tickers, e.g.
BTC,ETH. Unfiltered by default.
- Name
exchange- Type
- string
- Description
Narrows to coins settling on one venue. Accepts the slug, the display name as returned in
venues[].exchange, or the ccxt id. An unrecognized value returns a 400 error. Implies the per-venue breakdown internally; the response still omitsvenuesunlessexpand=venuesis also set.
- Name
limit- Type
- integer
- Description
Maximum number of rows returned.
1to1000. Defaults to100.
- Name
offset- Type
- integer
- Description
Zero-based row offset for pagination. Defaults to
0.
- Name
sort- Type
- string
- Description
Sort field for the selected window, optionally prefixed with a hyphen for descending order. One of
base_coin,net,long_paid,short_paid,open_interest_usd,-base_coin,-net,-long_paid,-short_paid,-open_interest_usd. Rows with no value for the sort field always sort last, regardless of direction.
- Name
expand- Type
- string
- Description
Set to
venuesto include each row's per-venue breakdown. Omitted by default to keep the default payload small.
Response fields
- Name
base_coin- Type
- string
- Description
The base asset ticker.
- Name
asset_class- Type
- string
- Description
Underlying category:
crypto,equity,commodity,fxorindex.
- Name
price- Type
- number | null
- Description
Always
nulltoday -- no price source is wired into this endpoint yet. Use/v1/funding/ratesor/v1/market-cap/searchfor spot price.
- Name
price_change_24h_pct- Type
- number | null
- Description
Always
nulltoday, for the same reason asprice.
- Name
open_interest_usd- Type
- number | null
- Description
One-sided USD open interest summed across whichever of this coin's venues currently have a priced reading, less any venue left out of totals (see "Venue coverage" below).
nullonly when none do -- never0as a stand-in for missing.
- Name
windows- Type
- object
- Description
Keyed by
current,1d,3d,7d. Every window carriesnet,long_paidandshort_paid(see "Sign convention").currentadditionally carriesestimated: trueandrate_source(predictedorcurrent, see "Whatcurrentmeans"). The three realised windows additionally carrycoverage_ratioandpartialonce the window has any priced history at all (see "Partial windows").
- Name
venues- Type
- array
- Description
Present only when
expand=venuesis set. Each entry is{ exchange, open_interest_usd, windows }-- the same per-window shape as the row itself, scoped to that one venue -- plusexcluded_from_totals(the reason) on a venue whose dollars the row and the totals leave out.
Sign convention
A positive rate means longs pay shorts, so a positive net is a cost to longs, and a negative net means longs were net paid. long_paid and short_paid are both always non-negative; net = long_paid − short_paid recovers the sign. Both legs are always returned alongside net -- a net of 0 can conceal $50M changing hands in each direction, so no consumer is given the net alone.
What current means
window=current has not happened yet -- it is the next settlement, priced live: fee_usd = open_interest_usd × rate, using the freshest OI reading and the forward-looking rate (the venue's predicted_rate when it publishes one, otherwise its in-progress rate -- see rate_source). It always carries estimated: true. 1d, 3d and 7d are realised: every settlement that actually occurred inside that window, summed.
Partial windows
Open interest only accrues forward from when Sharpe first started tracking a venue's OI -- no exchange backfills OI history. A venue tracked for the last two days has a complete 1d window but an incomplete 7d one until a full week of history exists. coverage_ratio is the fraction of the window actually covered by priced history (1 = complete) -- a coin, venue or total row weights its contracts by open interest, and a contract that stopped settling (halted or delisted) is only expected until its last priced settlement plus one interval; partial is true when that ratio is below 0.9. A partial window's net, long_paid and short_paid are still real sums of whatever settled in that shorter span -- building history, not a completed total -- so treat partial: true as a caveat on the figure, not a reason to hide it.
Venue coverage
Of the 32 venues in Sharpe's funding book, 28 run an open-interest fetcher capable of pricing a dollar figure here, and every one stores open interest the same way: one-sided USD notional, each contract counted once -- the side that pays, which is what makes fee_usd = open_interest_usd × rate exact. Venues that publish both sides (Bybit, Gate.io, Bitget, Pacifica, Backpack, ApeX, Extended) are read through their own one-sided field or halved. tradeXYZ, Lighter, Variational and Aster, withheld until 2026-09-27 for reading at half the figure other sources show, contribute again: their figures were one side all along, and those sources publish both. MEXC is the exception: its open interest moves 7.00x the position change its own trade feed reports, so its dollars appear only in the per-venue breakdown (venues[].excluded_from_totals) and are left out of every row's net, long_paid, short_paid and open_interest_usd and of totals; settlementMeta.oi_excluded_venues names it with the reason. Its funding rates are unaffected and still appear on /v1/funding/rates.
Request
curl -G https://www.sharpe.ai/api/v1/funding/settlement \
-H "Authorization: Bearer sk_live_your_key_here" \
-d window=7d \
-d class=crypto
Response
{
"data": {
"rows": [
{
"base_coin": "ETH",
"asset_class": "crypto",
"price": null,
"price_change_24h_pct": null,
"open_interest_usd": 9080000000,
"windows": {
"current": {
"net": 234930,
"long_paid": 998150,
"short_paid": 820350,
"estimated": true,
"rate_source": "current"
},
"1d": {
"net": 809050,
"long_paid": 1200000,
"short_paid": 390950,
"coverage_ratio": 1,
"partial": false
},
"3d": { "net": null, "long_paid": null, "short_paid": null },
"7d": {
"net": 5460000,
"long_paid": 8210000,
"short_paid": 2750000,
"coverage_ratio": 1,
"partial": false
}
}
}
],
"totals": {
"current": { "net": 177800, "long_paid": 998150, "short_paid": 820350, "estimated": true },
"1d": { "net": 3790000, "long_paid": 6930000, "short_paid": 3130000, "coverage_ratio": 1, "partial": false },
"3d": { "net": null, "long_paid": null, "short_paid": null },
"7d": { "net": 24680000, "long_paid": 53570000, "short_paid": 28880000, "coverage_ratio": 1, "partial": false }
},
"settlementMeta": {
"class": "crypto",
"coins": 940,
"updated_at": "2026-08-06T10:00:00Z",
"total": 940,
"limit": 100,
"offset": 0
},
"pagination": { "cursor": null, "has_more": true, "total": 940 }
},
"meta": {
"request_id": "req_stu345vwx678yzab",
"timestamp": "2026-08-06T10:00:00Z",
"elapsed_ms": 41
}
}
List available coins
Returns every distinct base coin in the current funding-rate book with a display name and a same-origin logo path, ordered by symbol. Use this to populate coin selectors without downloading the full funding book.
Response fields
- Name
coins- Type
- array
- Description
Array of coin objects, ordered by symbol.
- Name
coins[].symbol- Type
- string
- Description
Asset ticker as quoted in the funding book (e.g.,
BTC,1000PEPE).
- Name
coins[].name- Type
- string | null
- Description
Display name from coin metadata;
nullwhen no metadata exists.
- Name
coins[].logo_url- Type
- string | null
- Description
Same-origin logo path;
nullwhen no logo exists.
Request
curl -G https://www.sharpe.ai/api/v1/funding/coins \
-H "Authorization: Bearer sk_live_your_key_here"
Response
{
"data": {
"coins": [
{
"symbol": "BTC",
"name": "Bitcoin",
"logo_url": "/api/coin-logo-image?symbol=BTC"
},
{
"symbol": "ETH",
"name": "Ethereum",
"logo_url": "/api/coin-logo-image?symbol=ETH"
}
]
},
"meta": {
"request_id": "req_abc123def456ghi7",
"timestamp": "2026-08-13T10:00:00Z",
"elapsed_ms": 18
}
}