The listen_key is a unique token required for user authentication and to establish a WebSocket connection. It binds a user to a WebSocket session, ensuring that only authenticated users can access the private streams.
Acquiring a Listen Key
Users must first authenticate with the server to receive a listen_key
This key is then used in the WebSocket connection headers to validate the user's session
Listen Key Expirations
Listen keys have a limited lifetime of 60 minutes
Users can prolong the key's lifetime
The server monitors the listen's key expirations and will automatically close the WebSocket connection when they expire
The listen_key parameter is crucial for accessing the WebSocket server. It carries the listen_key token that is unique to each user session.
Obtaining the listen_key:
The listen_key can be obtained via a GET request to the listen_key endpoint provided by the server after user authentication.
Once acquired, the listen_key must be included in the query parameter for the WebSocket handshake.
Signer parameter
The signer parameter identifies the main account associated with the WebSocket connection. This query parameter is used along with the listen_key to establish a secure and authenticated connection.
Usage:
Key: Signer
Value: Address of the signer of trading account.
WebSocket Server Streams Documentation
1. Fills Stream (fills_ prefix)
Description
This is a private stream that provides real-time information about order fills.
Requires authentication and authorization to access specific trading accounts.
Connection Request
To subscribe to the Fills Stream:
Action: "subscribe"
Stream: "fills_{trading_account_address}"
Replace {trading_account_address} with the specific trading account you want to subscribe to.
Example subscription response (same response structure as for HTTP requests
{ "result": "OK", "id": "5"}
Example Stream Events
Order flow:
submit -> if succ response -> put into processing queue ->:
failed to process -> NOT_PROCCESSED (matcher result = FAILED_VALIDATION)
processed -> ACK -> OPEN -> ...
Existente of error_code_orderbook in event message indicates that actions was unsuccessfull
Partially filled
{"result": {"client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","matcher_result":"OK",// matching engine result"fill_price":"2716.2819",// avg fill price"fill_base_qty":"0.0007704",// fill qty in base"fill_quote_qty":"2.092623",// fill qty in quote"acc_base_qty":"0.0013676",// accumulated so far"acc_quote_qty":"3.714786",// accumulated so far"hash":"0x05fabffcde5a985b39a304803a501fe9d835e5762666592c2442e767fbc91798",// hash of the associated order"is_sell_side":false,"status":"PARTIALLY_FILLED" },"stream":"fills","client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","pair": {"base":"AETH","quote":"AUSDC" }}
example#1{"result": {"client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","matcher_result":"FAILED_VALIDATION", <--- error description"fill_price":"0","fill_base_qty":"0","fill_quote_qty":"0","acc_base_qty":"0","acc_quote_qty":"0","hash":"0x02e8e9fc7a892f225aa80d4e23f988da60daf35efe06886396a5ba70e610ede2","is_sell_side":false,"status":"NOT_PROCESSED", <--- order status"error_code_orderbook":"FAILED_SIGN_CHECK" <--- new field },"stream":"fills","client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","pair": {"base":"AETH","quote":"AUSDC" }}
{"result": {"client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","report_type":"CANCEL_ORDER","req_hash":"0x0576635fb70c1d49bd11778c9c6d74fa7c0075667ca0f8b673e7199d5c105ce6",// hash of the request"entity_hash":"0x043b508c740f9912df5f5bab044087b79ce9e6f3ada48c2f2a3edd8496df50ca",// order hash intented to be cancelled"error_code_orderbook":"NO_ORDERS_WITH_THIS_ID" },"stream":"fills","client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580"}
{"result": {"client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","cancel_ticker_hash":"0x01d19066b73825550e387d6532736ceca2847193fe40ab2640a266d8751e6bb8",// hash of cancel all request },"stream":"fills","client":"0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580","pair": {"base":"AETH","quote":"AUSDC" }}
FAILED_ROLLUP:
{"result": {"client":"0x541cf2823e5d004e9a5278ef8b691b97382fd0c9a6b833a56131e12232a7f0f","fill_price":2000,// fill price"fill_base_qty":2,// fill qty in base asset that was failed"fill_quote_qty":4000,// fill qty in quote asset that was failed"hash":"0x05fabffcde5a985b39a304803a501fe9d835e5762666592c2442e767fbc91798","is_sell_side":false,"status":"FAILED_ROLLUP",// trade was failed due to some exceptional situation eg router taker },"stream":"fills","client":"0x541cf2823e5d004e9a5278ef8b691b97382fd0c9a6b833a56131e12232a7f0f""pair": {"base":"AETH","quote":"AUSDC" }}
REIMBURSE:
{"result": {"client":"0x541cf2823e5d004e9a5278ef8b691b97382fd0c9a6b833a56131e12232a7f0f","price":0"fill_base_qty": "0.35",// reimburse amount in main gas token "hash":"0x05fabffcde5a985b39a304803a501fe9d835e5762666592c2442e767fbc91798","is_sell_side":false,"status":"REIMBURSE",// router trade was failed, so we incentivize market makers },"stream":"fills","client":"0x541cf2823e5d004e9a5278ef8b691b97382fd0c9a6b833a56131e12232a7f0f""pair": {"base":"STRK",// always strk/strk"quote":"STRK" }}
Example subscription response (same response structure as for HTTP requests)
{ "result":"OK","id":"5"}
Example Stream Event:
{"result": {"bid": ["1958","124.23",2],// price and volume and num orders"ask": ["195","87.11",25],"time":1705221916000 # epoch in millis },"stream":"bbo","millis":0,"ecosystem":true,"pair": {"base":"AETH","quote":"AUSDC" }}
3. Trade Stream (trade)
Description
Real-time stream of trade data for a specified trading pair.
Connection Request
To subscribe to the Trade Stream:
Use the same format as the BBO stream but with Stream: "trade".
{"result": {"bids": ["1958","0",0], # 0 means the level was removed"asks": [ ["1958","4300",2], # non zero means new volume on price level ... ],"msg_id":"3",// user can use this msg id to apply incremental update to snapshot that they query from rest"time":1705221916000 },"stream":"snap","millis":0,"ecosystem":true,"pair": {"base":"AETH","quote":"AUSDC" }}
Unsubscribe from a Stream
To unsubscribe from any stream:
Action: "unsubscribe"
Stream: Specify the stream you want to unsubscribe from.