Skip to main content

@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)​

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 .io base 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 .ai base URLs, a 503 from the API reaches the client as a 504 with an HTML body.
NetworkPeer A (.io)Peer B (.ai)
Arbitrumhttps://arbitrum.gmxapi.io/v1https://arbitrum.gmxapi.ai/v1
Avalanchehttps://avalanche.gmxapi.io/v1https://avalanche.gmxapi.ai/v1
MegaETHhttps://megaeth.gmxapi.io/v1https://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.

FigureReadDon't read
24h perpetual volumetotals.volume24h.perpstotals.volume24h.total, which adds swap volume
Open interesttotals.openInterest.totalThe open_interest sum of one /pairs feed, which covers one network
TVLtotals.tvl.totaltotals.tvl.pools plus totals.tvl.glv, which counts GLV vaults twice: they hold GM tokens
Userstotals.users.alltotals.users.traders, which counts only wallets that traded
Daily perpetual volume historygroups[0].points of GET /stats/timeseries?metric=volume.perps&groupBy=nonemetric=volume, which returns 400, and requests without groupBy=none, which return one group per network

Read the values with these rules:

  • USD values in /stats responses are 30-decimal fixed-point integer strings. Divide them by 10^30: "1640761366019651901162131323659069246145" is $1,640,761,366.02. User counts are plain numbers.
  • volume24h is a rolling window that starts on the hour 24 hours before the current hour, so it covers 24 to 25 hours.
  • Each timeseries point covers the UTC day that starts at its day, in Unix seconds. A point with provisional: 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. With from or to, groups is empty when no day falls in that range.
  • openInterest is 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.total is 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. When byNetwork.solana.tvl.store is null, the Solana part is its GM pool value instead, so keep your last TVL until it's back. totals.tvl.store is always null. tvl.total doesn't include GMX V1 (GLP) or staked GMX.
  • users.all is the all-time number of wallets that used GMX. Each network and version counts its own wallets, and totals adds 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.fees24h is null, and the users.active series with groupBy=none is null from July 2023 on. For protocol-wide fees, read daily fees.total from /stats/timeseries.
  • byNetwork and byVersion break the same totals down. If you publish a network as a separate entry, such as byNetwork.solana, it's already inside totals.
  • Keep a figure's last published value while it's null, or while a source in meta.sources[] whose metrics include the figure's group, such as openInterest, isn't fresh. A stale source still counts toward totals, but its 24-hour volume misses the hours it lags, and a missing source is left out. totals.volume24h, totals.openInterest, and totals.tvl can be null as 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.