The websocket API provides streaming access to data such as market data or user data (e.g. order fills). It is more efficient and provides lower latency information than repeatedly polling the order book and recent trades, but is more complicated to implement.
The streaming protocol works by requiring the client to keep an in-memory record of the streamed data, such as the order book. Update messages are then sent from the server and the client uses these to update its copy of the order book. When applied correctly, the client's view of the order book will be identical to the server's view.
Market stream
Protocol
The client state consists of the following data:
- sequence number
- set of bid orders (id, price, volume)
- set of ask orders (id, price, volume)
- list of trades
- market status
Each update message transmitted from the server has a unique increasing sequence number. The message with sequence number n can be applied to state sequence n-1 to produce state sequence n.
A message may contain multiple updates which must be applied atomically and in order.
If an update is received out-of-sequence (for example update sequence n+2 or n-1 received after update sequence n), the client cannot continue and must reinitialise the state.
There are four types of update:
- Create
- Delete
- Trade
- Status
Create
Add a bid or ask Order to the Order Book with a given id, price and volume. For example:
{
"order_id": "BXMC2CJ7HNB88U4",
"type": "BID",
"price": "1234.00",
"volume": "1.23"
}
Delete
Remove the order from the order book with a given id. For example:
{
"order_id": "BXMC2CJ7HNB88U4"
}
Trade
Reduce the outstanding volume of an Order in the Order Book (maker_order_id) and append a Trade to the Trades List. For example:
{
"sequence": 24509303,
"base": "0.1",
"counter": "5232.00",
"maker_order_id": "BXMC2CJ7HNB88U4",
"taker_order_id": "BXMC2CJ7HNB88U5"
}
Status
Set the status of the market to the given value. This field will not include the POSTONLY state a market is in during the 24-hour launch window. During this launch window, this status will report as ACTIVE, but the API will not accept orders without the post_only parameter set to true.
{
"status": "POSTONLY",
}
Examples
A new order is placed below market
In this case, an update message is sent with a single create update.
A market order is placed that is immediately filled
In this case, an update message is sent containing multiple trade updates. There will be no create update since the new order never enters the order book.
An order is placed that is partially filled
In this case, the update message contains multiple trade updates and a single create update. The volume in the create update is the remaining volume for the order.
An order is stopped
In this case, the update message contains a single delete update.
The market switches to post-only and trading is suspended
In this case, the update message contains a single status update.
Websockets
The streaming updates protocol described above can be accessed using websockets. The server sends the current order book state, and then sends update messages as quickly as possible. Both the client and server must send regular keep alive messages to avoid disconnection during periods of low update message activity.
Connect to the websocket server at: wss://ws.luno.com/api/1/stream/:pair
The client must start by sending API key credentials:
{
"api_key_id": "abcdef",
"api_key_secret": "api_key_secret_goes_here"
}
The server will then send the current order book in the following format:
{
"sequence": "24352",
"asks": [
{
"id": "BXMC2CJ7HNB88U4",
"price": "1234.00",
"volume": "0.93"
}
],
"bids": [
{
"id": "BXMC2CJ7HNB88U5",
"price": "1201.00",
"volume": "1.22"
}
],
"status": "ACTIVE",
"timestamp": 1528884331021
}
The server then sends messages like the following:
{
"sequence": "24353",
"trade_updates": null, // array of 0 or more trade updates
"create_update": null, // null or 1 create update
"delete_update": null, // null or 1 delete update
"status_update": null, // null or 1 status update
"timestamp": 1469031991
}
An empty message is a keep alive message.
Ping/Pong messages are supported.
If there is any error while processing an update (e.g. an out-of-order update) or there is a network error or timeout (e.g. keep alive message not received in time), the client should close the connection and reconnect in order to reinitialise its state. It is important that clients implement some kind of backoff to avoid being rate limited in case of errors.
User stream
Protocol
There are three types of update:
- Order Status
- Order Fill
- Balance Update
Order Status
Update the status of an order. For example:
{
"order_id": "BXGMHMJXVEZK6NS",
"client_order_id": "sample-XYZ",
"market_id": "XBTZAR",
"status": "AWAITING"
}
The possible values for status are AWAITING, PENDING and COMPLETE.
Order Fill
Update the fill data of an order. For example:
{
"order_id": "BXGMHMJXVEZK6NS",
"client_order_id": "sample-XYZ",
"market_id": "XBTZAR",
"base_fill": "1.00000000",
"counter_fill": "100.00000000",
"base_delta": "0.40000000",
"counter_delta": "40.00000000",
"base_fee": "0.00100000",
"counter_fee": "0.10000000",
"base_fee_delta": "0.00040000",
"counter_fee_delta": "0.04000000"
}
Balance Update
Latest account balance status:
{
"account_id": 8203463422864003664",
"row_index": 1,
"balance": "100.00000000",
"balance_delta": "100.00000000",
"available": "99.00000000",
"available_delta": "1.00000000"
}
Websockets
The streaming updates protocol described above can be accessed using websockets. The server sends update messages as quickly as possible.
Connect to the websocket server at: wss://ws.luno.com/api/1/userstream
The client must start by sending API key credentials:
{
"api_key_id": "abcdef",
"api_key_secret": "api_key_secret_goes_here"
}
The server then sends messages like the following:
{
"type": "order_status",
"timestamp": 1469031991,
"order_status_update": null, // null or 1 order status update
"order_fill_update": null, // null or 1 order fill update
"balance_update": nill, // null or balance update
}
The possible values for type are order_status, order_fill, balance_update.
Ping/Pong messages are supported.
It is important that clients implement some kind of backoff to avoid being rate limited in case of errors.
The server keeps a cache of all messages sent in the last 5 minutes. When reconnecting, messages generated while
the client was disconnected will be resent to ensure messages are not missed. Note that staying disconnected for
longer than 5 minutes will discard the message cache.