Messages
Trades IN
Trade message JSON is structured like this:
{
"type": "trade",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "770C7A3B-7258-4441-8182-83740F3E2457",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "BUY"
}
Trade message is sent for every executed transaction (orderbook match).
Message variables
Variable | Description |
---|---|
type | Message type, always trade |
symbol_id | Our symbol identifier, format documented here |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Time of trade reported by exchange |
time_coinapi | Time when coinapi first received trade from exchange |
uuid | Our unique trade identifier in form of UUIDv4 |
price | Price of the transaction |
size | Base asset amount traded in transaction (if a value is equal to zero, then transaction price just marking a data point eg. in the index time series) |
taker_side | Aggressor side of the transaction (BUY/SELL/BUY_ESTIMATED/SELL_ESTIMATED/UNKNOWN) |
Possible taker_side
values
If exchange has not reported who the aggressor side of the transaction was, then we will classNameify who it most probably was based on current market view.
taker_side | Description |
---|---|
BUY | Exchange has reported that transaction aggressor was buying |
SELL | Exchange has reported that transaction aggressor was selling |
BUY_ESTIMATED | Exchange has not reported transaction aggressor, we estimated that more likely it was buying |
SELL_ESTIMATED | Exchange has not reported transaction aggressor, we estimated that more likely it was selling |
UNKNOWN | Exchange has not reported transaction aggressor and we have not estimated who it was |
To classNameify who the aggressor of the transaction was, we use a proprietary algorithm that extends the method described in the paper "Inferring trade direction from intraday data (1991) by Lee and Ready"
Quotes IN
Quote message JSON is structured like this:
{
"type": "quote",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
}
Quote message is sent for each update on orderbook first best bid or ask level.
Message variables
Variable | Description |
---|---|
type | Message type, always quote |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
ask_price | Best asking price |
ask_size | Volume resting on best ask (if a value is equal to zero then size is unknown) |
bid_price | Best bidding price |
bid_size | Volume resting on best bid (if a value is equal to zero then size is unknown) |
Orderbook L2 (Full) IN
A Book message is sent for each snapshot or update of the order book. After subscription to this data type is initialized, we immediately start delivering updates to the order book and at least one snapshot will be provided as soon as possible with the nearest update of the book. Book message represents total ammount of bids and asks aggregated by price level.
{
"type": "book",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"is_snapshot": true,
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
is_snapshot | Is message a snapshot? If true then all bid and ask levels are listed, otherwise only changed since the last message. |
asks | All ask levels for snapshot message, otherwise only changed ask levels since the last message. Data will be in order from the best to the worst price. |
bids | All bid levels for snapshot message, otherwise only changed bid levels since the last message. Data will be in order from the best to the worst price. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x5) IN
A Book5 message contain first 5 best bid or ask levels.
Updates in this data type are sent as soon as possible if orderbook changed (outside or inside levels covered by the snapshot visibility). To reduce amount of updates please use the subscribe_update_limit_ms_book_snapshot
parameter.
{
"type": "book5",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book5 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 5 ask levels in order from best to worst. |
bids | Best 5 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x20) IN
A Book20 message contain first 20 best bid or ask levels.
Updates in this data type are sent every 1 second if orderbook changed (outside or inside levels covered by the snapshot visibility). To reduce amount of updates please use the subscribe_update_limit_ms_book_snapshot
parameter.
{
"type": "book20",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book20 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 20 ask levels in order from best to worst. |
bids | Best 20 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x50) IN
A Book50 message contain first 50 best bid or ask levels.
Updates in this data type are sent every 1 second if orderbook changed (outside or inside levels covered by the snapshot visibility). To reduce amount of updates please use the subscribe_update_limit_ms_book_snapshot
parameter.
{
"type": "book50",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book50 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 50 ask levels in order from best to worst. |
bids | Best 50 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L3 (Full) IN
A book_l3
message is sent for each snapshot or update of the order book in the level 3 format (order-by-order).
After subscription to this data type is initialized, we immediately start delivering updates to the order book and at least one snapshot will be provided as soon as possible with the nearest update of the book.
Book L3 does not aggregate any data. Every ask and bid corresponds to passive order with information on the price and size of that order. The id can identify any order.
If the data source is providing the maximum resoluiont of the order book on level 2 then this data type will fallback to the Level 2, in that case the Order ID's will be null or not provided. You should treat Order without Id as Level 2 aggregated entry in the price queue.
{
"type": "book_l3"
"symbol_id": "COINBASE_SPOT_BCH_USD",
"sequence": 2323346,
"time_exchange": "2020-08-26T12:36:04.3464706Z",
"time_coinapi": "2020-08-26T12:36:04.2807750Z",
"is_snapshot": false,
"asks": [
{
"id": "520269d4-c085-47ed-8825-6d787af90800",
"price": 273.01,
"size": 1.81940502,
"update_type":"ADD"
},
{
"id": "0ac891c7-8360-462c-8d9a-d8b217d3fca2",
"price": 273.02,
"size": 1.0,
"update_type":"DELETE"
},
... cut ...
],
"bids": [
{
"id": "6340ec1e-8be8-404e-b9a4-a14120ec179e",
"price": 272.94,
"size": 1.81940502,
"update_type":"UPDATE"
},
{
"id": "7eaaa899-089f-4308-9fa2-e33737ae36ee",
"price": 272.96,
"size": 1.85989855,
"update_type":"DELETE"
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book_l3 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
is_snapshot | Is message a snapshot? If true then all bid and ask levels are listed, otherwise only changed since the last message |
asks | All ask levels for snapshot message, otherwise only changed ask levels since the last message. Data will be in order from the best to the worst price. |
bids | All bid levels for snapshot message, otherwise only changed bid levels since the last message. Data will be in order from the best to the worst price. |
id | Order identifier |
price | Price of bid/ask |
size | Bid/ask base asset amount |
update_type | Type of update message |
Possible update_type
values
The snapshot message represents the initial collection of the orders in the order book. Further updates are modifying this collection.
update_type
determines the type of update for the order.
Please note that the snapshot message has no defined update_type
.
update_type | Description |
---|---|
ADD | Add order to the price queue. |
UPDATE | Update the order size in the price queue. |
SUBTRACT | Subtract the order size in the price queue. |
DELETE | Delete the order from the price queue. |
MATCH | Subtract the order size in the price queue (same as SUBTRACT but caused by the match). |
Reconnect IN
Reconnect message is sent by the server to all connected clients when the server will be restarted or shut down at the defined exact time included in the message content. After the period specified in message passes, the client must expect that the underlying WebSocket connection will be closed from the server-side. A new connection will automatically be established to a different server.
The correct way of handling this event depends on the specific requirements of the integration, but we can define standard ways how to handle it:
- Wait for the connection to be closed and reconnect
- Reconnect immediately after receiving the message
- Upon receiving the message, establish a second connection, and subscribe to the same scope of data. When the first connection is disconnected, do not reconnect it and instead transparently switch the data streams between connections. This method requires more implementation as a transparent switch of the data stream must not break the sequence for streams published using the initial snapshot and update messages. To make sure the sequence is correct, the client must: (a) maintain a state by applying updates to snapshot or (b) buffer the data from the second connection and processing it at the transparent connection switch.
Example JSON reconnect message is structured like this:
{
"type": "reconnect"
"within_seconds": 10,
"before_time": "2020-08-06T19:19:09.7035429Z",
}
Message variables
Variable | Description |
---|---|
type | Message type, always reconnect |
within_seconds | Seconds within which reconnection should be performed. |
before_time | Time before which reconnection should be performed. |
Heartbeat IN
Heartbeat message JSON is structured like this:
{
"type": "hearbeat"
}
Heartbeat message is sent to you every time there is one second of silence in communication between us, if you agreed on this feature in Hello message.
WebSocket working on TCP protocol which doesn’t have the feature indicating that the connection is broken without trying exchange data over it. As you will not be actively sending messages to us, with Heartbeat you can distinguish a situation where there are no market data updates for you (Heartbeat is delivered but no market data updates) or connection between us is broken (Heartbeat and market data updates are not delivered).