CRX API (GraphQL)
What is the CRX indexer?
The CRX indexer is the system of record for everything the CRX core emits. It scans Base Sepolia forward-only, persists every one of the 26 core events to its own database, and serves a read-only GraphQL API. After first boot, history lives in the indexer; upstream log pruning never matters again.
It is the durable counterpart to the live reads. The relayer is fast and the chain is authoritative, but neither retains history: the public RPC prunes old getLogs, and the relayer holds only what is in flight. The indexer retains all of it, queryable.
The following diagram shows the network flow:
The API is read-only: there are no mutations. It indexes the chain; it never writes to it.
Where is it?
The indexer serves one GraphQL endpoint, on the same-origin path prefix as the rest of the network:
INDEXER="https://app.crxfx.com/svc/indexer"
# POST GraphQL here
curl -s -X POST "$INDEXER/graphql" \
-H 'content-type: application/json' \
-d '{"query":"{ syncStatus { lastBlock head healthy } }"}'
# {"data":{"syncStatus":{"lastBlock":"…","head":"…","healthy":true}}}If the syncStatus response prints, the indexer is reachable.
A GET /svc/indexer/graphiql playground, a GET /svc/indexer/healthz, and a GET /svc/indexer/status (JSON sync state) sit beside it. Big numbers, addresses, and ids are strings (decimal or 0x-hex); times are ISO-8601.
Read one party's positions
positions(party:) matches a firm on the long or the short side. The shape mirrors the on-chain Position 1:1.
Query a party's positions using the following shape:
query Positions($party: String!) {
positions(party: $party, first: 100) {
id
acaId
longAcct
shortAcct
notional
pair
lockedRate
status # open | settled | closed | force_closed
finalRate
openedTime
closedTime
}
}Run the same query over curl using the following command:
curl -s -X POST "$INDEXER/graphql" \
-H 'content-type: application/json' \
-d '{"query":"query($p:String!){positions(party:$p,first:100){id pair notional status}}","variables":{"p":"0xYourAddress"}}'Read the markets
markets returns per-pair stats, computed in SQL at query time: open interest, rolling volume, trade count, and the last trade.
Query the markets using the following shape:
query Markets {
markets {
pair # "USD/PHP"
whitelisted
oracle
openInterest
volume24h
volume7d
tradeCount
lastTradeTime
}
}What does it index?
The indexer captures all 26 core events, and none are dropped; every one also lands raw, keyed by (txHash, logIndex), making a range re-scan harmless. The query surface groups them into entities; the table below shows each query and what it returns:
| Query | What it returns |
|---|---|
syncStatus | Last indexed block, chain head, healthy flag |
positions / position | Bound positions, by party / pair / status, or by id |
trades | Bound events, newest first |
markets | Per-pair open interest, volumes, trade count, last trade |
firms / firm | Registered makers and takers, with their state flags |
vmSettlements | Variation-margin transfers |
collateralFlows | Deposits, withdrawals, allocations, fills, claims |
creditEvents | Close-outs, cascades, suspensions, terminations (the Liquidation* / Defaulted event family) |
NoteThe chain is still the ledger. When an indexed figure and an on-chain read diverge, the on-chain read is authoritative.