Subscription & Event Handling
The crypto trade event push uses a connect-to-subscribe model: once the client establishes a WebSocket connection and completes authentication, the server automatically pushes all crypto trade events for the authenticated user — no additional subscription request is required.
Message Identification
Upon receiving a push message, follow these two steps to determine the handling scenario:
Step 1: Read event_type → Determine the event category (order placed / filled / cancelled / expired)
Step 2: Read order_info.is_close → Determine whether this is a terminal state with no further updatesevent_type | Description | order_info.is_close |
|---|---|---|
EVENT_NEW | Order placement succeeded | false — order is still active |
EVENT_NEW_REJECTED | Order placement failed | true — terminal state |
EVENT_FILL (partial fill) | order_info.ord_status = PARTIAL_FILLED | false — remainder still open |
EVENT_FILL (full fill) | order_info.ord_status = FILLED | true — terminal state |
EVENT_CANCELED | Cancellation succeeded | true — terminal state |
EVENT_EXPIRED | Order expired | true — terminal state |
Event Coverage
After successful authentication, the client automatically receives all of the following event types with no ability to filter individual types:
| Event Type | Description |
|---|---|
EVENT_NEW | Order placement succeeded |
EVENT_NEW_REJECTED | Order placement failed |
EVENT_FILL | Fill event (partial and full fills) |
EVENT_CANCELED | Cancellation succeeded |
EVENT_EXPIRED | Order expired |
For the message structure and field descriptions of each event, see Data Format.
Account Scope
The server pushes events scoped to the authenticated user's accounts. The user_info.account_id field in each push message identifies the specific crypto account the event belongs to.
Scenario Details
Scenario 1: Order Placement Succeeded
Trigger: The system confirms the order has entered the order queue (status NEW).
Identification: event_type = EVENT_NEW
order_info characteristics:
ord_status = NEWis_close = false— the order is still active; further fill or cancellation events will followcum_qty = "0"— no fills yetavg_px = "0"— no fills yet
Recommended handling: Record the order as "pending fill" and display a waiting-for-fill UI.
Scenario 2: Order Placement Failed
Trigger: The order was rejected by the system (e.g. insufficient balance, invalid price, risk control block).
Identification: event_type = EVENT_NEW_REJECTED
order_info characteristics:
ord_status = REJECTEDorFAILEDis_close = true— terminal state; this order has ended and no further events will be receivedcum_qty = "0"— no fills
Recommended handling: Mark the order as failed and close its lifecycle.
Scenario 3: Partial Fill
Trigger: The order was partially matched; unfilled quantity remains.
Identification: event_type = EVENT_FILL, order_info.ord_status = PARTIAL_FILLED
order_info characteristics:
ord_status = PARTIAL_FILLEDis_close = false— not terminal; further fill or cancellation events may followcum_qty— updated to the cumulative total fill quantity (including this fill)avg_px— updated to the new average fill price
fill_infos[0] characteristics:
quantity— quantity filled in this eventprice— fill price for this eventamount— fill amount for this event
Recommended handling: Accumulate fill details, update the order's filled quantity and average price, and display a "Partially Filled" status. Use fill_id for idempotency to avoid duplicate processing.
Scenario 4: Full Fill
Trigger: The order has been fully matched.
Identification: event_type = EVENT_FILL, order_info.ord_status = FILLED
order_info characteristics:
ord_status = FILLEDis_close = true— terminal state; the order is completecum_qty— equals the originalorder_qty(fully filled)avg_px— final average fill price
Recommended handling: Record the last fill, mark the order as "Fully Filled", and close it — no further events expected.
Scenario 5: Cancellation Succeeded
Trigger: The system confirms the cancellation is complete (full cancel, or cancel after partial fill).
Identification: event_type = EVENT_CANCELED
order_info characteristics:
ord_status = CANCELEDorCANCELLED_PART(cancelled after partial fill)is_close = true— terminal statecum_qty— cumulative filled quantity at the time of cancellation (greater than 0 if there were prior partial fills)avg_px— average fill price at the time of cancellation
Recommended handling: Mark the order as "Cancelled". If cum_qty > "0", it was a partial fill then cancel — retain the filled portion record (ord_status = CANCELLED_PART).
Scenario 6: Order Expired
Trigger: The order exceeded its time in force (e.g. an IOC order that was not immediately fully filled, or an order that reached its expiry).
Identification: event_type = EVENT_EXPIRED
order_info characteristics:
ord_status = EXPIREDis_close = true— terminal statecum_qty— cumulative filled quantity at expiry (IOC orders may have had partial fills before expiry)avg_px— average fill price at expiry
Recommended handling: Mark the order as "Expired". If cum_qty > "0", the IOC order had partial fills before expiry — retain the filled records.
Terminal State Quick Reference
order_info.is_close == true → Order has reached terminal state; no further events for this order
order_info.is_close == false → Order is still active; fill or cancellation events may follow| Scenario | is_close |
|---|---|
| Order placement succeeded | false |
| Order placement failed | true |
| Partial fill | false |
| Full fill | true |
| Cancellation succeeded | true |
| Order expired | true |
Idempotency Recommendations
| Field | Purpose |
|---|---|
event_id | Message-level deduplication to prevent duplicate processing from network replays |
fill_infos[].fill_id | Fill-level deduplication to prevent double-counting |
Consumers should use event_id or fill_id as a key for idempotency checks to avoid duplicate processing.
Timing Examples
Limit buy 0.1 BTC, partial fill then cancel
t1: event_type=EVENT_NEW
→ order_info.cum_qty="0", order_info.is_close=false
→ Order placement succeeded, order is live
t2: event_type=EVENT_FILL, order_info.ord_status=PARTIAL_FILLED
→ order_info.cum_qty="0.06", order_info.is_close=false
→ Partial fill 0.06 BTC, 0.04 BTC remaining
t3: event_type=EVENT_CANCELED, order_info.ord_status=CANCELLED_PART
→ order_info.cum_qty="0.06", order_info.is_close=true
→ Cancellation succeeded, final fill 0.06 BTC, remaining 0.04 BTC cancelledMarket order fully filled
t1: event_type=EVENT_NEW
→ Order placement succeeded
t2: event_type=EVENT_FILL, order_info.ord_status=FILLED
→ order_info.cum_qty=order_info.order_qty, order_info.is_close=true
→ Fully filled, order completeOrder placement failed
t1: event_type=EVENT_NEW_REJECTED
→ order_info.ord_status=REJECTED, order_info.is_close=true
→ Order placement failed, order completeIOC order partial fill then expire
t1: event_type=EVENT_NEW
→ order_info.is_close=false
→ Order placement succeeded
t2: event_type=EVENT_FILL, order_info.ord_status=PARTIAL_FILLED
→ order_info.cum_qty="0.03", order_info.is_close=false
→ Partial fill 0.03 BTC
t3: event_type=EVENT_EXPIRED, order_info.ord_status=EXPIRED
→ order_info.cum_qty="0.03", order_info.is_close=true
→ Remaining quantity expired, final fill 0.03 BTCBehavior Notes
No Replay of Historical Events
Trade events that occurred during a disconnection will not be replayed after reconnection. Use the following REST endpoints to retrieve historical orders or fills:
- Active Orders — Query currently outstanding orders.
- Order History — Query historical orders.
- Get Fills — Query fill records for specific orders.
- Fill History — Query historical fill records.
Recovery After Reconnection
After a disconnection and re-authentication, the server will automatically re-establish the push channel and resume pushing subsequent events.
Next Steps
- Authentication — Learn the authentication flow.
- Connection Keep-Alive — Handle disconnections and reconnections.
- Data Format — View the complete field descriptions for event messages.