Real-Time Orderbook
Stream a live aggregated orderbook with the SDK, hooks, or UI components
The AGG WebSocket delivers a full aggregated orderbook snapshot on subscribe, then incremental deltas as the book changes. Each outcome has its own orderbook — there is no complement derivation. Each level includes per-venue attribution so you can render both the aggregated depth and the venue breakdown from the same stream.
Orderbook subscriptions are keyed by venueMarketOutcomeId — the outcomes[].id on REST
market responses — not by venueMarketId. Subscribing with a venueMarketId never resolves a
book and the gateway replies with a Snapshot unavailable error. (Only the REST
GET /orderbooks endpoint and the arb streams use market-level ids.)
Full control over the WebSocket connection and local orderbook state.
1. Connect and subscribe
import { createAggClient } from "@agg-build/sdk";
const client = createAggClient({
baseUrl: "https://api.agg.market",
appId: "your-app-id",
wsUrl: "wss://ws.agg.market/ws",
});
let book = null;
const ws = client.createWebSocket({
onSnapshot: (_outcomeId, nextBook) => {
book = nextBook;
renderOrderbook(book);
},
onDelta: (_outcomeId, nextBook) => {
book = nextBook;
renderOrderbook(book);
},
onError: (msg) => {
console.error(msg.message);
},
});
ws.subscribe("your-outcome-id", "orderbook");The SDK applies snapshots and deltas for you, tracks seq, validates checksum (XOR of
per-level CRC32), drops stale deltas where seq <= current.seq, and requests a fresh snapshot
when integrity checks fail. The gateway is a stateless fan-out — all orderbook recovery is
handled client-side by the SDK.
2. Read the orderbook
The OrderbookState passed to callbacks uses object-shaped levels:
interface OrderbookState {
outcomeId: string;
bids: Array<{ price: number; size: number; venues: Record<string, number> }>;
asks: Array<{ price: number; size: number; venues: Record<string, number> }>;
venueOrderbooks: Record<
string,
{
bids: Array<{ price: number; size: number }>;
asks: Array<{ price: number; size: number }>;
}
>;
venues: Record<string, { bestBid: number | null; bestAsk: number | null }>;
midpoint: number | null;
spread: number | null;
seq: number;
checksum: number;
timestamp: number; // seconds
}3. Per-venue orderbooks
Per-venue depth is available on the same object:
const ws = client.createWebSocket({
onSnapshot: (_outcomeId, book) => {
console.log(book.venueOrderbooks.predict?.bids);
console.log(book.venueOrderbooks.polymarket?.asks);
},
});4. REST fallback
For one-time fetches without a live socket:
const response = await client.getOrderbooks({
venueMarketIds: ["your-market-id"],
depth: 20,
});
const book = response.data[0];
if (book?.status !== "ok") {
throw new Error(book?.error?.message ?? "No live orderbook available");
}
// book.venueOrderbooks — per-venue depth keyed by venue
// book.matchedMarkets — venue markets considered for the requested market
// book.requestedMarket — lifecycle metadata for the requested marketIntegrity
The SDK verifies seq and checksum automatically and requests a fresh snapshot when the local
book drifts. If you are implementing the wire protocol yourself, use the
WebSocket Protocol page for the snapshot/delta formats and resnapshot flow.