Subgraph - The Data Layer
Query markets, order books, trades, positions, and price history via The Graph. Endpoint, entities, and copy-paste GraphQL examples.
The subgraph indexes every protocol event on Polygon into a queryable GraphQL API. It is the data layer for every frontend, bot, and keeper in the ecosystem: the contracts are the source of truth, the subgraph is how you read them at scale.
Endpoint
https://api.studio.thegraph.com/query/1744387/magistery/v3.0.0Hosted on The Graph's Subgraph Studio. Free, but rate-limited - fine for development and light production use. Migration to The Graph's decentralized network (independent indexers, no rate limits, per-query GRT payments) is planned; all consumers read the endpoint from a single config value, so the swap is one line.
curl -s https://api.studio.thegraph.com/query/1744387/magistery/v3.0.0 \
-H 'content-type: application/json' \
-d '{"query": "{ protocol(id: \"1\") { totalMarkets totalVolumeUsd totalFeesUsd } }"}'Entities
| Entity | What it holds |
|---|---|
Protocol | Singleton (id: "1"). Lifetime totals: markets, orders, matches, volume, fees, users. |
Market | One binary market per conditionId. Question, creator, resolver, deadline, status (Active / Pending / Resolved / Voided), volume, linked flag for Kalshi/Polymarket resolvers. |
MarketOutcome | Per-outcome state: positionId (ERC-1155 token ID), lastPrice, bestBid / bestAsk (1e6 scale), liquidity totals, active price levels. |
OrderBookLevel | Pre-aggregated depth: total unfilled shares and order count per price level, per side. |
Order | Individual limit order: side, price (1e6), amount, filled, cancelled. |
Match | One matched fill: fillType (BuyVsBuy / BuyVsSell), execution price, volume, fee. |
TradeExecution | Per-side detail within a match: user, side, price, amount, cost. |
UserOutcomePosition | User's net position per outcome, with cost basis and realized PnL. |
UserMarketSummary | Per-market PnL rollup: invested, returned (sells + redemptions), realized PnL. |
Assertion | UMA/Kalshi resolution assertions: status (Pending / Settled / Disputed / Rejected). |
NegRiskMarket / NegRiskLeg | Multi-outcome markets and their binary legs. |
MarketHourData / MarketDayData | OHLCV candles per outcome: open, high, low, close, volume, trade count. |
Resolver, User | Resolver registry (with isTrusted for known deployments) and per-user aggregates. |
Full-text search on market questions is built in: marketSearch(text: "election").
Balances are not canonical
UserOutcomePosition.balance tracks net protocol activity (OrderBook buys minus sells). It does not see ERC-1155 transfers made outside the protocol. For true wallet balances, read CTF.balanceOf(user, positionId) on-chain. Also note: MarketOutcome.totalBidLiquidity and totalAskLiquidity are denominated in shares, not USDC.
Examples
Trending markets
Active markets by volume, with current prices:
{
markets(
first: 10
orderBy: volumeUsd
orderDirection: desc
where: { status: "Active" }
) {
id
question
deadline
volumeUsd
uniqueTraders
outcomes {
outcomeIndex
lastPrice
bestBid
bestAsk
}
}
}Order book depth
Full depth for one market, pre-aggregated by price level (prices are 1e6 scale, totalAmount is shares):
{
orderBookLevels(
where: { outcome_: { market: "0xYOUR_CONDITION_ID" } }
orderBy: price
orderDirection: desc
) {
outcome { outcomeIndex }
side
price
totalAmount
orderCount
}
}User positions and PnL
{
user(id: "0xyour_address_lowercase") {
totalVolumeUsd
positions(where: { balance_gt: 0 }) {
market { question status }
outcome { outcomeIndex lastPrice }
balance
totalCostBasis
realizedPnl
}
marketSummaries {
market { question }
totalInvested
totalReturned
realizedPnl
redeemed
}
}
}Remember: balance here is the protocol-level net position. Confirm on-chain before letting a user redeem.
Price candles
Hourly OHLCV for one outcome (use marketDayDatas for daily):
{
marketHourDatas(
where: { outcome: "0xYOUR_CONDITION_ID-0" }
orderBy: periodStart
orderDirection: desc
first: 168
) {
periodStart
open
high
low
close
volumeUsd
tradeCount
}
}Search
{
marketSearch(text: "bitcoin") {
id
question
status
}
}Conventions
- IDs are lowercase hex. Markets are keyed by conditionId, users by address, outcomes by
conditionId-outcomeIndex. - Prices come in two scales.
bestBid/bestAsk/Order.price/OrderBookLevel.priceare raw 1e6 integers (500000 = $0.50).lastPrice, candle OHLC, and execution prices are decimals (0.5 = $0.50). - Amounts are 1e6 shares. Same scale as USDC.
- Trading survives the deadline.
status: "Pending"markets (past deadline, not yet resolved) still accept and match orders. Filter accordingly.