> ## 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.

# Overview

> Real-time, venue-agnostic orderbook streaming over WebSocket

The streaming API pushes live, normalized orderbooks to you over a single
WebSocket connection. Subscribe to any market we support, and receive an
initial snapshot followed by a continuous, gap-free stream of price-level
changes — all in one message shape, regardless of which venue the market lives
on. An optional `trade` channel streams the market's public trade tape
alongside the book.

## How it works

* **One connection, many markets.** Open a single WebSocket and subscribe to
  as many markets as you need (up to a per-connection cap, see
  [limits](/streaming/connection#connection-limits)). Open more connections to
  scale past the cap — an account can hold up to 20 simultaneous connections
  (200 subscriptions each). Close connections you no longer need to stay under
  the limit; dropped or unresponsive connections are cleaned up automatically
  within about a minute and stop counting against it.
* **One subscription per `(market, channel)`.** Each subscription you create
  gets a server-assigned `subscriptionId`. Every frame for that subscription
  carries the id — you route incoming frames to your local book by it.
* **Snapshot, then deltas.** The first frame for a book subscription is a full
  `snapshot`. After that you receive `delta` frames carrying only the levels
  that changed. Apply them in order; the
  [sequencing contract](/streaming/orderbook#sequencing-and-resync) guarantees
  you never have to reconcile a gap yourself.
* **Optional trade tape.** Subscribe with `channels: ["trade"]` (or
  `["book", "trade"]`) to also receive one [`trade` frame](/streaming/trades)
  per fill on the market, from the moment you subscribe. Available on
  Polymarket; Limitless has no public trade feed, so trade subscribes there are
  rejected with `UNSUPPORTED_CHANNEL`.

## Prices and sizes

Every market is normalized to one scale:

| Field   | Unit                                                           |
| ------- | -------------------------------------------------------------- |
| `price` | Implied probability, a decimal in `[0, 1]` (dollars per share) |
| `size`  | Outcome shares                                                 |

A `Level` is `{ price, size }`. You receive separate `bids` and `asks` arrays
on a snapshot, and a flat list of `changes` on a delta where each change is
`{ side, price, size }` and `size: 0` means that price level is now gone.

## Step 1 — Get a stream key

WebSocket connections authenticate with a **stream API key**, distinct from
your REST API key. Stream keys look like:

```
parx_stream_<hex>_<checksum>
```

Stream keys are currently issued by ParlayX in a closed release. If you don't
have one yet and are interested in using this service,
[reach out to us](https://parlayx.com/contact).

## Step 2 — Identify the markets you want

Each market you stream is described by a `MarketStream` — a small object keyed
on `venue`. You build it from venue-native identifiers you already have, or
that you get from the [Markets API](/api-reference/markets/search-markets):

<CodeGroup>
  ```json Polymarket theme={null}
  { "venue": "polymarket", "outcomeId": "71045620195867637" }
  ```

  ```json Limitless theme={null}
  { "venue": "limitless", "kind": "clob", "marketId": "btc-100k-weekly", "outcomeId": "84329471234058196" }
  ```
</CodeGroup>

| Venue          | How to build the `MarketStream`                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Polymarket** | `outcomeId` is the ERC-1155 token id of the side you want. It is already outcome-specific (YES and NO are different token ids), so no separate outcome field is needed. The Markets API returns this as the outcome's `outcomeId`.                                                                                                                                                                                                                           |
| **Limitless**  | Pass `kind: "clob"`, the `marketId` (the market slug), and `outcomeId` — the outcome token id of the side you want, the same value the Markets API returns as the outcome's `outcomeId`. Both fields come straight from one discovery result. One slug covers both sides; you subscribe to YES and NO as two separate `MarketStream` entries, one per token. An `outcomeId` that matches neither of the slug's two tokens is rejected with `UNKNOWN_MARKET`. |

<Note>
  Limitless YES and NO are two views of one shared orderbook — the NO book is
  the exact complement of the YES book. You can subscribe to either or both;
  both stream accurately.
</Note>

## Step 3 — Connect and subscribe

Open the WebSocket, wait for the `welcome` frame, then send a `subscribe`. The
[Quickstart](/streaming/quickstart) walks through a complete, runnable example
for both venues. The full wire contract — every frame, the sequencing
guarantees, limits, errors, and disconnects — lives in the
[WebSocket API reference](/streaming/authentication), starting with
authentication.

<Tip>
  Using TypeScript? The official SDK ships a typed streaming client that handles
  the handshake, keepalive, and reconnect-with-resubscribe for you — see
  [`@parlayx/sdk/stream`](/sdk/stream/introduction).
</Tip>
