General
WebSocket endpoint provides real-time market data streaming which works in Subscribe-Publish communication model. After establishing a WebSocket connection with us, you will need to send a Hello message documented below.
General
Hello (OUT)
Example hello message for trades subscription to 2 selected
COINBASEsymbols one via the CoinAPI symbol id and other via the exchange symbol id:
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": ["trade"],
"subscribe_filter_symbol_id": [
"COINBASE_SPOT_BTC_USD",
"ETH-USD"
]
}Another example of a hello message for subscription to quotes related to the BTC or ETH assets:
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": ["quote"],
"subscribe_filter_asset_id": ["BTC", "ETH"]
}Another example of a hello message for subscription to quotes related to the BTC/USD asset pair:
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": ["quote"],
"subscribe_filter_asset_id": ["BTC/USD"]
}Another example of a hello message for subscription of multiple data types:
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": ["trade", "quote", "book20", "connectivity_status"]
}Example hello message for
connectivity_statussubscription:
{
"type": "hello",
"subscribe_data_type": ["connectivity_status"]
}Example hello message for Hyperliquid L4 order book and trade data:
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": ["book_l4", "trade_l4"],
"subscribe_filter_symbol_id": ["HYPERLIQUIDL4_PERP_BTC_USDC"]
}[!NOTE]
The
book_l4,trade_l4,hl_oracle_prices,hl_twap_statuses,hl_misc_events, andhl_system_eventsdata types are available only on the Hyperliquid L4 WS DS data source. Connect to the Hyperliquid L4 endpoint, for examplewss://hyperliquidl4.ws-ds.md.coinapi.io/, and use Hyperliquid L4 symbols.
Example hello message for extended Hyperliquid L4 feeds (oracle, TWAP, and node raw events):
{
"type": "hello",
"heartbeat": false,
"subscribe_data_type": [
"hl_oracle_prices",
"hl_twap_statuses",
"hl_misc_events",
"hl_system_events"
],
"subscribe_filter_symbol_id": [
"HYPERLIQUIDL4_PERP_BTC_USDC",
"HYPERLIQUIDL4_PERP_ETH_USDC"
]
}[!NOTE]
hl_oracle_pricesandhl_twap_statusesare symbol-scoped Hyperliquid L4 streams.hl_misc_eventsandhl_system_eventsare exchange-level Hyperliquid L4 streams and can include events not tied to a specific trading pair.
Subscribe (OUT)
The WebSocket API has been enhanced to support dynamic subscription management through subscribe and unsubscribe messages. These allow for more granular control over the data streams without the need to resend the entire subscription scope as previously required with the hello message.
To subscribe to additional data types or filters without overriding existing subscriptions, send a subscribe message:
Example
subscribemessage for book data related to "BTC" and "ETH":
{
"type": "subscribe",
"heartbeat": true,
"subscribe_data_type": ["book"],
"subscribe_filter_asset_id": ["BTC", "ETH"]
}This message adds subscriptions to the specified data types and filters, augmenting any existing subscriptions maintained in the session.
Unsubscribe (OUT)
Similarly, to remove specific data types or filters from your current subscription, send an unsubscribe message:
Example unsubscribe message to remove book data subscription for "BTC":
{
"type": "unsubscribe",
"heartbeat": true,
"subscribe_data_type": ["book"],
"subscribe_filter_asset_id": ["BTC"]
}The unsubscribe message removes the specified subscriptions without affecting other existing subscriptions.
Subscribe vs Hello
In the realm of subscription management, three key actions allow you to fine-tune your information feed according to evolving requirements:
- Subscribe: This action expands your current subscription scope by adding new elements without discarding any existing ones. It's particularly useful for tailoring your feed as your interests or information needs grow.
- Unsubscribe: Through this option, you can selectively remove specific elements from your current subscription. It's an efficient way to declutter your feed by eliminating content that no longer serves your needs, without affecting the rest of your subscriptions.
- Hello: Use this command to initiate a fresh start. It clears your existing subscription slate and sets up a new scope from scratch. Opt for this when a complete overhaul of your subscriptions is needed, rather than just an adjustment.
After your WebSocket connection is established, you must send us a hello or subscribe message which contains:
- Stream preferences (Heartbeat and subscription details)
- API key for authorization
If your message will be incorrect, we will send you error message and disconnect connection afterwards.
Hello message can be repeated, each one will cause subscription scope override without interruption of your WebSocket connection.
Message parameters
| Parameter | Type | Description |
|---|---|---|
| type | string | Message type, must be equal to one of the values: hello, subscribe or unsubscribe |
| heartbeat | bool | true to receive Heartbeat message every second, otherwise false |
| subscribe_data_type | string[] | List of data types you want to receive (required, possible values listed in table below) |
| subscribe_filter_symbol_id | string[] | List of exact symbol identifier to which should be included in the stream. Symbols can be in our eg. BITSTAMP_SPOT_BTC_USD or the exchange format eg. BTC-USD. |
| subscribe_filter_asset_id | string[] | Filter data to messages which are related to the at least one of the listed asset identifiers or to specific asset pair (e.g. BTC/USD) (optional, if not provided then stream will not be filtered by assets) |
| subscribe_update_limit_ms_quote | int | Minimum delay in milliseconds between quote updates for the same symbol (optional) |
| subscribe_update_limit_ms_book_snapshot | int | Minumum delay in milliseconds between book snapshot (book5, book20, book50) updates for the same symbol (optional) |
Data types
Listed below are all allowed values for subscribe_data_type variables from hello message.
| Data type | Description |
|---|---|
trade | Executed transactions feed (order book matches) |
trade_l4 | Hyperliquid L4 executed transactions feed with taker and maker user addresses (HYPERLIQUIDL4 only). |
hl_oracle_prices | Hyperliquid L4 oracle and mark price enrichment feed per coin, including daily values and price inputs (HYPERLIQUIDL4 only). |
hl_twap_statuses | Hyperliquid L4 TWAP execution status feed with progress and execution metrics (HYPERLIQUIDL4 only). |
hl_misc_events | Hyperliquid L4 raw node misc events feed with block number, event type, and JSON payload (HYPERLIQUIDL4 only). |
hl_system_events | Hyperliquid L4 raw node system actions feed with block number, action type, and JSON payload (HYPERLIQUIDL4 only). |
quote | Quote updates feed (order book level 1) |
book | Order book snapshots and updates feed (order book level 2, full order book snapshot and real-time updates). To use this data type you need to define a filter in the hello or subscribe message. |
book5 | Order book snapshots feed (order book level 2, 5 best levels from each side of book). To use this data type you need to define a filter in the hello or subscribe message. |
book20 | Order book snapshots feed (order book level 2, 20 best levels from each side of book). To use this data type you need to define a filter in the hello or subscribe message. |
book50 | Order book snapshots feed (order book level 2, 50 best levels from each side of book). To use this data type you need to define a filter in the hello or subscribe message. |
book_l4 | Hyperliquid L4 order-by-order snapshots and updates with order id and user address for each order (HYPERLIQUIDL4 only). To use this data type you need to connect to the HYPERLIQUIDL4 data source and define a symbol filter in the hello or subscribe message. |
connectivity_status | Periodic connectivity status feed for the connected market data source. Each message contains the source exchange_id and a timestamp. |
high_frequency_market_changes | Real-time high-frequency market changes detection feed including new symbols, delisted symbols, and exchange announcements (Enterprise plan only). This feature continuously monitors exchange APIs and detects market structure changes as they happen. See message details in the Messages section. |
Error handling
Example JSON error message is structured like this:
{
"type": "error",
"message": "Invalid API key"
}You need to be prepared to receive an error message from us when you send something wrong; all errors are permanent and you should expect that the underlying WebSocket connection will be closed by us after sending an error message.
[!NOTE]
Good practice is to store all error messages somewhere for further manual review.
Data buffering
Data buffering JSON error message is structured like this:
{
"type": "error",
"message": "Reached maximum allowed buffered messages for this connection."
}The stream will send the data to the client as fast as possible; this can result in a high volume of data in cases where the subscription scope is broad. If our server cannot write data to the stream because of the TCP backpressure most likely caused by your client is not reading the data fast enough, or there is not enough network bandwidth available, we will buffer the messages to allow your client to catch up. However, when the buffer is full, a disconnect will be initiated from the server-side, and the buffered messages are dropped, and they will not be resent to the client.
One way to identify when your client is falling behind is to compare the CoinAPI time of the messages being received with your current time on the client and track this metric over time. Make sure your clock is synchronized correctly and do not have a drift.
The possible causes of the buffering are limited and are related to:
- Bandwidth bottleneck, eg.
- Internet connection instability
- Not enough bandwidth to receive a full stream.
- Network card or link saturation.
- I am not receiving messages fast enough, eg.
- Lack of the thread separation between the (a) receiving thread or (b) parsing or (c) processing operations.
- No CPU affinity on the receiving thread.
- CPU bottleneck on the receiving thread.
- Infrequent collection of the data from the TCP stack.
- Heap allocation per message and Garbage Collector pressure.
If your client is unable to receive messages fast enough because of the issues listed above, then these things will happen:
- Your client TCP stack will be full, and TCP window will be closed to inform us that you can't receive more data and we should not send to you
- Our TCP stack queue will be full because we couldn't send you more data
- We will internally create a limited queue of the messages to deliver when the channel is available again (this could cause the delay on the real-time data before the gaps will appear)
- If the queue is full, then we will disconnect you.
To minimize the occurrence of disconnects:
- Make sure that your client is reading the stream fast enough. Typically you should not do any real processing work as you read the stream. Read the stream and hand the activity to another thread/process/data store to do your processing asynchronously.
- Make sure that your data center has inbound bandwidth sufficient to accomodate large sustained data volumes as well as significantly larger spikes (e.g. 10x normal volume).
The current default queue size per connection is 131 072 messages.
For more information please google: TCP Flow Control.
Introduction
WebSocket endpoint provides real-time market data streaming which works in Subscribe-Publish communication model. After establishing a WebSocket connection with us, you will need to send a Hello message documented below.
Endpoints
WebSocket endpoint provides real-time market data streaming which works in Subscribe-Publish communication model. After establishing a WebSocket connection with us, you will need to send a Hello message documented below.