# allCandles

{% hint style="info" %}
This endpoint requires special permission on your API key. Contact us to enable it.
{% endhint %}

Streams candle updates for **every coin** at a given interval, batched per block. Each message contains an array of candle snapshots — one per coin that had trading activity in that block. This is ideal for building dashboards, heatmaps, or any application that needs cross-market candle data without managing individual per-coin subscriptions.

For single-coin candle streaming, see [`candles`](/readme/websocket/candles.md).

### Subscribe

```json
{
    "method": "subscribe",
    "subscription": {
        "type": "allCandles",
        "interval": "1m"
    }
}
```

| Field      | Type   | Required | Description                                                                                                  |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------ |
| `interval` | string | Yes      | Candle interval: `1s`, `1m`, `3m`, `5m`, `15m`, `30m`, `1h`, `2h`, `4h`, `8h`, `12h`, `1d`, `3d`, `1w`, `1M` |

### Unsubscribe

```json
{
    "method": "unsubscribe",
    "subscription": {
        "type": "allCandles",
        "interval": "1m"
    }
}
```

### Update data format

Each message contains an array of candle snapshots batched per block. Only coins with trading activity in the block are included.

```json
{
    "type": "allCandles",
    "seq": 5,
    "cursor": "1700000040000",
    "data": [
        {
            "s": "BTC",
            "i": "1m",
            "t": 1700000040000,
            "T": 1700000099999,
            "o": "45000.00",
            "h": "45100.50",
            "l": "44980.00",
            "c": "45050.25",
            "v": "123.45",
            "q": "5560125.00",
            "n": 312,
            "x": false
        },
        {
            "s": "ETH",
            "i": "1m",
            "t": 1700000040000,
            "T": 1700000099999,
            "o": "2150.00",
            "h": "2155.50",
            "l": "2148.00",
            "c": "2153.25",
            "v": "456.78",
            "q": "982345.00",
            "n": 189,
            "x": false
        }
    ]
}
```

### Field definitions

**Envelope fields:**

| Field    | Type   | Description                                                            |
| -------- | ------ | ---------------------------------------------------------------------- |
| `type`   | string | Always `"allCandles"`                                                  |
| `seq`    | number | Per-subscription sequence number (starts at 1, increments per message) |
| `cursor` | string | Candle open time as millisecond timestamp string (for session replay)  |

**Candle fields (each item in `data`):**

| Field | Type    | Description                                                     |
| ----- | ------- | --------------------------------------------------------------- |
| `s`   | string  | Coin name                                                       |
| `i`   | string  | Interval string                                                 |
| `t`   | number  | Candle open time (milliseconds, interval start)                 |
| `T`   | number  | Candle close time (milliseconds, interval end)                  |
| `o`   | string  | Open price                                                      |
| `h`   | string  | High price                                                      |
| `l`   | string  | Low price                                                       |
| `c`   | string  | Close (latest) price                                            |
| `v`   | string  | Volume in base asset                                            |
| `q`   | string  | Quote volume (notional value)                                   |
| `n`   | number  | Number of trades                                                |
| `x`   | boolean | `true` if the candle is closed/finalized, `false` if still open |

### Chunking

`allCandles` supports live message chunking. When enabled via `liveFormat=chunked-v1` in your connection URL, large batches are split into smaller messages with `chunk`, `totalChunks`, and `batchId` fields. See [Live Message Chunking](/readme/websocket/live-message-chunking.md) for details.

### Session replay

`allCandles` supports session replay. On reconnect with a session, missed candle updates are replayed from the cursor. The cursor represents the candle open timestamp.

### Limits

Only one `allCandles` subscription is allowed per API key. To stream multiple intervals, subscribe once per interval (each counts as a separate subscription).

### Examples

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const WebSocket = require('ws');

const ws = new WebSocket(`wss://api.hydromancer.xyz/ws?token=${process.env.HYDROMANCER_API_KEY}`);

ws.on('message', (data) => {
    const msg = JSON.parse(data);

    if (msg.type === 'connected') {
        ws.send(JSON.stringify({
            method: 'subscribe',
            subscription: {
                type: 'allCandles',
                interval: '1m'
            }
        }));
    } else if (msg.type === 'ping') {
        ws.send(JSON.stringify({ type: 'pong' }));
    } else if (msg.type === 'allCandles') {
        for (const c of msg.data) {
            const status = c.x ? 'CLOSED' : 'open';
            console.log(`[${status}] ${c.s} ${c.i}  O=${c.o} H=${c.h} L=${c.l} C=${c.c} V=${c.v} trades=${c.n}`);
        }
    }
});
```

{% endtab %}

{% tab title="Python" %}

```python
import websocket
import json
import os

def on_message(ws, message):
    msg = json.loads(message)

    if msg['type'] == 'connected':
        ws.send(json.dumps({
            "method": "subscribe",
            "subscription": {
                "type": "allCandles",
                "interval": "1m"
            }
        }))
    elif msg['type'] == 'ping':
        ws.send(json.dumps({'type': 'pong'}))
    elif msg['type'] == 'allCandles':
        for c in msg['data']:
            status = 'CLOSED' if c['x'] else 'open'
            print(f"[{status}] {c['s']} {c['i']}  O={c['o']} H={c['h']} L={c['l']} C={c['c']} V={c['v']} trades={c['n']}")

ws = websocket.WebSocketApp(
    f"wss://api.hydromancer.xyz/ws?token={os.environ.get('HYDROMANCER_API_KEY')}",
    on_message=on_message
)
ws.run_forever()
```

{% endtab %}
{% endtabs %}

### Common errors

| Error                | Cause                                                           |
| -------------------- | --------------------------------------------------------------- |
| `Invalid interval`   | Interval string not in the valid list                           |
| `Permission denied`  | API key does not have the required permission                   |
| `Connection timeout` | Not responding to ping messages — reply with `{"type": "pong"}` |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hydromancer.xyz/readme/websocket/allcandles.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
