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

# WebSocket candle Channel: Real-Time OHLCV Bar Updates

> Subscribe to the candle WebSocket channel to receive live OHLCV bar updates for a contract at your chosen interval, including closed-bar events.

The `candle` channel delivers live OHLCV updates for a contract at a specified interval. The current open bar is pushed approximately every 500 ms as new trades arrive within the bar. When a bar closes at an interval boundary, the server pushes the finalized closed bar (with `"closed": true`) immediately followed by the first update for the new open bar — so your chart never misses a transition. To show historical candles before the subscription starts, call the REST `candleSnapshot` endpoint first, then use the WebSocket stream for all subsequent updates.

## Subscribing

```json theme={"system"}
{
  "method": "subscribe",
  "subscription": {"type": "candle", "asset": "1", "interval": "1m"}
}
```

<ParamField body="asset" type="string" required>
  The numeric contract ID to receive candles for.
</ParamField>

<ParamField body="interval" type="string" required>
  The candle interval. Accepts the same values as the `candleSnapshot` REST endpoint: `1m`, `3m`, `5m`, `15m`, `30m`, `1h`, `2h`, `4h`, `8h`, `12h`, `1d`, `3d`, `1w`, `1M`.
</ParamField>

## Push message format

```json theme={"system"}
{
  "channel": "candle",
  "ts": 1782279307885,
  "data": {
    "s": "1",
    "i": "1m",
    "t": 1782279300000,
    "T": 1782279360000,
    "o": "110",
    "c": "70",
    "h": "110",
    "l": "70",
    "v": "15",
    "n": 6,
    "closed": false
  }
}
```

## Field reference

<ResponseField name="ts" type="number">
  Server send timestamp in Unix milliseconds.
</ResponseField>

<ResponseField name="data.s" type="string">
  Contract ID. Matches the `asset` value in your subscription.
</ResponseField>

<ResponseField name="data.i" type="string">
  Interval of this candle (e.g., `"1m"`).
</ResponseField>

<ResponseField name="data.t" type="number">
  Bar open time — Unix milliseconds at the start of this interval bucket.
</ResponseField>

<ResponseField name="data.T" type="number">
  Bar close time — Unix milliseconds at the end of this interval bucket (exclusive).
</ResponseField>

<ResponseField name="data.o" type="string">
  Open price of the bar (raw string). This is the price of the first trade in the interval.
</ResponseField>

<ResponseField name="data.h" type="string">
  Highest trade price within the bar (raw string).
</ResponseField>

<ResponseField name="data.l" type="string">
  Lowest trade price within the bar (raw string).
</ResponseField>

<ResponseField name="data.c" type="string">
  Close price of the bar (raw string). For an open bar, this is the price of the most recent trade so far.
</ResponseField>

<ResponseField name="data.v" type="string">
  Total traded volume within the bar (raw string).
</ResponseField>

<ResponseField name="data.n" type="number">
  Number of individual trades that make up this bar.
</ResponseField>

<ResponseField name="data.closed" type="boolean">
  `false` for an in-progress open bar. `true` for a finalized closed bar — this message is pushed exactly once at the interval boundary and will not be updated further.
</ResponseField>

## Initialising a chart

<Steps>
  <Step title="Fetch historical candles via REST">
    Call the `candleSnapshot` endpoint with your chosen `asset` and `interval` to load historical OHLCV data. Render these bars as the initial chart state.
  </Step>

  <Step title="Subscribe to the WebSocket candle channel">
    Subscribe using the same `asset` and `interval`. Buffer incoming WebSocket messages while the REST response is in-flight.
  </Step>

  <Step title="Merge on bar open time (t)">
    Once you have both datasets, use `data.t` as the key. Replace or append bars from the WebSocket stream — for any bar where `data.t` matches an existing bar from REST, the WebSocket version is newer and should take precedence.
  </Step>

  <Step title="Handle closed-bar events">
    When you receive a message with `"closed": true`, finalize that bar in your chart. The next message will carry the new open bar with a later `t` value.
  </Step>
</Steps>

<Tip>
  You can subscribe to multiple intervals for the same asset simultaneously — for example, `1m` and `1h` — each as a separate subscription. They operate independently and do not interfere with each other.
</Tip>

<Note>
  All price and volume values are raw strings. Apply the contract's decimal precision before rendering values on a chart.
</Note>
