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 report_type → Determine the event category (placement / fill / cancellation / expiry)
Step 2: Read order.is_close → Determine whether this is a terminal state with no further updatesreport_type | Description | order.is_close |
|---|---|---|
1 (new_rpt.result=0) | Order placement succeeded | false — order is still active |
1 (new_rpt.result≠0) | Order placement failed | true — terminal state |
4 (fill_rpt.fill_status=1) | Partial fill | false — remainder still open |
4 (fill_rpt.fill_status=2) | Full fill | true — terminal state |
3 (cancel_rpt.result=0) | Cancellation succeeded | true — terminal state |
5 | Order expired | true — terminal state |
Event Coverage
After successful authentication, the client automatically receives all of the following report types with no ability to filter individual types:
report_type | Description |
|---|---|
1 | Order placement report (success and failure) |
3 | Order cancellation report |
4 | Fill report (partial and full fills) |
5 | Order expiry report |
For the message structure and field descriptions of each report type, see Data Format.
Scenario Details
Scenario 1: Order Placement Succeeded
Trigger: The system confirms the order has entered the order queue.
Identification: report_type=1, new_rpt.result=0
order characteristics:
is_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: report_type=1, new_rpt.result≠0
order characteristics:
is_close = true— terminal state; this order has ended and no further events will be receivedcum_qty = "0"— no fills
new_rpt characteristics:
result— non-zero error codeerr_msg— failure reason
Recommended handling: Mark the order as failed, display new_rpt.err_msg, and close its lifecycle.
Scenario 3: Partial Fill
Trigger: The order was partially matched; unfilled quantity remains.
Identification: report_type=4, fill_rpt.fill_status=1
order characteristics:
is_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_rpt characteristics:
last_qty— quantity filled in this eventlast_px— fill price for this eventlast_amount— fill amount for this eventleave_qty— remaining unfilled quantity
Recommended handling: Accumulate fill details, update the order's filled quantity and average price, and display a "Partially Filled" status. Use fill_rpt.fill_id for idempotency to avoid duplicate processing.
Scenario 4: Full Fill
Trigger: The order has been fully matched.
Identification: report_type=4, fill_rpt.fill_status=2
order characteristics:
is_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: report_type=3, cancel_rpt.result=0
order characteristics:
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 order.cum_qty > "0", it was a partial fill then cancel — retain the filled portion record.
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: report_type=5
order characteristics:
is_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 order.cum_qty > "0", the IOC order had partial fills before expiry — retain the filled records.
Terminal State Quick Reference
order.is_close == true → Order has reached terminal state; no further events for this order
order.is_close == false → Order is still active; fill or cancellation events may follow| Scenario | order.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 |
|---|---|
report_id | Message-level deduplication to prevent duplicate processing from network replays |
fill_rpt.fill_id | Fill-level deduplication to prevent double-counting |
Consumers should use report_id or fill_rpt.fill_id as a key for idempotency checks to avoid duplicate processing.
Timing Examples
Limit buy 0.1 BTC, partial fill then cancel
t1: report_type=1, new_rpt.result=0
→ order.cum_qty="0", order.is_close=false
→ Order placement succeeded, order is live
t2: report_type=4, fill_rpt.fill_status=1
→ order.cum_qty="0.06", order.is_close=false
→ Partial fill 0.06 BTC, fill_rpt.leave_qty="0.04"
t3: report_type=3, cancel_rpt.result=0
→ order.cum_qty="0.06", order.is_close=true
→ Cancellation succeeded, final fill 0.06 BTC, remaining 0.04 BTC cancelledMarket order fully filled
t1: report_type=1, new_rpt.result=0
→ Order placement succeeded
t2: report_type=4, fill_rpt.fill_status=2
→ order.cum_qty=order.order_qty, order.is_close=true
→ Fully filled, order completeOrder placement failed
t1: report_type=1, new_rpt.result≠0
→ order.is_close=true, new_rpt.err_msg="<failure reason>"
→ Order placement failed, order completeIOC order partial fill then expire
t1: report_type=1, new_rpt.result=0
→ order.is_close=false
→ Order placement succeeded
t2: report_type=4, fill_rpt.fill_status=1
→ order.cum_qty="0.03", order.is_close=false
→ Partial fill 0.03 BTC
t3: report_type=5
→ order.cum_qty="0.03", order.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:
- Get Unfilled Orders — Query currently outstanding orders.
- Get Order History — Query historical orders.
- Get Fill Details — Query fill records for specific orders.
- Get 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.