API reference
WebSocket
One connection, JSON frames, channel subscriptions. The socket powers the app’s live order books; API keys get the same feed.
Connect
/v1/wsX-Thassa-Key or ?key=Authenticate on connect with the X-Thassa-Key header, or ?key= where headers are unavailable (browsers). Either scope (read or trade) may subscribe to market-data channels.
import WebSocket from "ws";
const ws = new WebSocket("ws://localhost:8080/v1/ws", {
headers: { "X-Thassa-Key": process.env.THASSA_KEY! },
});
ws.on("open", () => {
ws.send(JSON.stringify({ type: "subscribe", channel: "book:42" }));
});
ws.on("message", (raw) => {
const { type, channel, payload } = JSON.parse(raw.toString());
if (type === "book.delta") applyDelta(payload);
if (type === "book.trade") recordTrade(payload);
});Frame shape
Every frame — both directions — is:
{ "type": "…", "channel": "…", "payload": { … } }Subscribing
API keys subscribe to order-book channels: book:{marketId} — order-book deltas plus trades for one market. Subscribe to as many markets as you need on a single connection.
// client → server
{ "type": "subscribe", "channel": "book:42" }
{ "type": "unsubscribe", "channel": "book:42" }Channel authorization
dm:{conversationId} and user:{me} channels; API keys are for book:* market data.Events
Book deltas
// server → client: a price level changed (shares = new total at the level;
// "0" removes the level)
{
"type": "book.delta",
"channel": "book:42",
"payload": {
"market_id": "42",
"side": "yes",
"price_cents": 62,
"shares": "1150"
}
}Trades
// server → client: a fill occurred
{
"type": "book.trade",
"channel": "book:42",
"payload": {
"market_id": "42",
"side": "yes",
"price_cents": 62,
"shares": "300",
"fee": "1649200",
"tx_hash": "0x8c31…e9d0",
"created_at": "2026-07-15T21:09:44Z"
}
}The recommended pattern: fetch the snapshot from GET /trade-api/v1/markets/{id}/book after subscribing, then apply deltas — replacing each level’s total with payload.shares. Deltas are totals, not increments, so a missed frame self-heals on the next delta for that level.
Connection lifecycle
- The server pings periodically; unresponsive connections are dropped. Reply with standard pongs (every client library does this automatically).
- On reconnect, re-subscribe and re-fetch snapshots — subscriptions don’t survive the connection.
- Delivery is best-effort; the REST book endpoint is always the recoverable source of truth.