Skip to content

Data Format

WebSocket crypto trade event push uses Protobuf binary encoding. Each push message corresponds to one trade event. The client should first distinguish the event type by the event_type field, then parse the specific fields such as order_info and fill_infos.

Note

Trade event pushes are transmitted as Protobuf binary frames, not JSON text. The authentication response (code/msg) is JSON. Clients must allow receiving binary frames (e.g., skip_utf8_validation=True).

INFO

Numeric fields in trade events (such as price and quantity) are transmitted as strings to avoid floating-point precision issues. Time fields use microsecond timestamps (Unix microseconds). Handle types according to field descriptions when parsing, and ignore unknown fields to maintain forward compatibility.

Message Structure

The top level of each push message is a CryptoTradeEvent object:

json
{
  "event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "event_type": "EVENT_FILL",
  "event_time_us": 1751433600000000,
  "user_info": {
    "uid": 123456789,
    "account_id": 987654321098765432
  },
  "order_info": {
    "order_id": "FTHC2989880641155745280T",
    "version": 2,
    "symbol_pair": {
      "symbol": "BTCUSD",
      "base": "BTC",
      "quote": "USD"
    },
    "side": "BUY",
    "order_qty": "0.1",
    "price": "29500",
    "order_amount": "2950",
    "cum_qty": "0.06",
    "avg_px": "29498.50",
    "fill_amount": "1769.91",
    "ord_type": "LIMIT",
    "time_in_force": "TIF_GTC",
    "create_time": 1751433500000000,
    "update_time": 1751433600000000,
    "ord_status": "PARTIAL_FILLED",
    "order_show_id": "C2989880641155745280",
    "is_close": false,
    "trigger_price": "",
    "trigger_time": 0,
    "cash_order_qty": ""
  },
  "fill_infos": [
    {
      "order_id": "FTHC2989880641155745280T",
      "fill_id": "FILL001",
      "quantity": "0.06",
      "price": "29498.50",
      "amount": "1769.91",
      "fill_time": 1751433600000000
    }
  ]
}

CryptoTradeEvent Top-Level Fields

FieldTypeDescription
event_idstringUnique event ID (UUID). Can be used for client-side idempotency.
event_typestringEvent type. See event type descriptions below.
event_time_usintegerEvent occurrence time, Unix microsecond timestamp.
user_infoobjectUser information. See user_info Fields.
order_infoobjectOrder snapshot reflecting the latest order state at the time of the event. See order_info Fields.
fill_infosobject[]List of fill details. See fill_infos Fields. Only populated for EVENT_FILL events; empty array for all other event types.

Event Types

Possible values for the event_type field:

ValueDescription
EVENT_NEWOrder placement succeeded. The order has been accepted by the system and entered the order queue. order_info.is_close = false.
EVENT_NEW_REJECTEDOrder placement failed. The order was rejected by the system. order_info.is_close = true.
EVENT_FILLFill event. fill_infos contains the fill details for this event. Use order_info.ord_status to distinguish partial fill (PARTIAL_FILLED) from full fill (FILLED). order_info.is_close = true when fully filled.
EVENT_CANCELEDCancellation succeeded. The order has been cancelled. order_info.is_close = true.
EVENT_EXPIREDOrder expired. The order was cancelled by the system due to expiry. order_info.is_close = true.

user_info Fields

FieldTypeDescription
uidintegerUser ID (nnid).
account_idintegerCrypto account ID (uint64). If the same user holds multiple crypto accounts, this field identifies which account the event belongs to.

order_info Fields

Each push message carries the current snapshot of the order, reflecting the latest order state at the time of the event.

Key Field: is_close

is_close = true means the order has reached a terminal state — no further push events will be received for this order. is_close = false means the order is still active; fill or cancellation events may follow.

FieldTypeDescription
order_idstringOrder ID, unchanged throughout the order lifecycle.
versionuint32Order version number.
symbol_pairSymbolPairTrading pair.
sidesideTrade direction.
order_qtystringOrder quantity.
pricestringLimit price. May be empty for market orders.
order_amountstringOrder amount.
cum_qtystringCumulative filled quantity as of this event.
avg_pxstringAverage fill price as of this event. "0" if no fills yet.
fill_amountstringCumulative fill amount as of this event.
ord_typeord_typeOrder type.
time_in_forcetime_in_forceTime in force.
create_timeint64Order creation time, Unix microsecond timestamp.
update_timeint64Order last update time, Unix microsecond timestamp.
ord_statusord_statusCurrent order status.
order_show_idstringDisplay order ID for client UI.
is_closebooltrue indicates the order has reached a terminal state — no further events will be pushed for this order. See note above.
trigger_pricestringTrigger price for conditional orders; empty string for non-conditional orders.
trigger_timeint64Trigger time for conditional orders (Unix microseconds); 0 if not yet triggered.
cash_order_qtystringOrder amount for amount-based orders; empty string for quantity-based orders.

fill_infos Fields

Only contains valid data for EVENT_FILL events; empty array for all other event types.

FieldTypeDescription
order_idstringAssociated order ID.
fill_idstringFill ID. Can be used for idempotency deduplication.
quantitystringQuantity filled in this event.
pricestringFill price in this event.
amountstringFill amount in this event (price × quantity).
fill_timeint64Fill time, Unix microsecond timestamp.

Compatibility Recommendations

  • Dispatch by event_type: Whether fill_infos has data varies significantly across event types. Use switch/match for handling.
  • Ignore unknown fields: The server may add new fields; clients should maintain forward compatibility.
  • Handle unknown event_type values: Log and skip them to avoid errors from newly added event types.
  • Parse numeric fields as strings: Price, quantity, and similar fields are strings — convert to Decimal or float as needed for precision.
  • Microsecond timestamps: event_time_us, create_time, update_time, and fill_time are all Unix microsecond timestamps — be careful not to confuse them with millisecond timestamps.