General

This article explains the channels the API provides, the format of the messages sent, the channel subscription procedure, and a channel connection example.

Available Channels

The WebSocket API uses the following communication channels to facilitate real-time data transfer from and to the server:

  • Trades Channel: Sends a message whenever the service executes a new trade in the corresponding order book.

  • Orders Channel: Maintains an up-to-date list of the top 20 asks and the top 20 bids. New messages are sent across the channel whenever there is a change in either top 20 items.

  • Diff-Orders Channel: Sends across any modifications to the order book, specifically any state changes in existing orders (including orders not in the top 20 items) and any new orders. The service could do the following with an order:

    • Cancel it, in which case it does not have the fields a (amount) and v (value).
    • Partially fill it, which reflects in the amount field. You can look up an order's state via the Look Up Orders endpoint.

    Each message in the Diff-Orders channel contains a sequence number, which is an increasing integer value. Each new message increments the sequence number by one. If you see a sequence number greater than the previous one by more than one unit, it means a message has been dropped, and you need to update the order book to get to the correct state.

    In theory, you can get a copy of the whole order book via REST once and keep it up to date using the Diff-Orders channel with the algorithm explained in the section, How to Keep an Order Book.

Fields Included in Messages

All of the messages from every channel of the WebSocket API are JSON objects that contain four mandatory fields:

  • type: Represents the channel sending the message.
  • book: Indicates the corresponding order book.
  • payload: Stores data relevant to the subscribed channel.
  • sent: Indicates when the service broadcasted the event to the publish-subscribe messaging in milliseconds (timestamp).

However, the Diff-Orders channel adds one field to this list of four mandatory elements, so the messages from this channel contain five required fields:

  • sequence: Stores an increasing integer value.

Sample Messages

The following JSON objects depict the mandatory fields contained in every message of the WebSocket API channels:

{
   "type": "...",
   "book": "...",
   "payload": ["..."],
   "sent": 123465789
}
{
   "type": "...",
   "book": "...",
   "payload": ["..."],
   "sent": 123465789,
   "sequence": 1
}

How to Keep an Order Book

To get a copy of the whole order book once via REST and keep it up to date:

  1. Subscribe to the Diff-Orders channel.
  2. Queue any message that comes into this channel.
  3. Retrieve the whole order book by calling the REST /order_book/ endpoint.
  4. Play back the queued messages, discarding the ones with a sequence number below or equal to the one from the REST order book.
  5. Apply the subsequent queued messages to your local order book data structure.
  6. Apply real-time messages to your local order book as they come in through the stream.

📘

Timestamp Field

An order's timestamp field is immutable. Even if the service mutates the amount field or removes the order, the timestamp field remains as it was when the service created the order.

A timestamp is not unique, and different orders can have the same timestamp.

How to Subscribe to a Channel

To connect to the channels of the WebSocket API, perform the following steps:

  1. Create a WebSocket instance:
websocket = new WebSocket('wss://ws.bitso.com');
  1. Subscribe to each of the channels you want to connect to:
websocket.onopen = function() {
    websocket.send(JSON.stringify({ action: 'subscribe', book: 'btc_mxn', type: 'trades' }));
    websocket.send(JSON.stringify({ action: 'subscribe', book: 'btc_mxn', type: 'diff-orders' }));
    websocket.send(JSON.stringify({ action: 'subscribe', book: 'btc_mxn', type: 'orders' }));
};

The server acknowledges each subscription to a channel with a message. For example, a successful subscription to the trades channel returns the following acknowledgment message:

{"action": "subscribe", "response": "ok", "time": 1455831538045, "type": "trades"}
  1. When you've successfully subscribed to a channel, listen for messages and handle them appropriately:
websocket.onmessage = function(message){
                var data = JSON.parse(message.data);

                if (data.type == 'trades' && data.payload) {

                }
                else if (data.type == 'diff-orders' && data.payload) {

                }
                else if (data.type == 'orders' && data.payload) {

                }
            };

Keep alive messages look like this:

{"type": "ka"}

Implementation Example

The following native JavaScript implementation can serve as a channel connection example: