Real-Time Orderbook
Stream a live aggregated orderbook with the SDK, hooks, or UI components
The sufwan-local-test 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.)
For bounded REST snapshots and the shared single/batch outcome-unit quota, see Market-data API. That guide also explains snapshotChecksum versus the full engine checksum and optional native Worker ownership.
Orderbook socket: wss://ob.agg.market/ws. The orderbook channel can run on its own socket
with the same snapshot and delta objects. It keeps the 100 ms default and adds an opt-in
realtime tier ("latency": "realtime" on subscribe). Backends can also stream every book on a
venue from it once Snag enables the firehose for their app.
Orderbook streams
Move this channel to orderbookUrl, and choose the 100 ms or realtime tier.
Orderbook firehose
Every non-empty book for selected venues, from a backend with an app API key.
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.t.sufwankhalid.com",
appId: "your-app-id",
wsUrl: "wss://ws.t.sufwankhalid.com/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);
},
});
const venueMarketOutcomeId = "vmo_1";
ws.subscribe(venueMarketOutcomeId, "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. It also runs a 5-minute book watchdog; see
Integrity.
2. Read the orderbook
Orderbook timestamp is Unix milliseconds on the wire, and the SDK reports it as seconds.
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 (SDK converts wire milliseconds)
}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 keeps each book correct without any code from you:
- Seq and checksum: it applies deltas only in order, verifies every
checksum, and requests a fresh snapshot when either check fails. - Server-sent snapshots: if sufwan-local-test rebuilds a book, its
seqrestarts and the gateway sends a new snapshot with the first update from it. The SDK replaces the book with it. - Connection liveness: it reconnects with backoff after 45 seconds with no frame, and
re-subscribes everything. Reconnects authenticate with the token from your latest
authenticate()call. - Resolution: on
market_resolvedit drops the outcome's book and callsonMarketResolved. - Book watchdog: heartbeats only prove the connection is alive. Once a minute, the SDK checks
any book with no update for 5 minutes against
GET /orderbooks/outcomes(see Market-data API). A matchingseqmeans the market is just quiet. A differentseqtriggers a resnapshot, then a resubscribe if the next check still differs or the snapshot never arrives.
The watchdog is on for sockets from client.createWebSocket(), which the hooks and UI components
use too (always with the default timings). Each check costs one market-data quota unit per
silent outcome, and it pauses for Retry-After on a 429. With the SDK directly, tune or
disable it:
const ws = client.createWebSocket(callbacks, {
bookWatchdog: { silenceMs: 10 * 60_000, checkIntervalMs: 2 * 60_000 },
// or: bookWatchdog: false
});Watch it through onDiagnostics:
const ws = client.createWebSocket({
onDiagnostics: (event) => {
if (event.type === "book_watchdog_resync") {
// { outcomeId, localSeq, serverSeq, action: "resnapshot" | "resubscribe" }
console.warn("orderbook healed", event);
}
if (event.type === "book_watchdog_error") {
// { status } — the REST check failed; the next tick retries
}
},
});If you are implementing the wire protocol yourself, follow Staleness checks and Best practices on the WebSocket Protocol page.
Related
WebSocket Protocol
Wire format, sequencing, resnapshot requests, and heartbeat behavior.
Orderbook streams
The 100 ms default, the realtime opt-in, and a separate orderbook socket.
Orderbook firehose
Every book on a venue, from a backend, after Snag enables it.
Real-Time Charts
Build live candles from the same orderbook and trade streams.
User Notifications
Authenticated order and balance events on the same WebSocket connection.