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

# WebSocket API

> The streaming half of the TakeProfit Platform API: how the handshake authenticates, the query parameters the channels share, what frames each stream delivers, and how a stream ends.

Live market data over WebSocket: candles, volume footprint profiles and order books. Subscription parameters go in the query string of the connection URL, and the server pushes JSON text frames until you disconnect. The client sends nothing after the handshake.

```bash theme={null}
websocat -H "x-api-key: $TAKEPROFIT_API_KEY" \
  "wss://public-api.takeprofit.com/api/v1/marketdata/candles/stream?exchange=CXBNCE&symbol=BTC%2FUSDT&timeframe=1m"
```

Base URL: `wss://public-api.takeprofit.com/api/v1/marketdata`. History is a separate protocol — see the [REST API](/docs/platform-api/rest/overview).

## Streams

<CardGroup cols={3}>
  <Card title="Candles" icon="chart-candlestick" href="/docs/platform-api/websocket/candles">
    The latest candle, then live updates of the forming one.
  </Card>

  <Card title="Volume footprint" icon="chart-simple" href="/docs/platform-api/websocket/footprint">
    An optional historical snapshot, then complete profile replacements.
  </Card>

  <Card title="Order book" icon="layer-group" href="/docs/platform-api/websocket/orderbook">
    One snapshot of the top levels per side, then incremental updates.
  </Card>
</CardGroup>

| Stream | Path | Required parameters |
| - | - | - |
| Candles | `/candles/stream` | `exchange`, `symbol`, `timeframe` |
| Footprint | `/footprint/stream` | `exchange`, `symbol`, `timeframe` |
| Order book | `/orderbook/stream` | `exchange`, `symbol` |

## The handshake

The API key goes in the `x-api-key` header of the upgrade request, exactly as in REST. One header value is required; duplicate or comma-combined values are rejected. A failed handshake answers with a regular HTTP response and a JSON body:

| Status | Meaning |
| - | - |
| `400` | Invalid query, or no WebSocket upgrade |
| `401` | Authentication failed |
| `403` | Permission denied |
| `405` | A method other than `GET` |
| `429` | Credit quota exhausted |
| `503` | Service unavailable |

Unknown query parameters and repeated scalar parameters are rejected, and historical range parameters such as `from`, `to` and `limit` are not accepted: use REST for history.

## Parameters the streams share

| Parameter | Applies to | Notes |
| - | - | - |
| `exchange`, `symbol` | all streams | Required. The same pair the REST Securities endpoints return. |
| `timeframe` | candles, footprint | Required. Footprint takes minute to month frames. |
| `throttlingDelay` | all streams | Milliseconds, up to 60000. A positive delay coalesces updates into at most one frame per delay; `0` or omitted forwards every upstream batch. |
| `sessionType` | candles, footprint | Session filter. Candles default to `MAINSESSION`; footprint delivers every session type when omitted. |
| `properties` | candles | Candle fields to include, such as `close,volume`. The timestamp is always present. |
| `rowSize`, `rowSizeValue` | footprint | Price row height in ticks, or an absolute value that pins the price grid. |
| `since` | footprint | Start of the initial snapshot. Omitted means no snapshot: the first live profile arrives when the next period opens. |
| `depth` | order book | Levels per side, default 200; `0` streams the full book. |

## Frames

Every frame carries a `type` and a `meta` echo of the normalized subscription parameters.

| Frame | Stream | What it means |
| - | - | - |
| `candle` | candles | A replayed or updated candle. |
| `rowSize` | footprint | The price grid resolved for this subscription. Echo it back as `rowSizeValue` in REST to load history on the same grid. |
| `rangeTruncated` | footprint | The history depth limit moved your `since` forward. Its presence tells a trimmed answer apart from a security with no data that far back. |
| `footprint` | footprint | One complete profile. `isLast` marks the frame that ends the initial snapshot. |
| `snapshot` | order book | The full top-`depth` view, exactly once per connection. |
| `update` | order book | Changed levels only; size `"0"` removes a level. |
| `error` | all streams | A terminal error; the socket closes right after it. |

Order book levels are keyed by numeric price, so `"1.5"` and `"1.50"` are the same level. An upstream resync is absorbed into a regular `update`, so you never see a second `snapshot`.

Error frames carry a stable code: `canceled`, `invalid_argument`, `unauthenticated`, `permission_denied`, `not_found`, `conflict`, `resource_exhausted`, `deadline_exceeded`, `unimplemented`, `unavailable` or `upstream_error`.

## Credits

A subscription is charged once when upstream data confirms it is active, not per frame. A stream that dies on a terminal upstream error before that is not charged. The handshake needs the full subscription price in remaining credits, otherwise it is rejected with `429`.
