Skip to main content

User Data Stream

Receive real-time account updates via WebSocket: balance changes, order execution reports, and order list status updates.

Binance API Reference: User Data Streams

Setup

User data streams require a listen key obtained from the REST API:

val resources = for
rest <- BinanceClient.resource[IO](config)
ws <- BinanceWsClient.resource[IO](config)
yield (rest, ws)

resources.use { (rest, ws) =>
for
key <- rest.createListenKey
_ <- ws.subscribe(UserDataStream(key.listenKey))
.evalMap(event => IO.println(s"Event: $event"))
.compile.drain
yield ()
}

Event Types

The user data stream sends the following event types as JSON:

Account Update (outboundAccountPosition)

Pushed when account balances change (trade, deposit, withdrawal).

Balance Update (balanceUpdate)

Pushed when balance changes not related to trades (deposits, withdrawals).

Order Update (executionReport)

Pushed on every order state change: new, filled, partially filled, canceled, expired.

Order List Status (listStatus)

Pushed when an OCO order list status changes.

note

User data events are returned as raw Json from UserDataStream. Parse the e field to determine the event type and decode accordingly.

Keep-Alive

Listen keys expire after 60 minutes. Run a keep-alive in parallel:

import scala.concurrent.duration.*

val keepAlive = fs2.Stream
.fixedRate[IO](30.minutes)
.evalMap(_ => rest.keepAliveListenKey(key.listenKey))
.compile.drain

val listen = ws.subscribe(UserDataStream(key.listenKey))
.evalMap(event => IO.println(s"$event"))
.compile.drain

// Run both concurrently
(IO.race(keepAlive, listen)).void