> For the complete documentation index, see [llms.txt](https://docs.ethereal.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ethereal.trade/developer-guides/trading-api/websockets/socket.io-deprecated.md).

# Socket.io (deprecated)

Ethereal uses [Socket.io](https://socket.io/docs/v4/), a library that extends the standard WebSocket protocol. Socket.io provides ready-made client libraries in multiple languages with automatic reconnection handling and built-in ping/pong frames to maintain stable connections, saving developers from implementing these basic features themselves.

Refer to [Socket.io](https://socket.io/docs/v4/#client-implementations) for language specific client implementations.

{% hint style="warning" %}
Socket.io **has now been replaced with native web sockets and will be removed in a future release**. Ensure you transition to using native websockets to prevent any disruptions in the future.
{% endhint %}

{% hint style="success" %}
**Migration** *Native* WebSockets will be available on testnet first for integrators to test and provide feedback. After mainnet release, both Socket.io and native WebSockets will remain available for a transition period to allow a smooth migration without disruption.
{% endhint %}

<table><thead><tr><th width="370.79296875">URL</th><th>Status</th></tr></thead><tbody><tr><td><code>wss://ws.ethereal.trade/v1/stream</code></td><td>Live - Soon to be deprecated</td></tr></tbody></table>

### WebSockets

Ethereal also offers WebSocket support, which communicates with plain JSON payloads, resulting in lower latency, reduced overhead, and smaller message sizes. This makes it well-suited for latency-sensitive integrations and lightweight clients that don't need the built-in reconnections provided by Socket.io.

Websockets support a subset of the Socket.io feeds. If you require additional data streams, use the Socket.io gateway above which supports the full set of subscription types.

## `Socket.io` Subscription Streams

### Subscribe

The WebSocket gateway offers the following subscription streams:

**`BOOK_DEPTH`** - Provides order book depth updates for a specific product.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "BookDepth",
  "productId": "<uuid>"
}

// Response message
{
  "timestamp": "<epoch>",
  "previousTimestamp": "<epoch>",
  "productId": "<uuid>",
  "asks": [[price: string, quantity: string]],
  "bids": [[price: string, quantity: string]],
  "t": "<epoch>"
}
```

{% endcode %}

* `BookDepth` events are emitted on a configurable fixed interval (as of writing, this is configured to be **once every 200ms**)
* `previousTimestamp` is in milliseconds and represents the last time the `BookDepth` emitted
* `timestamp` also in milliseconds and the system timestamp of when this `BookDepth`was emitted
* Using both the `previousTimestamp` and `timestamp` you can infer whether or not any events were missed during connection or during consumption
* `asks` an array of price/quantity tuples representing asks
* `bids` an array of price/quantity tuples representing bids
* `t` represents server time when response was published (epoch in miliseconds)

{% hint style="warning" %}
A `BookDepth` message of the current book **(up to 100 price levels per side)** is emitted back on initial connection. Every subsequent message is a price level diff with absolute quantities. A zero quantity price diff indicates that this level has been removed.
{% endhint %}

**`MARKET_PRICE`** - Delivers real-time market price updates for a specified product.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "MarketPrice",
  "productId": "<uuid>"
}

// Response message (same as `/v1/product/market-price`)
// @see: https://api.ethereal.trade/docs#/Product/ProductController_getMarketPrice
{
  "productId": "<uuid>",
  "bestBidPrice": numberString,
  "bestAskPrice": numberString,
  "oraclePrice": numberString,
  "price24hAgo": numberString,
  "t": "<epoch>"
}
```

{% endcode %}

* `MarketPrice` events are emitted on a configurable fixed interval (currently configured to be **once every second**)
* `t` represents server time when response was published (epoch in miliseconds)

**`ORDER_FILL`** - Notifies when orders are filled for a specific subaccount.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "OrderFill",
  "subaccountId": "<uuid>"
}

// Response message (same as `/v1/order/fill`)
// @see: https://api.ethereal.trade/docs#/Order/OrderController_listFillsBySubaccountId
{
  "data": [
      {
        "id": "<uuid>",
        "orderId": "<uuid>",
        "clientOrderId": "string",
        "price": numberString,
        "filled": numberString,
        "type": "LIMIT|MARKET",
        "side": 0|1,
        "reduceOnly": boolean,
        "feeUsd": numberString,
        "isMaker": boolean,
        "productId": "<uuid>",
        "subaccountId": "<uuid>",
        "createdAt": "<epoch>"
      }
    ],
  "t": "<epoch>"
}
```

{% endcode %}

* `OrderFill` events are emitted in real-time as they occur
* `t` represents server time when response was published (epoch in miliseconds)

**`TRADE_FILL`** - Provides a stream of trades that have occurred filtered by product.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "TradeFill",
  "productId": "<uuid>"
}

// Response message
{
  "data": [
    {
      "id": "<uuid>",
      "price": numberString,
      "filled": numberString,
      "takerSide": 0|1,
      "createdAt": "<epoch>"
    }
  ],
  "productId": "<uuid>",
  "t": "<epoch>"
}
```

{% endcode %}

* `TradeFill` events are emitted in real-time as they occur
* `t` represents server time when response was published (epoch in miliseconds)
* Similar to `OrderFill`, an array of trade fills will be emitted in a single message, grouped by the product they were traded on

**`ORDER_UPDATE`** - Provides updates about order status changes for a specific subaccount.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "OrderUpdate",
  "subaccountId": "<uuid>"
}

// Response message (same as `/v1/order`)
// @see https://api.ethereal.trade/docs#/Order/OrderController_listBySubaccountId
{
  "data": [
    {
      "id": "<uuid>",
      "clientOrderId": "string",
      "type": "LIMIT"|"MARKET",
      "availableQuantity": numberString,
      "quantity": numberString,
      "side": 0|1,
      "productId": "<uuid>",
      "subaccountId": "<uuid>",
      "status": "<status>",
      "reduceOnly": boolean,
      "close": booleanue,
      "updatedAt": "<epoch>",
      "createdAt": "<epoch>",
      "sender": "<address>",
      "price": numberString,
      "filled": numberString,
      "stopPrice": numberString,
      "stopType": "<stopType>",
      "stopPriceType": "<stopPriceType>",
      "timeInForce": "<tif>",
      "expiresAt": "<epochInSeconds>",
      "postOnly": boolean,
      "groupContingencyType": "<groupContingencyType>",
      "groupId": "<uuid>"
    }
  ],
  "t": "<epoch>"
}

```

{% endcode %}

* `OrderUpdate` events are emitted in real-time
* `t` represents server time when response was published (epoch in miliseconds)

{% hint style="warning" %}
Only the latest update processed is emitted and intermediary states are omitted.
{% endhint %}

**`SUBACCOUNT_LIQUIDATION`** - Provides an update when a subaccount is liquidated.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "SubaccountLiquidation",
  "subaccountId": "<uuid>"
}

// Response message
{
  "subaccountId": "<uuid>",
  "liquidatedAt": "<epoch>",
  "t": "<epoch>"
}
```

{% endcode %}

* `SubaccountLiquidation` events are emitted in real-time
* `subaccountId` the subaccount that has been liquidated, `liquidatedAt` the time (in ms, since the Unix epoch) when the liquidation occurred
* `t` represents server time when response was published (epoch in miliseconds)

**`TOKEN_TRANSFER`** - Updates on token transfers (deposits/withdrawals) for a specific subaccount.

{% code expandable="true" %}

```json
// Subscription message payload
{
  "type": "TokenTransfer",
  "subaccountId": "<uuid>"
}

// Response message (same as `/v1/token/transfer` with pagination)
// @see https://api.ethereal.trade/docs#/Token/TokenController_listTransfers
{
  "id": "<uuid>",
  "initiatedBlockNumber": numberString,
  "finalizedBlockNumber": numberString,
  "status": "<status>",
  "subaccountId": "<uuid>",
  "tokenName": "string",
  "tokenAddress": "<address>",
  "type": "WITHDRAW"|"DEPOSIT",
  "amount": numberString,
  "lzDestinationAddress": "<address>",
  "lzDestinationEid": number,
  "fee": numberString,
  "createdAt": "<epoch>",
  "initiatedTransactionHash": "<hex>",
  "finalizedTransactionHash": "<hex>",
  "t": "<epoch>"
}
```

{% endcode %}

* &#x20;`t` represents server time when response was published (epoch in miliseconds)

{% hint style="success" %}
*Each subscription requires specific parameters as shown in the formats above. To subscribe to these streams, emit a 'subscribe' event to the socket with the appropriate subscription message.*
{% endhint %}

{% hint style="warning" %}
During connection establishment ensure `websocket` is the only configured transport (i.e. `transports: ['websocket']`).
{% endhint %}

### Unsubscribe

To stop receiving data from a previously established subscription, you can unsubscribe using the same payload format as your original subscription. Simply emit an `unsubscribe` event to the socket with the identical payload structure you used when subscribing.

### Handling `Socket.io` Exceptions

Exceptions are exposed in its own event aptly named "*exception*". Exceptions follow the following shape:

```typescript
{
  pattern: 'order:dryRun',
  status: 'BadRequest',
  error: {
    message: [
      'subaccount is not a valid subaccount',
    ]
  }
}
```

* `pattern` indicates the source event pattern if available e.g. "subscribe"&#x20;
* `status` the error status
* `error` general body of the error its shape changes depending on the status


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.ethereal.trade/developer-guides/trading-api/websockets/socket.io-deprecated.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
