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

# Authentication

> Connect to the orderbook stream and authenticate the WebSocket handshake

The orderbook stream lives at a single endpoint:

```
wss://wss.parlayx.com/v1/orderbook
```

Authentication happens **during the WebSocket upgrade** — there is no separate
login message and no token to refresh mid-stream. You either open the
connection authenticated, or the upgrade is rejected before the socket opens.

## Stream keys

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

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

One stream key authenticates every connection your account opens, up to your
[connection limit](/streaming/connection#connection-limits).

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

## Supplying the key

Supply your key one of three ways, in order of preference:

| # | Method                            | How                                                |
| - | --------------------------------- | -------------------------------------------------- |
| 1 | **Subprotocol** (preferred)       | `Sec-WebSocket-Protocol: parlayx.v1, key.<rawKey>` |
| 2 | **Authorization header**          | `Authorization: Bearer <rawKey>`                   |
| 3 | **Query parameter** (last resort) | `?api_key=<rawKey>`                                |

<Warning>
  Prefer the subprotocol or header. The `?api_key=` query parameter is supported
  as a fallback for clients that can't set headers, but query strings are
  commonly written to logs and proxies along the way — avoid it when you can.
</Warning>

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

const KEY = process.env.PARLAYX_STREAM_KEY;

// Preferred: pass the key as a subprotocol.
const ws = new WebSocket("wss://wss.parlayx.com/v1/orderbook", [
  "parlayx.v1",
  `key.${KEY}`,
]);

// Alternative: Authorization header.
// const ws = new WebSocket("wss://wss.parlayx.com/v1/orderbook", {
//   headers: { Authorization: `Bearer ${KEY}` },
// });
```

## Handshake responses

The outcome of authentication is an HTTP status on the upgrade request, before
any frame is sent:

| Status | Meaning                                                                                   | What to do                                                        |
| ------ | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `101`  | Switching Protocols — the connection is open.                                             | Wait for the [`welcome`](/streaming/connection#welcome) frame.    |
| `401`  | The key is missing or invalid.                                                            | Fix the key. Don't retry the same key.                            |
| `429`  | Your account is at its [`maxConnections`](/streaming/connection#connection-limits) limit. | Close a connection you no longer need; retrying alone won't help. |
| `503`  | The gateway is at capacity.                                                               | Back off briefly and retry — you'll be routed to fresh capacity.  |

Once the upgrade succeeds the server immediately sends a
[`welcome`](/streaming/connection#welcome) frame. From there, see
[Subscriptions & markets](/streaming/subscriptions) to start streaming.
