Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bullet Trading API WebSocket Specification

WebSocket endpoint: ws://<host>:<port>/ws

  • Localnet: ws://localhost:3000/ws
  • Staging: wss://tradingapi.staging.bullet.xyz/ws
  • Testnet: wss://tradingapi.testnet.bullet.xyz/ws
  • Mainnet: wss://tradingapi.bullet.xyz/ws

Timestamps: all timestamps in this API are microseconds since Unix epoch (16 digits, e.g. 1706745600000000). Binance uses milliseconds (13 digits). Divide by 1,000 if converting from Bullet to Binance format.


Connection Lifecycle

WebSocket connections go through three phases: establishment, keepalive, and disconnection. The server uses status messages to inform clients of connection state changes (e.g., successful connection, impending disconnection with reason).

Status Message

FieldTypeDescriptionBinance Equivalent
estring"status"- (no equivalent)
Eu64event time (μs)-
statusstring"connected" or "disconnecting"-
clientIdstringUUID client identifier-
reasonstring?disconnect reason (only for disconnecting)-

Connection Establishment

  1. Client connects to WebSocket endpoint
  2. Server assigns unique clientId
  3. Server sends "connected" status message
{
  "e": "status",
  "E": 1706745600000000,
  "status": "connected",
  "clientId": "ws_abc123"
}

Disconnection

The server sends a "disconnecting" status message before closing:

{
  "e": "status",
  "E": 1706745600000000,
  "status": "disconnecting",
  "clientId": "ws_abc123",
  "reason": "pong_timeout"
}

Disconnect Reasons

ReasonDefaultDescription
idle_timeout60sno valid message within timeout
pong_timeout60sclient didn’t respond to ping
max_duration24hconnection exceeded max lifetime

Keepalive (Ping/Pong)

Connections are kept alive via WebSocket ping/pong frames. The server sends ping frames every 30 seconds; clients must respond with pong frames. Most WebSocket libraries answer ping frames automatically. Anything the client sends that proves liveness resets the keepalive timeout: a pong frame, the client’s own ping frame, or an application-level ping message.

Ping

Ping the server to check connection health. Alternatively clients can also send WebSocket ping frames.

{
  "method": "ping",
  "id": 4
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"ping" or "PING"(WebSocket ping frame)
idu64norequest correlation id-

Possible errors: ValidationError (message parse)

Responses: Pong

Pong

{
  "e": "pong",
  "id": 4,
  "E": 1706745600000000
}
FieldTypeDescriptionBinance Equivalent
estring"pong"(WebSocket pong frame)
idu64?echoed request id-
Eu64event time (μs)-

Subscription Streams

All client messages use JSON format with method field. Method names are case-insensitive.

Subscribe

Subscribe to market data topics or user data streams.

{
  "method": "subscribe",
  "id": 1,
  "params": [
    "BTC-USD@aggTrade",
    "ETH-USD@depth10"
  ]
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"subscribe" or "SUBSCRIBE"method: "SUBSCRIBE"
paramsstring[]yesarray of topic stringsparams
idu64norequest correlation idid

Behavior: Idempotent with atomic validation. All topics validated first - if any fails, entire request fails. Already-subscribed topics silently skipped.

Possible errors: ValidationError, TooManyRequests, InvalidSubscriptionFormat, Unauthorized, InvalidSymbol, ClientNotFound

Responses:

Subscribe (success)

{
  "e": "subscribe",
  "id": 1,
  "E": 1706745600000000,
  "result": "success"
}
FieldTypeDescriptionBinance Equivalent
estring"subscribe"- (Binance uses result: null)
idu64?echoed request idid
Eu64event time (μs)-
resultstring"success"result: null

Unsubscribe

Unsubscribe from market data topics or user data streams.

{
  "method": "unsubscribe",
  "id": 5,
  "params": [
    "BTC-USD@aggTrade"
  ]
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"unsubscribe" or "UNSUBSCRIBE"method: "UNSUBSCRIBE"
paramsstring[]yestopics to unsubscribeparams
idu64norequest correlation idid

Behavior: Idempotent - always succeeds. Invalid or non-subscribed topics silently skipped.

Possible errors: ValidationError (message parse)

Responses:

Unsubscribe (success)

{
  "e": "unsubscribe",
  "id": 5,
  "E": 1706745600000000,
  "result": "success"
}
FieldTypeDescriptionBinance Equivalent
estring"unsubscribe"- (Binance uses result: null)
idu64?echoed request idid
Eu64event time (μs)-
resultstring"success"result: null

ListSubscriptions

List all active subscriptions for the client.

{
  "method": "list_subscriptions",
  "id": 6
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"list_subscriptions" or "LIST_SUBSCRIPTIONS"method: "LIST_SUBSCRIPTIONS"
idu64norequest correlation idid

Possible errors: ValidationError (message parse)

Responses:

ListSubscriptions (success)

{
  "e": "list_subscriptions",
  "id": 6,
  "E": 1706745600000000,
  "result": [
    "BTC-USD@depth10",
    "ETH-USD@aggTrade"
  ]
}
FieldTypeDescriptionBinance Equivalent
estring"list_subscriptions"-
idu64?echoed request idid
Eu64event time (μs)-
resultstring[]subscribed topicsresult: […]

Request-Response

OrderPlace

Place an order via WebSocket.

{
  "method": "order.place",
  "id": 10,
  "params": {
    "tx": "c2lnbmVkX3RyYW5zYWN0aW9uX2J5dGVz"
  }
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"order.place" or "ORDER.PLACE"method: "order.place"
params.txstringyessigned base64-encoded borsh transaction bytes(different: REST params)
idu64norequest correlation idid

Building the tx payload: see Place Orders (or Replace Orders for atomic quote refresh) for construction, Order Types and Fields for NewOrderArgs reference, and Signing for the sign → encode → submit flow.

Possible errors: ValidationError (empty tx), ServiceUnavailable (submission failed), Timeout, NewOrderRejected

Responses:


OrderCancel

Cancel an order via WebSocket.

{
  "method": "order.cancel",
  "id": 11,
  "params": {
    "tx": "c2lnbmVkX3RyYW5zYWN0aW9uX2J5dGVz"
  }
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"order.cancel" or "ORDER.CANCEL"method: "order.cancel"
params.txstringyessigned base64-encoded borsh transaction bytes(different: orderId/clientOrderId)
idu64norequest correlation idid

Building the tx payload: see Cancel Orders for construction and Signing for the sign → encode → submit flow.

Possible errors: ValidationError (empty tx), ServiceUnavailable (submission failed), Timeout, CancelRejected

Responses:


OrderAmend

Amend an existing order via WebSocket.

{
  "method": "order.amend",
  "params": {
    "tx": "<signed-base64-borsh-tx>"
  },
  "id": 7
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"order.amend", "order.modify", or "ORDER.AMEND"-
params.txstringyessigned base64-encoded borsh transaction bytes-
idu64norequest correlation idid

Building the tx payload: see Amend Orders for construction and Signing for the sign → encode → submit flow.

Possible errors: ValidationError (empty tx), ServiceUnavailable (submission failed), Timeout, CancelRejected

Responses:


OrderCancelAll

Cancel all open orders for a market via WebSocket.

{
  "method": "order.cancelAll",
  "params": {
    "tx": "<signed-base64-borsh-tx>"
  },
  "id": 8
}
FieldTypeRequiredDescriptionBinance Equivalent
methodstringyes"order.cancelAll" or "ORDER.CANCEL_ALL"-
params.txstringyessigned base64-encoded borsh transaction bytes-
idu64norequest correlation idid

Building the tx payload: see Cancel Market Orders / Cancel All Orders for construction and Signing for the sign → encode → submit flow.

Possible errors: ValidationError (empty tx), ServiceUnavailable (submission failed), Timeout, CancelRejected

Responses:


Responses

Error

Error response to any client request.

{
  "e": "error",
  "id": 2,
  "E": 1706745600000000,
  "error": {
    "param": "invalid-topic-format",
    "code": -1004,
    "msg": "invalid subscription format: expected <symbol>@<stream>"
  }
}
FieldTypeDescriptionBinance Equivalent
estring"error"-
idu64?echoed request idid
Eu64event time (μs)-
error.codei32error codeerror.code
error.msgstringerror messageerror.msg
error.paramstring?parameter that caused error- (Bullet-specific)

OrderResult

Response to OrderPlace, OrderCancel, OrderAmend, or OrderCancelAll.

{
  "e": "order.place",
  "id": 10,
  "E": 1706745600000000,
  "results": {
    "tx_id": "0xabc123def456",
    "status": "processed",
    "order_ids": [
      1
    ],
    "client_order_ids": [
      1
    ]
  }
}
FieldTypeDescriptionBinance Equivalent
estring"order.place", "order.cancel", "order.amend", "order.cancelAll"-
idu64?echoed request idid
Eu64event time (μs)-
results.tx_idstringtransaction hash- (DEX-specific)
results.statusstringtx status — see status values below- (DEX-specific)
results.order_idsu64[]affected order ids- (DEX-specific)
results.client_order_idsu64[]affected client order ids- (DEX-specific)

OrderError

Error response to OrderPlace, OrderCancel, OrderAmend, or OrderCancelAll.

{
  "id": 12,
  "E": 1706745600000000,
  "error": {
    "code": -2010,
    "msg": "new order rejected: insufficient margin"
  }
}
FieldTypeDescriptionBinance Equivalent
idu64?echoed request idid
Eu64event time (μs)-
error.codei32error codeerror.code
error.msgstringerror messageerror.msg

Tx Status Values

StatusDescription
processedtransaction was executed by the sequencer — check order_ids for affected orders
publishedtransaction accepted and will be processed in a subsequent block
submittedtransaction received by the sequencer but not yet published
finalizedtransaction finalized on-chain
droppedtransaction was dropped (e.g. expired uniqueness, duplicate generation value)
unknownstatus could not be determined

Most successful order operations return processed. If you receive dropped, the order was not placed — inspect the error and retry with a fresh uniqueness value.


Market Data

All market data messages are pushed to subscribed clients. No type wrapper.

DepthUpdate

Topic: SYMBOL@depth, SYMBOL@depth5, SYMBOL@depth10, SYMBOL@depth20, SYMBOL@depth100

{
  "e": "depthUpdate",
  "E": 1706745600000000,
  "T": 1706745600000000,
  "s": "BTC-USD",
  "U": 1000,
  "u": 1000,
  "pu": 0,
  "b": [
    [
      "50000.00",
      "1.5"
    ],
    [
      "49999.00",
      "2.0"
    ]
  ],
  "a": [
    [
      "50001.00",
      "1.2"
    ],
    [
      "50002.00",
      "3.0"
    ]
  ],
  "mt": "s"
}
FieldTypeDescriptionBinance Equivalent
estring"depthUpdate"e
Eu64event time (μs)E
Tu64transaction time (μs)T
sstringsymbols
Uu64first update idU
uu64last update id (always equals U)u
puu64previous update idpu
b[[price, qty], …]bids (descending)b
a[[price, qty], …]asks (ascending)a
mtstring"s" (snapshot) or "u" (update)- (Bullet-specific)

Note: U equals u and as we don’t batch updates.

An update (mt: "u") describes how the top N levels of the subscribed depth changed since the previous message. A level that leaves the top N, including one pushed out by a better price, arrives with qty "0"; a level that enters the top N arrives with its full qty. Changes deeper in the book are not sent. Every depth receives each update, possibly with empty b and a, so its pu chain stays continuous.

AggTrade

Topic: SYMBOL@aggTrade

{
  "e": "aggTrade",
  "E": 1706745600000000,
  "s": "BTC-USD",
  "a": 200001,
  "p": "50000.50",
  "q": "0.5",
  "f": 200001,
  "l": 200001,
  "T": 1706745600000000,
  "m": false,
  "th": "0xabc123def456",
  "ua": "",
  "oi": 0,
  "mk": false,
  "ff": false,
  "lq": false,
  "fe": "0",
  "nf": "0",
  "fa": "",
  "co": 0,
  "sd": "",
  "ft": "",
  "z": "0",
  "Z": "0",
  "rs": "0"
}
FieldTypeDescriptionBinance Equivalent
estring"aggTrade"e
Eu64event time (μs)E
sstringsymbols
au64aggregate trade ida
pstringpricep
qstringquantityq
fu64first trade idf
lu64last trade idl
Tu64trade time (μs)T
mboolis buyer makerm
thstringtransaction hash- (DEX-specific)
uastring?deprecated placeholder (""); address not exposed- (DEX-specific)
oiu64?deprecated placeholder (0)- (DEX-specific)
mkbool?deprecated placeholder (false)- (DEX-specific)
ffbool?deprecated placeholder (false)- (DEX-specific)
lqbool?deprecated placeholder (false)- (DEX-specific)
festring?deprecated placeholder ("0")- (DEX-specific)
nfstring?deprecated placeholder ("0"); no Binance equivalent- (DEX-specific)
fastring?deprecated placeholder ("")- (DEX-specific)
cou64?deprecated placeholder (0); client order id belongs on user order updates- (DEX-specific)
sdstring?deprecated placeholder (""); infer aggressor side from m- (DEX-specific)
ftstring?deprecated placeholder (""); fill type belongs on user order updates- (DEX-specific)
zstring?deprecated placeholder ("0"); cumulative fill data belongs on user order updatesz
Zstring?deprecated placeholder ("0"); cumulative fill data belongs on user order updatesZ
rsstring?deprecated placeholder ("0"); remaining size belongs on user order updates- (DEX-specific)

BookTicker

Topic: SYMBOL@bookTicker, !bookTicker

{
  "e": "bookTicker",
  "u": 1000,
  "E": 1706745600000000,
  "T": 1706745600000000,
  "s": "BTC-USD",
  "b": "50000.00",
  "B": "1.5",
  "a": "50001.00",
  "A": "1.2",
  "mt": "s"
}
FieldTypeDescriptionBinance Equivalent
estring"bookTicker"e
uu64update idu
Eu64event time (μs)E
Tu64transaction time (μs)T
sstringsymbols
bstringbest bid priceb
Bstringbest bid qtyB
astringbest ask pricea
Astringbest ask qtyA
mtstring"s" (snapshot) or "u" (update)- (Bullet-specific)

MarkPrice

Topic: SYMBOL@markPrice, !markPrice@arr

{
  "e": "markPriceUpdate",
  "E": 1706745600000000,
  "s": "BTC-USD",
  "p": "50000.50",
  "i": "50000.00",
  "r": "0.0001",
  "T": 1706774400000000
}
FieldTypeDescriptionBinance Equivalent
estring"markPriceUpdate"e
Eu64event time (μs)E
sstringsymbols
pstringmark pricep
istringindex price (median CEX price)i
Pstring?estimated settle priceP
rstringfunding rater
Tu64?next funding timeT
thstring?transaction hash- (DEX-specific)

Mark-price E is publication time in Unix microseconds. Oracle and funding updates can republish the same cached mark with a new E.

Two optional DEX fields identify the actual cached mark event:

FieldTypeDescription
mark_execution_timestamp_usu64?Mark event execution time in Unix microseconds
mark_event_numberstring?Exact UInt64 sequencer event number as a decimal string

These fields and th refer to the mark event, even when an oracle or funding update triggers publication. Startup REST snapshots and upstream events without a transaction hash or event number omit the new fields: their mark execution identity is unknown. Never reinterpret E or the client’s receive time as archived execution time.

To join recent mark history, subscribe and buffer live events before fetching history. Merge identified events by (th, mark_event_number) (history calls th txHash), using execution timestamps for ordering and second buckets. Repeated publications of the same mark add no observation. Take the greatest (timestampUs, eventNumber, txHash) per UTC second, comparing event numbers as integers, and retain the winning event’s actual execution timestamp. Do not shift history to publication time or overwrite a newer live tail with an older HTTP result. Unknown-identity snapshots may update a current-price label, but must not seed historical observations. Missing intervals remain gaps; do not forward-fill them for volatility. Late history can repair older buckets but must not reset the current live price or replay chart animations.

Liquidation (ForceOrder)

Topic: SYMBOL@liquidations, SYMBOL@forceOrder, !liquidations, !forceOrder, liquidations, forceOrders

{
  "e": "liquidation",
  "E": 1706745600000000,
  "o": {
    "s": "BTC-USD",
    "S": "SELL",
    "o": "LIMIT",
    "f": "IOC",
    "p": "49000.00",
    "ap": "49000.00",
    "X": "FILLED",
    "l": "1.0",
    "T": 1706745600000000,
    "th": "0xabc123def456",
    "ua": "0xuser123",
    "oi": 100001,
    "ti": 200001
  }
}
FieldTypeDescriptionBinance Equivalent
estring"liquidation"e ("forceOrder")
Eu64event time (μs)E
o.sstringsymbolo.s
o.Sstringside ("BUY" or "SELL")o.S
o.ostringorder type ("LIMIT")o.o
o.fstringtime in force ("IOC")o.f
o.qstring?original quantityo.q
o.zstring?filled quantityo.z
o.pstringpriceo.p
o.apstringaverage priceo.ap
o.Xstringstatus ("FILLED")o.X
o.lstringlast filled qtyo.l
o.Tu64trade time (μs)o.T
o.thstringtransaction hash- (DEX-specific)
o.uastringliquidated address- (DEX-specific)
o.oiu64order id- (DEX-specific)
o.tiu64trade id- (DEX-specific)

Market Status

Topic: marketStatus, marketStatuses, !marketStatus, !marketStatus@arr

Every market’s trading status. On subscribe you get a full snapshot (mt: "s"); after that only what changed (mt: "u"). Each update message carries every change observed in one refresh, so a single message may list several markets. The status vocabulary is the same as the status field of GET /fapi/v1/exchangeInfo, and the feed covers the same symbols (perpetuals; spot markets are not reported).

{
  "e": "marketStatusUpdate",
  "E": 1706745600000000,
  "mt": "s",
  "m": [
    {
      "s": "BTC-USD",
      "i": 1,
      "st": "TRADING"
    },
    {
      "s": "ETH-USD",
      "i": 2,
      "st": "POST_ONLY"
    }
  ]
}
{
  "e": "marketStatusUpdate",
  "E": 1706745600000000,
  "mt": "u",
  "m": [
    {
      "s": "BTC-USD",
      "i": 1,
      "st": "HALT",
      "ps": "TRADING",
      "ch": "status"
    },
    {
      "s": "SOL-USD",
      "i": 3,
      "st": "POST_ONLY",
      "ch": "listed"
    },
    {
      "s": "OLD-USD",
      "i": 7,
      "st": "CLOSE",
      "ch": "delisted"
    }
  ]
}
FieldTypeDescription
estring"marketStatusUpdate"
Eu64event time (μs)
mtstring"s" snapshot (every market) or "u" update (deltas)
marraythe markets reported in this message
m[].sstringsymbol
m[].iu16market id
m[].ststringstatus, see below
m[].psstring?previous status; only on ch: "status"
m[].chstring?what changed; absent in a snapshot

Status values (st):

ValueDescription
TRADINGopen for trading
POST_ONLYorders may only be posted, not executed; cancels allowed
CANCEL_ONLYorders may only be cancelled
HALThalted; no trading
CLOSEbeing force-settled or settled, pending deletion

Change values (ch):

ValueDescription
listeda market that was not in the previous view
statusthe market’s reported state changed (see below)
delistedthe market is gone; st is the status it last had

ch: "status" covers any change to an existing market’s reported state: its status, its symbol, or both. ps is the previous status, so ps == st means only the symbol changed. Every entry carries the market’s current s and st in full, so applying the entry as-is converges either way.

Deltas are idempotent — applying one twice leaves you in the same state — so a client may safely replay the last message it received.

Notes:

  • The snapshot arrives once the server has synced the market registry. A client that subscribes before the very first sync receives nothing until it lands.
  • Most status changes are picked up from the rollup as they happen; if that event stream is interrupted, they still arrive on the registry’s periodic refresh.
  • One transition is only ever observed on that periodic refresh, because the rollup emits no event for it: a market moving to CLOSE during force-settle.

OrderUpdate

Topic: ADDRESS@user.orders, ADDRESS@ORDER_TRADE_UPDATE

Published for order lifecycle events (NEW, TRADE, CANCELED).

{
  "e": "orderTradeUpdate",
  "E": 1706745600000000,
  "o": {
    "s": "BTC-USD",
    "i": 100001,
    "X": "NEW",
    "x": "NEW",
    "T": 1706745600000000,
    "th": "0xabc123def456",
    "ua": "",
    "S": "BUY",
    "o": "LIMIT",
    "f": "GTC",
    "p": "50000.00",
    "q": "1.0"
  }
}

Common fields (all events):

FieldTypeDescriptionBinance Equivalent
estring"orderTradeUpdate"e ("ORDER_TRADE_UPDATE")
Eu64event time (μs)E
o.sstringsymbolo.s
o.iu64order ido.i
o.Xstringorder statuso.X
o.xstringexecution typeo.x
o.Tu64transaction time (μs)o.T
o.thstringtransaction hash- (DEX-specific)
o.uastring?deprecated placeholder (""); address implicit from authenticated stream- (DEX-specific)

NEW order additional fields:

FieldTypeDescriptionBinance Equivalent
o.Sstringsideo.S
o.ostringorder typeo.o
o.fstringtime in forceo.f
o.pstringpriceo.p
o.qstringquantityo.q

TRADE fill additional fields:

{
  "e": "orderTradeUpdate",
  "E": 1706745600000000,
  "o": {
    "s": "BTC-USD",
    "i": 100001,
    "X": "FILLED",
    "x": "TRADE",
    "T": 1706745600000000,
    "th": "0xabc123def456",
    "ua": "",
    "S": "BUY",
    "ap": "50000",
    "l": "1.0",
    "L": "50000.00",
    "n": "0.025",
    "N": "USDC",
    "m": false,
    "isDegen": false,
    "t": 200001,
    "rp": "10.50",
    "ft": "o",
    "z": "1.0",
    "Z": "50000.00",
    "rs": "0"
  }
}
FieldTypeDescriptionBinance Equivalent
o.Sstringsideo.S
o.apstring?average priceo.ap
o.lstringlast filled qtyo.l
o.Lstringlast filled priceo.L
o.nstringcommissiono.n
o.Nstringcommission asseto.N
o.mboolis maker sideo.m
o.isDegenboolfill of a Degen position- (DEX-specific)
o.tu64trade ido.t
o.rpstringrealized PnLo.rp
o.ftstring?fill type (see fill type values)- (DEX-specific)
o.zstring?cumulative filled size for this ordero.z
o.Zstring?cumulative filled cost (size × price) for this ordero.Z
o.rsstring?remaining size on this order- (DEX-specific)

Fill type values (ft):

ValueDescription
oorderbook
lliquidation
bbackstop liquidation
aADL (auto-deleveraging)

Topics

Symbol-Based Topics

Bullet TopicAliasesBinance EquivalentDescription
SYMBOL@depthsymbol@depthorderbook (default 10)
SYMBOL@depth5symbol@depth5orderbook 5 levels
SYMBOL@depth10symbol@depth10orderbook 10 levels
SYMBOL@depth20symbol@depth20orderbook 20 levels
SYMBOL@depth100-orderbook 100 levels
SYMBOL@aggTradesymbol@aggTradetrades
SYMBOL@bookTickersymbol@bookTickerbest bid/offer
SYMBOL@markPricesymbol@markPricemark price + funding
SYMBOL@tickersymbol@ticker24hr ticker (coming soon)
SYMBOL@liquidationsSYMBOL@forceOrdersymbol@forceOrderliquidations
SYMBOL@kline_INTERVALsymbol@kline_INTERVALcandlesticks (coming soon)

Symbol format: Bullet uses BTC-USD (hyphen), Binance uses btcusdt (lowercase, no separator)

Kline intervals: 1m, 5m, 15m, 30m, 1h, 4h, 1d (coming soon)

Parse errors: InvalidFormat, MissingSymbol, InvalidDepth, InvalidInterval, UnknownTopic Resolution errors: SymbolNotFound

Broadcast Topics

Bullet TopicAliasesBinance EquivalentNote
tickers!ticker@arr, !ticker!ticker@arrcoming soon
markPrices!markPrice@arr, !markPrice!markPrice@arr
bookTickers!bookTicker, !bookTicker@arr!bookTicker
liquidations!liquidations, !forceOrder, forceOrders!forceOrder@arr
marketStatusmarketStatuses, !marketStatus-market status

Parse errors: InvalidFormat, UnknownTopic

User Data Topics

Bullet TopicAliasesBinance Equivalent
ADDRESS@user.ordersADDRESS@ORDER_TRADE_UPDATElistenKey stream

Key difference: Bullet uses address-prefixed topics directly. Binance requires a listenKey from REST API.

Note: Use your main account address, not the delegate address. Order updates for delegate trades are published under the main account.

Resolution errors: MissingUserAddress (when address not provided)

Speed Suffixes

Speed suffixes are accepted but ignored: @100ms, @500ms, @1s

Example: BTC-USD@depth@100ms is equivalent to BTC-USD@depth


Error Codes

General

CodeNameDescriptionBinance Code
-1000Unknownunknown error-1000
-1001Disconnectedserver busy/disconnected-1001
-1002Unauthorizedauthentication required-1002
-1003TooManyRequestsrate limit exceeded-1003
-1006UnexpectedResponseunexpected response-1006
-1007Timeoutrequest timeout-1007
-1014UnknownOrderorder not found-1014
-1015TooManyOrdersorder rate limit-1015
-1016ServiceUnavailableservice down-1016
-1020UnsupportedOperationoperation not supported-1020
-1021InvalidTimestampbad timestamp-1021
-1022InvalidSignaturesignature invalid-1022

Parameters

CodeNameDescriptionBinance Code
-1102MandatoryParamMissingrequired param missing-1102
-1111BadPrecisionprecision error-1111
-1116InvalidOrderTypebad order type-1116
-1117InvalidSidebad side-1117
-1122InvalidSymbolinvalid symbol-1122
-1123InvalidUserAddressinvalid address- (Bullet-specific)

Subscriptions

CodeNameDescriptionBinance Code
-1004InvalidSubscriptionFormatbad topic format- (Bullet-specific)
-1005SymbolNotFoundsymbol not found- (Bullet-specific)
-1008ValidationErrorvalidation failed- (Bullet-specific)
-1010SubscriptionExistsalready subscribed- (Bullet-specific)

Orders

CodeNameDescriptionBinance Code
-2010NewOrderRejectedorder rejected-2010
-2011CancelRejectedcancel failed-2011
-2013NoSuchOrderorder doesn’t exist-2013
-2014ApiKeyFormatInvalidbad api key-2014
-2015InvalidApiKeyIpPermissionsauth failure-2015
-2021OrderWouldTriggerwould trigger immediately-2021

Internal

CodeNameDescriptionBinance Code
-4001ClientNotFoundclient not found- (internal)
-4002CouldNotSendMessagecould not send message- (internal)

Notes

DEX-Specific Fields

DEX-specific fields use 2-letter codes for compactness:

CodeFull NameDescription
thtx_hashon-chain transaction hash
uauser_addressdeprecated aggTrade placeholder
oiorder_iddeprecated aggTrade placeholder
titrade_idsequencer trade ID
coclient_order_idreal on order updates; deprecated aggTrade placeholder
ftfill_typeBullet fill provenance
rsremaining_sizeremaining order size
nfnet_feedeprecated aggTrade placeholder
ffis_full_filldeprecated aggTrade placeholder
lqis_liquidationdeprecated aggTrade placeholder

Message Type Field

The mt field in orderbook and BBO messages indicates:

  • "s" - snapshot (complete state at that depth level)
  • "u" - update (incremental changes since last update)

Response Format Differences

  • All responses use e field for event type (e.g., "e":"subscribe", "e":"error")
  • Order responses still use Binance-style format with status code
  • Market data messages use e field for event type (e.g., "e":"depthUpdate")