> For the complete documentation index, see [llms.txt](https://docs.hello.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello.trade/developer-tools/websocket-api/market-data.md).

# Market Data

Public market data WebSocket API for real-time market information

Public market data is available via WebSocket without authentication.

**Endpoint**: `wss://marketdata.app.hello.trade/ws`

## Available Channels

| Channel                                                                       | Description                                                                                                 |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [ticker](/developer-tools/websocket-api/market-data/light-tickers.md)         | Market data snapshots with prices, volume, 24h stats, mark prices, and funding rates                        |
| [orderbook](/developer-tools/websocket-api/market-data/partial-order-book.md) | Order book snapshots with configurable depth (1, 5, 10, 20, or 100 levels), sampled or live on every change |
| [trades](/developer-tools/websocket-api/market-data/live-trades.md)           | Real-time trade executions                                                                                  |
| [candles](/developer-tools/websocket-api/market-data/candles.md)              | OHLCV candlestick data with configurable intervals                                                          |
| [instruments](/developer-tools/websocket-api/market-data/instrument-list.md)  | Instrument list with metadata and status                                                                    |

***

## Connection

Connect to the WebSocket endpoint and subscribe to channels using JSON messages.

**CLI Example:**

```bash
wscat -c wss://marketdata.app.hello.trade/ws

# Subscribe to ticker for BTC and ETH
{"type":"subscribe","channel":"ticker","symbols":["BTC","ETH"]}

# Subscribe to orderbook
{"type":"subscribe","channel":"orderbook","symbols":["BTC"],"levels":10}

# Subscribe to all instruments
{"type":"subscribe","channel":"instruments"}
```

***

## Subscription Format

**Subscribe Request:**

```json
{
  "type": "subscribe",
  "channel": "channelName",
  "sid": "my-request-1",
  "symbols": ["BTC", "ETH"]
}
```

| Field     | Type      | Required | Description                                                                                                                                                                                                                                                                                                                                                                 |
| --------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`    | string    | Yes      | Must be `"subscribe"`                                                                                                                                                                                                                                                                                                                                                       |
| `channel` | string    | Yes      | Channel name (see Available Channels)                                                                                                                                                                                                                                                                                                                                       |
| `sid`     | string    | No       | Client-supplied identifier, echoed back on every response tied to this subscription (`subscribed` and `marketData` messages). Lets a client open multiple concurrent requests for the same channel/symbol (e.g. two different candle date ranges) and tell their responses apart, instead of relying on symbol matching. Omit it and nothing changes from today's behavior. |
| `symbols` | string\[] | Varies   | List of symbols (required for most channels, optional for `instruments`)                                                                                                                                                                                                                                                                                                    |

**Unsubscribe Request:**

```json
{
  "type": "unsubscribe",
  "channel": "channelName",
  "sid": "my-request-1",
  "symbols": ["BTC"]
}
```

`sid` is optional here too and is only echoed back on the `unsubscribed` confirmation — it doesn't change which subscription gets torn down (that's still determined by `channel` + params).

**Response Format:**

```json
{
  "type": "marketData",
  "channel": "channelName",
  "sid": "my-request-1",
  "data": {
    // Channel-specific data
  }
}
```

`sid` is only present in the response if the subscribe request included one; otherwise the field is omitted entirely, exactly as before.

***

## Error Response

```json
{
  "type": "error",
  "message": "Invalid subscription request",
  "code": 400
}
```

| Field     | Type      | Description                                                                                      |
| --------- | --------- | ------------------------------------------------------------------------------------------------ |
| `type`    | string    | Always `"error"`                                                                                 |
| `message` | string    | Human-readable reason                                                                            |
| `code`    | number    | See the table below                                                                              |
| `sid`     | string    | The request's `sid`. Only present on unknown-symbol errors, and only if the request included one |
| `symbols` | string\[] | The symbols the error applies to. Only present on unknown-symbol errors                          |

| Code | Description                                                   |
| ---- | ------------------------------------------------------------- |
| 400  | Invalid request, or unknown symbol                            |
| 429  | Too many candle history requests in flight on this connection |
| 503  | Live orderbook not yet loaded after a server restart; retry   |

### Unknown symbols

The `ticker`, `orderbook`, `trades` and `candles` channels only accept symbols listed on the [instruments](/developer-tools/websocket-api/market-data/instrument-list.md) channel. Any other symbol is rejected with a single error naming every rejected symbol:

```json
{
  "type": "error",
  "message": "Unknown symbols: ADBE, 1138.HK",
  "code": 400,
  "sid": "my-request-1",
  "symbols": ["ADBE", "1138.HK"]
}
```

* Valid symbols in the same request are still subscribed. The `subscribed` confirmation lists only the symbols that were accepted.
* If every symbol is rejected, no `subscribed` confirmation is sent.
* Use the `symbols` array rather than parsing `message`.

See individual channel documentation for detailed specifications and examples.
