User Data Stream requests
User Data Stream subscription
- User Data Stream subscriptions allow you to receive all the events related to a given account on a WebSocket connection.
- There are 2 ways to start a subscription:
- If you have an authenticated session, then you can subscribe to events for that authenticated
account using
userDataStream.subscribe. - In any session, authenticated or not, you can subscribe to events for one or more accounts for
which you can provide an API Key signature, using
userDataStream.subscribe.signature. - You can have only one active subscription for a given account on a given connection.
- If you have an authenticated session, then you can subscribe to events for that authenticated
account using
- Subscriptions are identified by a
subscriptionIdwhich is returned when starting the subscription. ThatsubscriptionIdallows you to map the events you receive to a given subscription.- All active subscriptions for a session can be found using
session.subscriptions.
- All active subscriptions for a session can be found using
- Limits
- A single session supports up to 1,000 active subscriptions simultaneously.
- Attempting to start a new subscription beyond this limit will result in an error.
- If your accounts are very active, we suggest not opening too many subscriptions at once, in order to not overload your connection.
- A single session can handle a maximum of 65,535 total subscriptions over its lifetime.
- If this limit is reached, you will receive an error and must re-establish a new connection to be able to start new subscriptions.
- A single session supports up to 1,000 active subscriptions simultaneously.
- To verify the status of User Data Stream subscriptions, check the
userDataStreamfield insession.status:null- User Data Stream subscriptions are not available on this WebSocket API.true- There is at least one subscription active in this session.false- There are no active subscriptions in this session.
Subscribe to User Data Stream (USER_STREAM)
{
"id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7",
"method": "userDataStream.subscribe"
}
Subscribe to the User Data Stream in the current WebSocket connection.
Notes:
- This method requires an authenticated WebSocket connection using Ed25519 keys. Please refer to
session.logon. - To check the subscription status, use
session.status, see theuserDataStreamflag indicating you have have an active subscription. - User Data Stream events are available in both JSON and SBE
sessions.
- Please refer to User Data Streams for the event format details.
- For SBE, only SBE schema 2:1 or later is supported.
Weight: 2
Parameters:
| Name | Type | Mandatory | Description |
|---|---|---|---|
filter | OBJECT | No | Optional filter that controls which events are delivered on this subscription. See User Data Stream Subscription Filters below. When omitted, all events for the subscribed account are delivered. |
Response:
{
"id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7",
"status": 200,
"result": {
"subscriptionId": 0
}
}
User Data Stream Subscription Filters
The optional filter parameter accepted by
userDataStream.subscribe and
userDataStream.subscribe.signature controls which events are delivered on
the subscription. Without a filter, all events for the subscribed account are delivered. The filter
object must contain at least one key when present; empty objects and empty arrays are rejected.
Filters use the short field names that appear in event payloads. Within a filter key, values are OR'd (match any). Across filter keys, matches are AND'd (an event must pass every specified filter). Filters that don't apply to an event type are ignored - the event passes through.
Available filter keys:
| Key | Field | Values | Applies to | Bypass behavior |
|---|---|---|---|---|
e | Event type | camelCase event type names | All events | - |
s | Symbol | Instrument symbol names (e.g. BTCUSDT) | Events that carry a symbol field | Events without a symbol (balanceUpdate, outboundAccountPosition, externalLockUpdate) are delivered regardless. |
a | Asset | Asset names (e.g. BTC, USDT) | Events that carry an asset field | Events without an asset (executionReport, listStatus, outboundAccountPosition) are delivered regardless. |
x | Execution type | SCREAMING_SNAKE_CASE execution types | executionReport events only | All non-executionReport events are delivered regardless. |
Event type values (e):
| Value | Description |
|---|---|
executionReport | Order lifecycle events (new, trade, cancel, expire, amend) |
balanceUpdate | Balance credit/debit (deposits, withdrawals) |
outboundAccountPosition | Account position snapshot after a change |
listStatus | Order list (OCO/OTO) status updates |
externalLockUpdate | External lock balance changes |
Execution type values (x):
| Value | Description |
|---|---|
NEW | New order accepted |
TRADE | Order filled (partial or full) |
CANCELED | Order canceled |
REPLACED | Order replaced (cancel-replace) |
REJECTED | Order rejected |
EXPIRED | Order expired |
TRADE_PREVENTION | Self-trade prevention triggered |
Examples:
Only execution reports and balance updates:
{ "filter": { "e": ["executionReport", "balanceUpdate"] } }
Only events for BTCUSDT and ETHUSDT:
{ "filter": { "s": ["BTCUSDT", "ETHUSDT"] } }
Only balance updates for BTC:
{ "filter": { "e": ["balanceUpdate"], "a": ["BTC"] } }
Only fills on execution reports:
{ "filter": { "e": ["executionReport"], "x": ["TRADE"] } }
Validation rules:
| Condition | Result |
|---|---|
filter omitted | All events delivered (no filter) |
filter: {} | Error: empty filter object |
filter: {"e": []} | Error: empty value array |
filter: {"e": ["executionReport", "executionReport"]} | Error: duplicate value |
filter: {"e": ["badType"]} | Error: unrecognized event type |
filter: {"s": ["NOSYMBOL"]} | Error: unknown symbol (-1121) |
filter: {"a": ["NOASSET"]} | Error: unknown asset (-1108) |
filter: {"z": [...]} | Error: unknown filter key |
Notes:
-
listenKeyExpiredandeventStreamTerminatedlifecycle events are always delivered regardless of filters. -
Symbols and assets are resolved to internal IDs at subscribe time.
-
When using
userDataStream.subscribe.signature, thefiltermust be included in the string that is signed. For the signature to match:- Filter keys must be sorted alphabetically:
a,e,s,x. - There must be no whitespace between JSON elements of the filter.
Example parameter string being signed:
apiKey=...&filter={"e":["executionReport"],"s":["BAZUSD"],"x":["TRADE"]}×tamp=... - Filter keys must be sorted alphabetically:
-
When extending a signature subscription by re-subscribing with a new request, the active filter is replaced with the one in the new request.
Unsubscribe from User Data Stream
{
"id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7",
"method": "userDataStream.unsubscribe"
}
Stop listening to the User Data Stream in the current WebSocket connection.
Note that session.logout will only close the subscription created with userDataStream.subscribe
but not subscriptions opened with userDataStream.subscribe.signature.
Weight: 2
Parameters:
| Name | Type | Mandatory | Description |
|---|---|---|---|
subscriptionId | INT | No | When called with no parameter, this will close all subscriptions. When called with the subscriptionId parameter, this will attempt to close the subscription with that subscription id, if it exists. |
Response:
{
"id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7",
"status": 200,
"result": {}
}
Listing all subscriptions
{
"id": "d3df5a22-88ea-4fe0-9f4e-0fcea5d418b7",
"method": "session.subscriptions",
"params": {}
}
Note:
- Users are expected to track on their side which subscription corresponds to which account.
Weight: 2
Data Source: Memory
Response:
{
"id": "d3df5a22-88ea-4fe0-9f4e-0fcea5d418b7",
"status": 200,
"result": [
{
"subscriptionId": 0
},
{
"subscriptionId": 1
}
]
}
Subscribe to User Data Stream through signature subscription (USER_STREAM)
{
"id": "d3df8a22-98ea-4fe0-9f4e-0fcea5d418b7",
"method": "userDataStream.subscribe.signature",
"params": {
"apiKey": "mjcKCrJzTU6TChLsnPmgnQJJMR616J4yWvdZWDUeXkk6vL6dLyS7rcVOQlADlVjA",
"timestamp": 1747385641636,
"signature": "yN1vWpXb+qoZ3/dGiFs9vmpNdV7e3FxkA+BstzbezDKwObcijvk/CVkWxIwMCtCJbP270R0OempYwEpS6rDZCQ=="
}
}
Weight: 2
Parameters:
| Name | Type | Mandatory | Description |
|---|---|---|---|
apiKey | STRING | Yes | |
timestamp | LONG | Yes | |
signature | STRING | Yes | |
recvWindow | DECIMAL | No | The value cannot be greater than 60000. Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified. |
filter | OBJECT | No | Optional event filter. See User Data Stream Subscription Filters. When included, filter must be in the signed string with sorted keys and no whitespace between JSON elements. |
Data Source: Memory
Response:
{
"id": "d3df8a22-98ea-4fe0-9f4e-0fcea5d418b7",
"status": 200,
"result": {
"subscriptionId": 0
}
}