跳到主要内容

User Data Stream requests

User Data Stream subscription​

General information:

  • 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.
  • Subscriptions are identified by a subscriptionId which is returned when starting the subscription. That subscriptionId allows you to map the events you receive to a given subscription.
  • 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.
  • To verify the status of User Data Stream subscriptions, check the userDataStream field in session.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 the userDataStream flag 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:

NameTypeMandatoryDescription
filterOBJECTNoOptional 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:

KeyFieldValuesApplies toBypass behavior
eEvent typecamelCase event type namesAll events-
sSymbolInstrument symbol names (e.g. BTCUSDT)Events that carry a symbol fieldEvents without a symbol (balanceUpdate, outboundAccountPosition, externalLockUpdate) are delivered regardless.
aAssetAsset names (e.g. BTC, USDT)Events that carry an asset fieldEvents without an asset (executionReport, listStatus, outboundAccountPosition) are delivered regardless.
xExecution typeSCREAMING_SNAKE_CASE execution typesexecutionReport events onlyAll non-executionReport events are delivered regardless.

Event type values (e):

ValueDescription
executionReportOrder lifecycle events (new, trade, cancel, expire, amend)
balanceUpdateBalance credit/debit (deposits, withdrawals)
outboundAccountPositionAccount position snapshot after a change
listStatusOrder list (OCO/OTO) status updates
externalLockUpdateExternal lock balance changes

Execution type values (x):

ValueDescription
NEWNew order accepted
TRADEOrder filled (partial or full)
CANCELEDOrder canceled
REPLACEDOrder replaced (cancel-replace)
REJECTEDOrder rejected
EXPIREDOrder expired
TRADE_PREVENTIONSelf-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:

ConditionResult
filter omittedAll 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:

  • listenKeyExpired and eventStreamTerminated lifecycle events are always delivered regardless of filters.

  • Symbols and assets are resolved to internal IDs at subscribe time.

  • When using userDataStream.subscribe.signature, the filter must 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"]}&timestamp=...
  • 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:

NameTypeMandatoryDescription
subscriptionIdINTNoWhen 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:

NameTypeMandatoryDescription
apiKeySTRINGYes
timestampLONGYes
signatureSTRINGYes
recvWindowDECIMALNoThe value cannot be greater than 60000.
Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
filterOBJECTNoOptional 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
}
}