> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parlayx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Connect, subscribe to a market, and maintain a live orderbook

This walks the full path: connect, subscribe to a market's `book` channel,
apply the initial snapshot, then keep it current with delta frames. The client
handles the handshake, keepalive, and reconnect for you — you just handle frames.

```ts theme={null}
import { createStreamClient } from "@parlayx/sdk/stream";

const stream = createStreamClient({ streamKey: process.env.PARLAYX_STREAM_KEY! });

/* A local book we keep in sync from snapshot + delta frames. */
const book = { bids: new Map<number, number>(), asks: new Map<number, number>() };

/* The full book state. Arrives once per subscription, before any deltas. */
stream.on("snapshot", (frame) => {
  book.bids = new Map(frame.bids.map((l) => [l.price, l.size]));
  book.asks = new Map(frame.asks.map((l) => [l.price, l.size]));
  console.log(`snapshot seq=${frame.seq}: ${book.bids.size} bids / ${book.asks.size} asks`);
});

/* Incremental changes. size 0 deletes the level; anything else sets it. */
stream.on("delta", (frame) => {
  for (const change of frame.changes) {
    const side = change.side === "bid" ? book.bids : book.asks;
    if (change.size === 0) side.delete(change.price);
    else side.set(change.price, change.size);
  }
});

/* Subscribe. The `book` channel is the default, so `channels` is optional. */
stream.subscribe([{ venue: "polymarket", outcomeId: "71045620195867637" }]);
```

`subscribe` takes an array of markets, so you can open many subscriptions in one
call. Each market is a `MarketStream` — a discriminated union on `venue`
(`polymarket` needs only an `outcomeId`; `limitless` also needs `kind` and
`marketId`). See the WebSocket API's
[Subscriptions & markets](/streaming/subscriptions) for the market shapes and
[Orderbook channel](/streaming/orderbook) for price/size units and the gap-free
`seq` guarantee.

## Confirming and closing

The server acks each subscription with a `subscribed` frame carrying the
`subscriptionId` that keys every subsequent frame. Capture it if you want to
unsubscribe later, and close the client when you're done:

```ts theme={null}
let subscriptionId: string | undefined;

stream.on("subscribed", (frame) => {
  subscriptionId = frame.subscriptionId;
  console.log(`subscribed ${frame.subscriptionId} (${frame.channel})`);
});

/* later… */
if (subscriptionId) stream.unsubscribe([subscriptionId]);
stream.close(); /* closes the socket and stops reconnecting */
```

`subscribe`/`unsubscribe` are safe to call before the socket is open — the client
replays your active subscriptions automatically on connect (and on every
reconnect). See [Events](/sdk/stream/events) for the full frame set and
[Reconnection & lifecycle](/sdk/stream/reconnection) for what happens across
disconnects.

## Client options

Besides the required `streamKey` (see [Authentication](/sdk/stream/authentication)),
`createStreamClient` accepts two optional settings:

```ts theme={null}
import WebSocket from "ws";

const stream = createStreamClient({
  streamKey: process.env.PARLAYX_STREAM_KEY!,
  baseUrl: "wss://wss.parlayx.com", /* override the origin (e.g. staging); path is always /v1/orderbook */
  WebSocket, /* inject a WebSocket implementation for tests or Node.js older than 22 */
});
```

`baseUrl` defaults to production; `WebSocket` defaults to the runtime's global
`WebSocket` (Node.js 22+, modern browsers, edge), so you only pass it on older
Node or to supply a custom implementation.
