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

# Protocol description

> Understanding the WebSocket protocol structure and message formats

Our WebSocket API follows the [RFC 6455](https://datatracker.ietf.org/doc/html/rfc6455) standard. It is designed to be lightweight and persistent. Once a connection is established, it remains open until explicitly closed by the client or if rate limits are exceeded.

<Note>
  Standard PING/PONG control frames are disabled to reduce overhead. The connection relies on the underlying TCP keepalive mechanisms.
</Note>

## Connection Flow

### 1. Establish Connection

Connect to the WebSocket endpoint (e.g., `wss://api.xchangeapi.com/websocket/live`).

### 2. Subscribe to Pairs

Immediately after connecting, send a JSON message to subscribe to specific currency pairs:

```json theme={null}
{
  "pairs": ["EURUSD", "GBPCHF"]
}
```

### 3. Receive Initial Configuration

Upon successful subscription, the server sends an **Initial Message** (Code `0`). This message contains session details and the mapping definitions required to parse subsequent updates.

**Example Initial Message:**

```json theme={null}
0{"session_uid":"***","time_mult":1000,"start_time":1594922406.851688,"order":["name","ask","bid","time"],"mapping":{"0":"EURUSD","1":"GBPCHF"}}
```

| Parameter     | Type   | Description                                                                                               |
| :------------ | :----- | :-------------------------------------------------------------------------------------------------------- |
| `session_uid` | string | Unique identifier for the current session.                                                                |
| `time_mult`   | number | Time multiplier used to decode relative timestamps (usually `1000` to convert milliseconds).              |
| `start_time`  | number | The base Unix timestamp (in seconds). All subsequent updates provide time relative to this value.         |
| `order`       | array  | Defines the order of fields in the update messages (e.g., `["name", "ask", "bid", "time"]`).              |
| `mapping`     | object | Maps numeric IDs to currency pair names (e.g., `"0": "EURUSD"`). Updates use these IDs to save bandwidth. |

***

## Message Structure

All server messages start with a single-digit **Message Code**, followed by the message body.

### Message Codes

| Code | Type    | Description                                        |
| :--- | :------ | :------------------------------------------------- |
| `0`  | Initial | Configuration and mapping data (JSON format).      |
| `1`  | Update  | Live currency rate update (Pipe-delimited format). |

See [Message Codes](/docs/websocket/message-codes) for a complete list.

### Processing Updates (Code 1)

Update messages are optimized for size and speed. They are **not** JSON. Instead, they use a pipe-separated format prefixed by the message code `1`.

**Format:**
`1[PairID]|[Ask]|[Bid]|[RelativeTime]`

**Example:**

```text theme={null}
11|1.18912|1.18860|10
```

**Breakdown:**

| Part        | Value     | Description                                                          |
| :---------- | :-------- | :------------------------------------------------------------------- |
| **Code**    | `1`       | Indicates this is a Data Update.                                     |
| **Pair ID** | `1`       | Corresponds to `GBPCHF` (from the `mapping` in the Initial Message). |
| **Ask**     | `1.18912` | The current ask price.                                               |
| **Bid**     | `1.18860` | The current bid price.                                               |
| **Time**    | `10`      | Relative timestamp.                                                  |

### Calculating timestamps

To get the actual time of an update, combine the `start_time` from the Initial Message with the relative time from the update.

**Formula:**

$$
\text{Timestamp} = \text{start\_time} + \frac{\text{relative\_time}}{\text{time\_mult}}
$$

**Example Calculation:**
Using the values from the examples above:

* `start_time`: `1594922406.851688`
* `time_mult`: `1000`
* `relative_time`: `10`

```python theme={null}
timestamp = 1594922406.851688 + (10 / 1000)
# Result: 1594922406.861688
```
