Skip to Content

WebSocket stream

One connection for market data, the account, the layout of the windows and settings.

Address: ws://127.0.0.1:48180/v1/stream · AsyncAPI file

Connection

  • Address: ws://127.0.0.1:48180/v1/stream.
  • The token goes in the Authorization: Bearer <token> header of the handshake. The handshake requires the market:read scope. It is rejected by the same rules as an HTTP request, with 401 or 403.
  • The server sends a WebSocket ping every 20 s. If no pong comes for 50 s, the server closes the connection.
  • When the client closes the connection, the server answers with a close frame that carries the code of the client.
  • Closing the socket removes every subscription of the connection. An explicit unsubscribe removes a subscription at once.
  • A pair with no subscribers is released on the exchange after 30 s.

Close codes

CodeMeaning
1001the API was switched off or the token was reissued
4008the client is too slow and did not keep up for longer than 5 s
4029the limit of stream connections per token

Limits

GET /v1/meta returns the limits. A refusal is an error frame with rate_limited in answer to the request, or a close with 4029.

LimitValue
stream connections per token8
subscriptions per connection100
instruments opened only for the API50, not counting those open in the window
new subscriptions on exchanges a second5

Slow clients

A client that does not read slows down neither the terminal nor other clients. Frames it does not take in time are dropped. For trades a gap frame names the lost numbers. For the other topics the next frame is simply newer.

Sequence numbers

seq numbers the events of a subscription. For trades it grows by one. For topics where only the latest value is sent, gaps in the numbers are normal.

Client requests

What a program sends to the terminal.

subscribe

Ask for a topic.

What a topic needs depends on its family:

  • Market topics are trades, ticker, mark_price, book.top and clusters. instrument is required. connection_id is chosen by the common rule. The scope is market:read.
  • Account topics are account.*. connection_id is required. instrument is not used. The scope is account:read.
  • workspace and settings take neither. The scopes are workspace:read and settings:read.

Only book.top uses params. Other topics ignore them.

FieldTypeDescription
typerequired"subscribe"
request_idstringOptional. Returned in the answer as it is.
topicrequiredTopic
instrumentstringInstrument address, exchange:market:symbol. Required for market topics.
connection_idintegerRequired for account topics. Optional for market topics.
paramsobjectParameters of book.top.
params.depthintegerLevels on each side. Range: 1–200. Default: 50.
params.interval_msintegerThe shortest time between two frames, milliseconds. Range: ≥ 50. Default: 100.
Trades of a pair
{
  "type": "subscribe",
  "request_id": "r1",
  "topic": "trades",
  "instrument": "binance:futures:BTCUSDT",
  "connection_id": 12
}
Top of the book, 10 levels every 250 ms
{
  "type": "subscribe",
  "request_id": "r2",
  "topic": "book.top",
  "instrument": "binance:futures:BTCUSDT",
  "params": {
    "depth": 10,
    "interval_ms": 250
  }
}
Fills of a connection
{
  "type": "subscribe",
  "request_id": "r3",
  "topic": "account.fills",
  "connection_id": 12
}
The layout of the windows
{
  "type": "subscribe",
  "request_id": "r4",
  "topic": "workspace"
}

unsubscribe

Drop a subscription.

Takes only the sub returned by subscribed.

FieldTypeDescription
typerequired"unsubscribe"
request_idstring
subrequiredstringThe identifier from subscribed.
Example
{
  "type": "unsubscribe",
  "request_id": "r5",
  "sub": "7:trades"
}

Server frames

What the terminal answers and sends on its own, apart from events.

subscribed

The subscription is set up.

sub identifies the subscription in every later frame. It is "{stream}:{topic}" for market topics, "{connection}:account.<topic>" for account topics, and "workspace" or "settings" for the other two. Every client subscribed to the same pair and topic gets the same sub. connection_id is present for market and account topics. It is absent for workspace and settings.

FieldTypeDescription
typerequired"subscribed"
request_idstring
subrequiredstring
connection_idintegerThe chosen connection. Absent for workspace and settings.
Example
{
  "type": "subscribed",
  "request_id": "r1",
  "sub": "7:trades",
  "connection_id": 12
}

unsubscribed

The subscription is removed.

FieldTypeDescription
typerequired"unsubscribed"
request_idstring
subrequiredstring
Example
{
  "type": "unsubscribed",
  "request_id": "r5",
  "sub": "7:trades"
}

error

A request is refused, or a subscription is removed by the server.

With request_id it answers a request of the client. With sub and without request_id the server has removed the subscription. The codes are the codes of the HTTP operations.

FieldTypeDescription
typerequired"error"
request_idstringPresent when the frame answers a request.
substringPresent when the frame concerns a subscription.
coderequiredErrorCode
messagerequiredstringText for a human.
A refused request
{
  "type": "error",
  "request_id": "r1",
  "code": "not_found",
  "message": "no connection for the instrument"
}
A subscription removed by the server
{
  "type": "error",
  "sub": "7:trades",
  "code": "unavailable",
  "message": "the exchange refused the subscription"
}

gap

Trades the client lost.

Sent only for trades, before the first frame after the loss. The client was not reading, and the events from from_seq to to_seq are lost. Read them again with GET /v1/market/trades and since_ts.

FieldTypeDescription
typerequired"gap"
subrequiredstring
from_seqrequiredinteger
to_seqrequiredinteger
reasonrequiredstringslow_consumer.
Example
{
  "type": "gap",
  "sub": "7:trades",
  "from_seq": 42,
  "to_seq": 57,
  "reason": "slow_consumer"
}

Topics

Every event has the same envelope; data depends on the topic.

FieldTypeDescription
typerequired"event"
subrequiredstringThe subscription the event belongs to.
seqrequiredintegerThe number of the event in the subscription.
tsrequiredintegerWhen the frame was built, UTC milliseconds.
datarequiredanyThe data of the event. Its shape depends on the topic.
TopicRequiresScopeDelivery
tradesinstrumentmarket:readin order, gaps are reported
tickerinstrumentmarket:readlatest value only
mark_priceinstrumentmarket:readlatest value only
book.topinstrumentmarket:readlatest value only
clustersinstrumentmarket:readlatest value only
account.ordersconnection_idaccount:readlatest value only
account.positionsconnection_idaccount:readlatest value only
account.balancesconnection_idaccount:readlatest value only
account.fillsconnection_idaccount:readone frame per event
workspacenothingworkspace:readlatest value only
settingsnothingsettings:readone frame per event

trades

Trades of a pair, in order.

data is an array of trades, as in GET /v1/market/trades. Trades come in order. If the client falls behind, a gap frame names what was lost.

Data: Trade[]

Example
{
  "type": "event",
  "sub": "7:trades",
  "seq": 41,
  "ts": 1730294400130,
  "data": [
    {
      "id": null,
      "price": "67000.1",
      "qty": "0.012",
      "side": "buy",
      "ts": 1730294400125,
      "exchange_ts": 1730294400119
    }
  ]
}

ticker

The 24-hour ticker of a pair.

data is the ticker, as ticker in GET /v1/market/snapshot. Only the latest value is sent.

Data: Ticker

Example
{
  "type": "event",
  "sub": "7:ticker",
  "seq": 12,
  "ts": 1730294400130,
  "data": {
    "price": "67000.1",
    "change_24h_pct": "1.25",
    "volume_24h": "81234.5",
    "high_24h": null,
    "low_24h": null,
    "best_bid": null,
    "best_ask": null,
    "ts": 1730294400120
  }
}

mark_price

The mark price of a pair.

Only the latest value is sent.

Data: MarkPrice

Example
{
  "type": "event",
  "sub": "7:mark_price",
  "seq": 5,
  "ts": 1730294400130,
  "data": {
    "mark_price": "67001.0",
    "ts": 1730294400120
  }
}

book.top

The top of the order book of a pair.

Each subscriber sets its own depth and interval_ms. Values outside the bounds are refused with invalid_request. The first frame comes as soon as the book is ready. After that at most one frame comes per interval_ms, with the latest book. seq is the version of the book.

Data: BookTop

Example
{
  "type": "event",
  "sub": "7:book.top",
  "seq": 9031,
  "ts": 1730294400130,
  "data": {
    "ts": 1730294400123,
    "depth": 10,
    "bids": [
      [
        "67000.1",
        "1.25"
      ]
    ],
    "asks": [
      [
        "67000.2",
        "0.40"
      ]
    ]
  }
}

clusters

Volume clusters of an instrument.

data is one bucket, as an element of data in GET /v1/market/clusters. A frame comes for every bucket that changed, at most once in 16 ms, with its latest state. A change of the interval in the terminal shows in interval.

Data: ClusterBucket

account.orders

Orders and trigger orders of one instrument after a change.

Only the latest state of the instrument is sent. Subscribing does not touch the exchange, and events come from the moment the connection sends them. There is no snapshot frame on subscribing. Read the current state with GET /v1/account/orders.

Data: InstrumentOrders

account.positions

The position of one instrument after a change.

Only the latest state is sent. A closed position arrives as "position": null. There is no snapshot frame on subscribing.

Data: InstrumentPosition

account.balances

The balance of one currency.

data is one balance, as an element of data in GET /v1/account/balances. Only the latest value is sent. There is no snapshot frame on subscribing.

Data: Balance

account.fills

One fill.

One frame per fill. If the client falls behind, a frame is lost and seq shows the gap. Read the fills again with GET /v1/account/fills and since_ts.

Data: Fill

workspace

The whole layout of the windows.

data is the layout, as data in GET /v1/workspace. The first frame is the current layout, sent at once on subscribing. Then a frame comes for every change. Only the latest state is sent.

Data: WorkspaceSnapshot

settings

One written settings row.

One frame for every write to the settings table: from the API, from Settings App and from the window itself. There is no snapshot on subscribing. Read the current values with GET /v1/settings. If the client falls behind, a frame is lost and seq shows the gap.

Data: SettingWritten

Example
{
  "type": "event",
  "sub": "settings",
  "seq": 3,
  "ts": 1730294400130,
  "data": {
    "scope": "global",
    "scope_id": "default",
    "connection_id": null,
    "category": "multiview",
    "key": "stack_width_px",
    "value": 300
  }
}

Data types

The objects events carry. The same objects are returned by the HTTP operations.

Topic

tradestickermark_pricebook.topclustersaccount.ordersaccount.positionsaccount.balancesaccount.fillsworkspacesettings

ErrorCode

unauthorizedforbiddenforbidden_scopenot_foundinvalid_requestunsupportednot_activenot_tradablerate_limitedunavailable

A stable code, part of the contract. New codes may be added.

CodeHTTPWhen
unauthorized401the token is wrong or the API is off
forbidden403an Origin header or a foreign Host
forbidden_scope403the token lacks the scope of the operation
not_found404no such operation or connection, or no connection for the instrument
invalid_request400a wrong parameter: an instrument, an interval, a depth, a foreign connection_id
unsupported501the exchange is MOEX, the terminal was built without market data, or the setting is not written through the API
not_active409clusters of the instrument are not computed yet, or its leverage is not loaded yet
not_tradable409the connection cannot trade: it is disabled, read-only or has no credentials
rate_limited429a limit is exceeded: connections, subscriptions, instruments, new subscriptions a second, trading commands, workspace commands or settings writes
unavailable503the storage, the exchange or the window did not answer, the terminal is busy, or there is no data yet

Trade

FieldTypeDescription
idrequiredstring | nullAlways null in v1.
pricerequiredstring
qtyrequiredstring
siderequired"buy" | "sell"
tsrequiredintegerWhen the terminal received the trade, UTC milliseconds.
exchange_tsrequiredintegerExchange time.

Ticker

The 24-hour ticker.

FieldTypeDescription
pricerequiredstring
change_24h_pctrequiredstring | null
volume_24hrequiredstring
high_24hrequiredstring | null
low_24hrequiredstring | null
best_bidrequiredstring | null
best_askrequiredstring | null
tsrequiredinteger

MarkPrice

FieldTypeDescription
mark_pricerequiredstring
tsrequiredinteger

BookTop

The top of the book: bids from the best price down, asks from the best price up.

FieldTypeDescription
tsrequiredinteger
depthrequiredinteger
bidsrequiredPriceLevel[]
asksrequiredPriceLevel[]

ClusterBucket

FieldTypeDescription
intervalrequiredstring
tsrequiredintegerThe start of the bucket, UTC milliseconds.
end_tsrequiredinteger
volumerequiredstring
buy_volumerequiredstring
sell_volumerequiredstring
tradesrequiredinteger
vwaprequiredstring | null
min_pricerequiredstring | null
max_pricerequiredstring | null
completedrequiredboolean
last_trade_tsrequiredintegerThe time of the last trade of the bucket. 0 for a bucket from history that has no such time.
levelsrequiredClusterLevel[]Every price level of the bucket, from the lowest price to the highest.

InstrumentOrders

FieldTypeDescription
instrumentrequiredstring
ordersrequiredOrder[]
triggersrequiredTrigger[]

InstrumentPosition

FieldTypeDescription
instrumentrequiredstring
positionrequiredPosition | null

Balance

FieldTypeDescription
currencyrequiredstring
totalrequiredstring
availablerequiredstring | null
lockedrequiredstring | null
tsrequiredinteger

Fill

FieldTypeDescription
trade_idrequiredstring
order_idrequiredstringThe order id of the exchange.
instrumentrequiredstring
siderequiredstringbuy or sell.
pricerequiredstring
qtyrequiredstring
feerequiredstring
fee_currencyrequiredstring
position_siderequiredstring | nulllong or short on exchanges with hedge mode, otherwise null.
tsrequiredintegerExchange time.

WorkspaceSnapshot

FieldTypeDescription
windowsrequiredWindow[]By ascending id.

SettingWritten

A settings row as it was written, without writable.

FieldTypeDescription
scoperequiredstring
scope_idrequiredstring | null
connection_idrequiredinteger | null
categoryrequiredstring
keyrequiredstring
valuerequiredanyAny JSON value.

PriceLevel

string[]

[price, size], both decimal strings.

ClusterLevel

FieldTypeDescription
pricerequiredstring
volumerequiredstring
buy_volumerequiredstring
sell_volumerequiredstring
buy_tradesrequiredinteger
sell_tradesrequiredinteger

Order

FieldTypeDescription
keyrequiredstring | nullThe order key of the terminal, t-…. null until it is known.
exchange_idrequiredstring | nullThe order id of the exchange. null until the exchange accepts the order.
instrumentrequiredstring
siderequired"buy" | "sell"
typerequired"limit" | "market"
pricerequiredstring
sizerequiredstringIn the base coin.
filledrequiredstring
remainingrequiredstring
notionalrequiredstring | nullThe quote amount the trader entered. null for an order from a snapshot of the exchange.
statusrequired"pending" | "open" | "partially_filled"
created_tsrequiredinteger | nullnull for an order from a snapshot of the exchange that has no time.

Trigger

FieldTypeDescription
idrequiredstringThe numeric id used to cancel and amend the trigger.
instrumentrequiredstring
typerequiredTriggerKind
trigger_pricerequiredstring
rulerequiredTriggerRule
sizerequiredstring | nullIn the base coin.
notionalrequiredstring | nullIn the quote currency.
statusrequired"open" | "finished" | "inactive" | "invalid"
order_typerequiredstring | nullThe order type of the exchange, as it came.
client_idrequiredstring | nullThe key returned when the trigger was placed.
created_tsrequiredinteger | null

Position

FieldTypeDescription
instrumentrequiredstring
siderequired"long" | "short"
sizerequiredstringIn the base coin.
lot_sizerequiredstringBase units in one lot.
entry_pricerequiredstring
notionalrequiredstringIn the quote currency.
unrealized_pnlrequiredstringAs the terminal computes it.
mark_pricerequiredstring | nullThe best bid for a long, the best ask for a short. null until the first tick of the order book.

Window

FieldTypeDescription
idrequiredinteger
mainrequiredbooleanThe main window. Closing it ends the terminal.
chart_windowrequiredbooleanA detached window of charts.
focusedrequiredbooleanThe window in the focus of the OS.
geometryrequiredobjectPosition and size in logical pixels of the screen.
geometry.xrequiredinteger
geometry.yrequiredinteger
geometry.widthrequiredinteger
geometry.heightrequiredinteger
geometry.maximizedrequiredboolean
monitorrequiredstring | nullThe name of the monitor as the OS reports it.
tabsrequiredTab[]

TriggerKind

stop_losstake_profitstop

TriggerRule

price_above_or_equalprice_below_or_equal

Tab

FieldTypeDescription
idrequiredintegerNumbered inside each window from one.
namerequiredstring
activerequiredbooleanExactly one tab of a window is active.
stacksrequiredStack[]
chartsrequiredChart[]

Stack

An order book with the tape and clusters.

FieldTypeDescription
widget_idrequiredinteger
instrumentrequiredstring | nullnull while the stack is empty.
connection_idrequiredinteger | null
emptyrequiredboolean
frozenrequiredbooleanThe stack is frozen.
positionrequiredCell | null

Chart

FieldTypeDescription
widget_idrequiredinteger
instrumentrequiredstring | null
connection_idrequiredinteger | null
intervalrequiredstringThe candle interval: 1m, 5m, …
owner_widget_idrequiredinteger | nullThe stack the chart follows. null for a chart on its own.
positionrequiredCell | null

Cell

A cell of the grid of the tab: column from the left, row from the top, cell inside the row.

FieldTypeDescription
columnrequiredinteger
rowrequiredinteger
cellrequiredinteger

On this page