@gmx-io/gmx-public-api
GMX API overview with Swagger/OpenAPI links, base URLs, and the fields to read when you publish GMX figures.
GMX API (Swagger)
- Swagger/OpenAPI spec: GMX API Swagger
- Human-readable API docs: GMX API Docs
Base URLs
The GMX API is deployed per chain across two independent peer base URLs (.io and .ai). Neither is primary; both receive the same data and accept the same requests, with these exceptions. Integrations that hit the API directly should use either base URL, or rotate across both.
- Only the
.iobase URLs serve the generic/relay/*routes. - The peers don't share express order and GMX Account cross-chain withdrawal records, so keep all calls of one order or withdrawal on one base URL.
- On the
.aibase URLs, a503from the API reaches the client as a504with an HTML body.
| Network | Peer A (.io) | Peer B (.ai) |
|---|---|---|
| Arbitrum | https://arbitrum.gmxapi.io/v1 | https://arbitrum.gmxapi.ai/v1 |
| Avalanche | https://avalanche.gmxapi.io/v1 | https://avalanche.gmxapi.ai/v1 |
| MegaETH | https://megaeth.gmxapi.io/v1 | https://megaeth.gmxapi.ai/v1 |
The /v1/stats endpoints are protocol-wide: they cover every GMX network, including GMX on Solana, and every base URL serves them. Some base URLs answer them with a redirect, so let your HTTP client follow redirects.
The GMX on Solana pair feed is https://solana.gmxapi.io/v1/pairs, the only path on that host that these docs cover. The Arbitrum base URLs serve the same feed at /pairs/solana, for example https://arbitrum.gmxapi.ai/v1/pairs/solana; the base URLs of the other networks don't.
Publish GMX figures
Use this section if you publish GMX figures on a data platform, such as an aggregator, a ranking, or a market data site.
Read protocol-wide figures from GET /stats/summary on an Arbitrum base URL: https://arbitrum.gmxapi.io/v1/stats/summary, with https://arbitrum.gmxapi.ai/v1/stats/summary as its peer. One response covers Arbitrum, Avalanche, MegaETH, and GMX on Solana, and both GMX V1 and V2. Call it without the networks and versions filters: with them, totals covers only the networks and versions you select.
| Figure | Read | Don't read |
|---|---|---|
| 24h perpetual volume | totals.volume24h.perps | totals.volume24h.total, which adds swap volume |
| Open interest | totals.openInterest.total | The open_interest sum of one /pairs feed, which covers one network |
| TVL | totals.tvl.total | totals.tvl.pools plus totals.tvl.glv, which counts GLV vaults twice: they hold GM tokens |
| Users | totals.users.all | totals.users.traders, which counts only wallets that traded |
| Daily perpetual volume history | groups[0].points of GET /stats/timeseries?metric=volume.perps&groupBy=none | metric=volume, which returns 400, and requests without groupBy=none, which return one group per network |
Read the values with these rules:
- USD values in
/statsresponses are 30-decimal fixed-point integer strings. Divide them by10^30:"1640761366019651901162131323659069246145"is $1,640,761,366.02. User counts are plain numbers. volume24his a rolling window that starts on the hour 24 hours before the current hour, so it covers 24 to 25 hours.- Each
timeseriespoint covers the UTC day that starts at itsday, in Unix seconds. A point withprovisional: true, such as the current day, can still change, and so can the four days before the current day: re-read them each time you update your history. Withfromorto,groupsis empty when no day falls in that range. openInterestis the value of open positions at the current oracle mid price. Positions without a current price are valued at entry prices. It covers GMX on Solana and GMX V2 on Arbitrum, Avalanche, and MegaETH, but not GMX V1.tvl.totalis the value of the GM pools on Arbitrum, Avalanche, and MegaETH plus the assets that the GMX on Solana program holds,byNetwork.solana.tvl.store. WhenbyNetwork.solana.tvl.storeisnull, the Solana part is its GM pool value instead, so keep your last TVL until it's back.totals.tvl.storeis alwaysnull.tvl.totaldoesn't include GMX V1 (GLP) or staked GMX.users.allis the all-time number of wallets that used GMX. Each network and version counts its own wallets, andtotalsadds the counts, so a wallet active on two networks counts twice.- GMX V2 on Arbitrum, Avalanche, and MegaETH doesn't report 24-hour fees or daily active users, so
totals.fees24hisnull, and theusers.activeseries withgroupBy=noneisnullfrom July 2023 on. For protocol-wide fees, read dailyfees.totalfrom/stats/timeseries. byNetworkandbyVersionbreak the same totals down. If you publish a network as a separate entry, such asbyNetwork.solana, it's already insidetotals.- Keep a figure's last published value while it's
null, or while a source inmeta.sources[]whosemetricsinclude the figure's group, such asopenInterest, isn'tfresh. Astalesource still counts towardtotals, but its 24-hour volume misses the hours it lags, and amissingsource is left out.totals.volume24h,totals.openInterest, andtotals.tvlcan benullas a whole, not only their fields. - For the other daily metrics and the rest of
meta, see Read protocol-wide stats.
For pair listings, read GET /pairs on the base URL of each network, and https://solana.gmxapi.io/v1/pairs for GMX on Solana. Each feed covers one network only, so use the /stats/summary totals for protocol-wide figures. A feed has one Perpetual row per perpetual market and, on Arbitrum, Avalanche, and MegaETH, one Spot row per pair of swap tokens. The feeds give USD values as plain numbers, not as 30-decimal strings. On Perpetual rows, target_volume is the 24-hour volume in USD, the open_interest fields are in USD, and funding_rate is the paying side's rate in percent per hour, positive when longs pay, with funding_interval_minutes set to 60. On the GMX on Solana feed, open_interest is valued at entry prices, and target_volume can keep its last 24-hour window for up to 6 hours while the indexer lags.