/api/v1/markets
Every listed market with its parameters, validated index, mark, last trade, 24-hour figures, open interest and funding.
Returns data: marketSummary[]
curl $API/api/v1/marketsAPI reference
Written from the contract between the API and this application (packages/api-contracts). The API is not deployed for this site yet; examples use https://<api-host> in place of its address. Every value says where it came from.
/api/v1. All endpoints are GET, public and read-only. There is no authentication because nothing can be written."60000000000000000000000" for 60,000. Convert with BigInt; never parseFloat. Counts, ids and basis points are plain JSON numbers.0x plus 40 hex digits, lower-cased by the indexer; hashes 0x plus 64.:marketId.statusLabel, assetClassLabel) accompany them where a human reads the response.@elysta/api-contracts; this page is written from them. Parse responses with them and a shape the API never promised cannot reach your code.Every successful response is { data, meta }. The meta object is how the API keeps the thesis's promise that an estimate is never presented as a confirmed value.
{
"data": { ... },
"meta": {
"source": "indexed",
"observedAt": "2026-11-08T14:03:21.512Z",
"block": 1842211,
"chainId": 99901,
"freshness": "live"
}
}| Field | Type | Notes |
|---|---|---|
source | chain | indexed | computed | estimated | unavailable | Where the figures came from (THESIS.md §38). An estimate is never labelled as confirmed. |
observedAt | time | When the API assembled the response. |
block | integer | null | The chain block the figures describe, when known. |
chainId | integer | |
freshness | live | delayed | stale | unavailable | Optional. From the indexer's heartbeat and lag: live under 30 s and 50 blocks, delayed under 5 min, stale beyond; unavailable when it has never reported. |
Judged from the indexer’s heartbeat and how far its checkpoint is behind the chain head: live when the heartbeat is under 30 seconds old and the lag under 50 blocks, delayed under 5 minutes, stale beyond, and unavailable when the indexer has never reported, because then nothing can be said. Individual figures carry their own provenance where it differs from the response: a market’s mark.source and openInterest.source, for instance.
Every failure leaves the API as { error: { code, message, details? } } with a matching HTTP status.
{ "error": { "code": "BAD_REQUEST", "message": "cursor must have the form <block>:<logIndex>" } }| Code | HTTP status | Meaning |
|---|---|---|
NOT_FOUND | 404 | No such market, account route or resource. |
BAD_REQUEST | 400 | A malformed parameter: an unknown interval, a cursor not of the form <block>:<logIndex>, an empty types list. |
RATE_LIMITED | 429 | More requests per minute from one client address than the deployment allows. |
UNAVAILABLE | 503 | The API is up but a dependency (database, chain RPC) is not. The figures could not be read; nothing is estimated in their place. |
INTERNAL | 500 | A bug, including a response that failed its own contract validation. |
Configured per deployment: RATE_LIMIT_PER_MINUTE requests per minute per client address, default 600, after which the API answers 429 RATE_LIMITED. The WebSocket pings on WS_HEARTBEAT_SECONDS (default 20) and drops a client that misses two pings in a row; the welcome message reports the live value. Browser origins are allow-listed with WEB_ORIGINS.
Public market data: the registry’s configuration and status, the validated index, the mark, the book, trades, candles and funding.
Every listed market with its parameters, validated index, mark, last trade, 24-hour figures, open interest and funding.
Returns data: marketSummary[]
curl $API/api/v1/marketsOne market.
Returns data: marketSummary
curl $API/api/v1/markets/BTC-USDThe order book, read from the on-chain book: aggregated levels with order counts and cumulative quantity, best bid and ask, spread, mid, mark and index.
Returns data: orderBook
curl "$API/api/v1/markets/BTC-USD/orderbook?levels=10"Recent fills, newest first, each with its transaction and block.
Returns data: trade[]
curl "$API/api/v1/markets/BTC-USD/trades?limit=50"OHLCV candles built from indexed fills, ascending.
Returns data: { marketId: integer, interval, candles: candle[] }
Candles exist only where trades happened. A new market or a quiet interval returns fewer candles, not flat ones.
curl "$API/api/v1/markets/BTC-USD/candles?interval=1h&limit=168"The market's funding configuration, cumulative index, next settlement time, predicted rate (an estimate) and settlement history.
Returns data: { marketId, intervalSeconds, maxRatePerInterval: wad, cumulativeIndex: wad | null, nextFundingAt: time | null, predictedRate: wad | null, history: fundingEvent[] }
curl "$API/api/v1/markets/BTC-USD/funding?limit=24"Balances, positions, orders and history for any address. Nothing here is private: every figure is public chain data, served faster.
Balances, open positions and open orders for an address, in one response.
Returns data: accountView
curl $API/api/v1/accounts/0xYourAddressOpen positions only.
Returns data: positionView[]
curl $API/api/v1/accounts/0xYourAddress/positionsOpen orders only. Historical orders are in the history feed.
Returns data: orderView[]
curl $API/api/v1/accounts/0xYourAddress/ordersEverything that happened to an account, newest first, each item tied to its transaction: fills, order events, deposits, withdrawals, funding payments, liquidations, margin adjustments and realised PnL.
Returns data: { items: historyItem[], nextCursor: string | null }
curl "$API/api/v1/accounts/0xYourAddress/history?types=fill,funding&limit=50"The status page's source: chain connection, contracts, indexer, keeper, API, WebSocket, per-market oracle health, market status counts and the vault's figures.
Returns data: protocolStatus
curl $API/api/v1/protocol/statusThe insurance fund balance, protocol fees, bad debt and PnL pool as last read from the vault, with the fund's event history.
Returns data: insuranceFundView
curl $API/api/v1/protocol/insurance-fundRecent liquidations across all markets, newest first.
Returns data: liquidationView[]
curl "$API/api/v1/protocol/liquidations?limit=20"Accounts ranked by realised PnL from indexed fills over a window. basis says exactly how the ranking was computed.
Returns data: { window, entries: leaderboardEntry[], basis: string }
curl "$API/api/v1/leaderboard?window=7d"Leaderboard basis
basis string states the exact computation. It is derived data: a ranking, not a balance, and it is labelled as such.Each object the endpoints return, field by field, in the order the schema declares them.
marketSummary| Field | Type | Notes |
|---|---|---|
id | integer | The on-chain market id. |
symbol | string | e.g. BTC-USD |
underlying | string | |
assetClass | 0 | 1 | 2 | 3 | Crypto, Equity, Commodity, Index |
assetClassLabel | string | |
status | 0 | 1 | 2 | 3 | 4 | Inactive, Active, ReduceOnly, Paused, Halted |
statusLabel | string | |
sessionOpen | boolean | Whether the market's session is open now. |
tradingOpen | boolean | isTradingOpen: status Active or ReduceOnly, session open and a valid index. |
priceDecimals | integer | Display hint; the chain always uses WAD. |
qtyDecimals | integer | |
tickSize | wad | |
lotSize | wad | |
minOrderQty | wad | |
maxOrderQty | wad | |
maxLeverage | number | |
initialMarginFraction | wad | |
maintenanceMarginFraction | wad | |
makerFee | wad | |
takerFee | wad | |
fundingIntervalSeconds | integer | |
maxFundingRatePerInterval | wad | |
maxImpactBps | integer | |
priceBandBps | integer | |
markBandBps | integer | |
index | indexQuote | The validated index price and its health. |
mark | { price: wad | null, source: provenance } | |
last | { price: wad, at: time, side: 0 | 1 } | null | The most recent fill; null when the market has never traded. |
change24h | { absolute: wad, bps: number } | null | null without a trade 24 hours ago to compare against. |
volume24h | { base: wad, quote: wad, trades: integer } | From indexed fills only. |
openInterest | { long: wad, short: wad, notional: wad | null, source: provenance } | Read from the risk engine; never estimated. |
funding | { lastRate, lastSettledAt, cumulativeIndex, nextFundingAt, predictedRate } | Each nullable. predictedRate is labelled an estimate. |
oracle | { adapter: address, feedSource: string | null, heartbeatSeconds: integer, maxDeviationBps: integer } |
indexQuote| Field | Type | Notes |
|---|---|---|
price | wad | null | |
publishedAt | time | null | The source observation time, not the block time. |
valid | boolean | False when missing, stale, or the market is halted or unlisted. |
health | no_price | ok | stale | deviation | |
ageSeconds | number | null |
orderBook| Field | Type | Notes |
|---|---|---|
marketId | integer | |
bids | bookLevel[] | Best first. |
asks | bookLevel[] | Best first. |
bestBid | wad | null | |
bestAsk | wad | null | |
spread | wad | null | |
spreadBps | number | null | |
mid | wad | null | |
mark | wad | null | |
index | wad | null | |
depthLevels | integer | How many levels per side were requested. |
bookLevel| Field | Type | Notes |
|---|---|---|
price | wad | |
qty | wad | Total resting quantity at the level. |
count | integer | Orders at the level. |
cumulative | wad | Quantity from the best level to this one. |
trade| Field | Type | Notes |
|---|---|---|
seq | integer | The Fill event's sequence number. |
marketId | integer | |
price | wad | |
qty | wad | |
takerSide | 0 | 1 | Buy or Sell |
maker | address | |
taker | address | |
makerOrderId | integer | |
takerOrderId | integer | |
makerFee | wad | |
takerFee | wad | |
txHash | hash | |
blockNumber | integer | |
time | time |
candleBuilt from indexed fills only. An interval with no trades has no candle; nothing is synthesised.
| Field | Type | Notes |
|---|---|---|
t | time | Bucket start. |
o, h, l, c | wad | |
vBase | wad | |
vQuote | wad | |
n | integer | Trades in the bucket. |
fundingEvent| Field | Type | Notes |
|---|---|---|
marketId | integer | |
settledAt | time | |
rate | wad | Signed. Positive: longs paid shorts. |
cumulativeIndex | wad | |
markPrice | wad | |
indexPrice | wad | |
premiumTwap | wad | |
txHash | hash | |
blockNumber | integer |
positionView| Field | Type | Notes |
|---|---|---|
marketId | integer | |
symbol | string | |
qty | wad | Absolute quantity; side carries the direction. |
side | long | short | |
avgEntryPrice | wad | |
markPrice | wad | null | |
margin | wad | |
notional | wad | null | |
leverage | wad | null | notional / margin |
unrealizedPnl | wad | null | |
pendingFunding | wad | null | Positive: the position would receive at its next touch. |
liquidationPrice | wad | null | |
marginRatio | wad | null | |
realizedPnl | wad | |
fundingPaid | wad | |
feesPaid | wad | |
openedAt | time | null | |
updatedAt | time |
orderView| Field | Type | Notes |
|---|---|---|
orderId | integer | |
marketId | integer | |
symbol | string | |
side | 0 | 1 | |
kind | 0 | 1 | Limit, Market |
tif | 0 | 1 | 2 | 3 | GTC, IOC, FOK, PostOnly |
price | wad | |
qty | wad | |
remaining | wad | |
filled | wad | |
reserved | wad | |
reduceOnly | boolean | |
expiresAt | time | null | |
status | 0 | 1 | 2 | 3 | 4 | None, Open, Filled, Cancelled, Expired |
cancelReason | integer | null | CancelReason when cancelled. |
seq | integer | |
createdAt | time | |
updatedAt | time | |
txHash | hash | The placing transaction. |
balances| Field | Type | Notes |
|---|---|---|
available | wad | |
reserved | wad | |
locked | wad | |
unrealizedPnl | wad | null | |
pendingFunding | wad | null | |
equity | wad | null | available + reserved + locked + unrealized PnL + pending funding |
depositedTotal | wad | |
withdrawnTotal | wad | |
feesPaidTotal | wad | |
realizedPnlTotal | wad | |
fundingTotal | wad | |
reconciled | boolean | null | Whether the replayed ledger matched accountOf on chain at the last check. |
reconciledAt | time | null |
accountView| Field | Type | Notes |
|---|---|---|
address | address | |
balances | balances | |
positions | positionView[] | |
openOrders | orderView[] |
historyItemA discriminated union on type. Every variant carries type, time, txHash and blockNumber.
| Field | Type | Notes |
|---|---|---|
fill | marketId, symbol, side, price, qty, fee, role: maker | taker, orderId | |
order | marketId, symbol, orderId, event: placed | rested | filled | cancelled | expired, side, price, qty, remaining, cancelReason | |
deposit | amount: wad, tokenAmount: wad | null | |
withdrawal | amount: wad, tokenAmount: wad | null | |
funding | marketId, symbol, payment: wad | Positive: paid. |
liquidation | marketId, symbol, role: liquidated | liquidator, qty, markPrice, penalty, incentive, full | |
margin | marketId, symbol, delta: wad, margin: wad | |
realized | marketId, symbol, realizedPnl, fee, fillPrice, fillQty |
protocolStatusWhat the status page shows. Component statuses are ok | degraded | down | unknown, judged from heartbeats: ok under 45 s, degraded under 3 min, down beyond, unknown when never reported.
| Field | Type | Notes |
|---|---|---|
environment | local | testnet | mainnet | |
chain | { chainId, name, rpcOk, headBlock: integer | null, headBlockAt: time | null, explorerUrl: string | null } | |
contracts | { collateralToken, ElystaCollateralVault, ElystaMarketRegistryOracle, ElystaKeeperOracleAdapter, ElystaPerpRiskEngine, ElystaOrderBookEngine: address; startBlock: integer; testCollateral: boolean } | |
indexer | { status, lastBlock: integer | null, lagBlocks: integer | null, heartbeatAt: time | null, details: object | null } | |
keeper | { status, lastPostAt: time | null, heartbeatAt: time | null, details: object | null } | |
api | { status, startedAt: time, version: string } | |
websocket | { status, clients: integer } | |
oracle | { marketId, symbol, health, publishedAt: time | null, ageSeconds: number | null, feedSource: string | null }[] | |
markets | { total, active, reduceOnly, paused, halted, inactive: integer } | |
vault | { insuranceFund, protocolFees, badDebt, pnlPool, totalAvailable, totalReserved, totalLocked, assets: wad | null; balanced: boolean | null } | balanced is assets == liabilities + pnlPool when every term is present. |
insuranceFundView| Field | Type | Notes |
|---|---|---|
balance | wad | null | |
protocolFees | wad | null | |
badDebt | wad | null | |
pnlPool | wad | null | |
events | { time, txHash, blockNumber, kind: string, amount: wad, account: address | null, balanceAfter: wad | null }[] | kind: funded, fee_share, cover, bad_debt. |
liquidationView| Field | Type | Notes |
|---|---|---|
time | time | |
txHash | hash | |
blockNumber | integer | |
marketId | integer | |
symbol | string | |
account | address | |
liquidator | address | |
qty | wad | |
markPrice | wad | |
penalty | wad | |
liquidatorIncentive | wad | |
insuranceContribution | wad | |
badDebt | wad | |
full | boolean |
leaderboardEntry| Field | Type | Notes |
|---|---|---|
account | address | |
realizedPnl | wad | |
volume | wad | |
trades | integer | |
fundingNet | wad | |
feesPaid | wad |
Connect to the API's /api/v1/ws endpoint once it is deployed. Subscribe to channels with JSON messages; receive typed messages with block, transaction, observation time and freshness.
| Message | Notes |
|---|---|
| { "op": "subscribe", "channel": "book", "marketId": 1 } | Channels markets, book and trades take a marketId. |
| { "op": "subscribe", "channel": "account", "account": "0xYourAddress" } | The account channel takes an address. |
| { "op": "subscribe", "channel": "protocol" } | Protocol status needs no parameter. |
| { "op": "unsubscribe", "channel": "book", "marketId": 1 } | The same parameters as the subscription. |
| { "op": "ping" } | Answered with pong. |
Every server message has type, block (integer or null), txHash (hash or null), observedAt and freshness, then data. Market-scoped messages add marketId; account-scoped messages add account.
| type | Channel | data | Notes |
|---|---|---|---|
welcome | — | { chainId, version, heartbeatSeconds } | Sent once on connect. |
pong | — | {} | |
subscribed | — | { channel, marketId?, account? } | |
error | — | { code, message } | |
market.update | markets | marketSummary | marketId on the message. |
market.status | markets | { status, statusLabel, reason } | reason is a StatusReason code. |
funding.settled | markets | fundingEvent | |
liquidation | markets | liquidationView | |
book.update | book | orderBook | |
trade | trades | trade | |
order.update | account | orderView | account on the message. |
position.update | account | positionView | |
balance.update | account | balances | |
protocol.status | protocol | protocolStatus |
welcome, with the chain id, the API version and the heartbeat interval.subscribed; a malformed request gets error and the connection stays open.