This API is in private preview. Target September 2026; timing is subject to change.
tpslUpdates delivers the lifecycle of resting take-profit and stop-loss trigger
orders. This is ideal for trigger heatmaps, stop-order monitoring, frontend
overlays, and alerting.
For the corresponding gRPC stream, see StreamTpslUpdates.
{
"method": "subscribe",
"subscription": { "type": "tpslUpdates", "coins": ["BTC", "ETH"] }
}| Parameter | Type | Required | Source | Description |
|---|---|---|---|---|
coins | string[] | No | Alchemy extension | Markets to subscribe to. Omit to subscribe to all perpetual markets. |
Trigger orders exist only on perpetual markets, so no market-type filter applies.
{
"channel": "subscriptionResponse",
"data": { "subscriptionId": "sub_01", "type": "tpslUpdates" }
}{
"channel": "tpslUpdates",
"subscriptionId": "sub_01",
"blockHeight": 123456,
"blockTime": 1780000000000,
"cursor": "<opaque cursor>",
"data": {
"height": 123456,
"time": 1780000000000,
"isSnapshot": false,
"diffs": [
{
"type": "add",
"oid": 12345,
"coin": "BTC",
"user": "0x1111111111111111111111111111111111111111",
"side": "B",
"triggerPx": "99000.0",
"limitPx": "98900.0",
"sz": "0.10",
"triggerCondition": "Price below 99000",
"orderType": "Stop Limit",
"isPositionTpsl": false,
"reduceOnly": true,
"timestamp": 1780000000000
}
]
}
}| Field | Type | Description |
|---|---|---|
height | integer | Block height. |
time | integer | Block timestamp in milliseconds. |
isSnapshot | boolean | true when the message contains a complete replacement snapshot; absent or false for an incremental update. |
diffs[].type | string | add or remove. |
diffs[].oid | integer | Order ID. |
diffs[].coin | string | Market symbol. |
diffs[].user | string | Address that placed the order. |
diffs[].side | string | B for buy, A for sell. |
diffs[].triggerPx | string | Price at which the order triggers. |
diffs[].limitPx | string | Limit price applied once triggered. |
diffs[].sz | string | Order size. "0.0" indicates a position-level TP/SL sized by the position rather than a fixed quantity. |
diffs[].triggerCondition | string | Human-readable condition, for example Price above 50000. |
diffs[].orderType | string | For example Stop Market, Take Profit Limit. |
diffs[].isPositionTpsl | boolean | True when attached to a position rather than standing alone. |
diffs[].reduceOnly | boolean | True when the order can only reduce a position. |
diffs[].timestamp | integer | Order creation time in milliseconds. |
diffs[].reason | string | Present on remove only. Why the order left the book. |
- Trigger orders are immutable. There is no update operation — a modified order appears as a
removefollowed by anaddwith a newoid - A
removeis always terminal - Perpetual markets only
The first message after subscribing carries a snapshot of all open trigger orders with isSnapshot: true, delivering each order as an add diff. Install it as local state, then apply later diffs. A later message with isSnapshot: true uses the same replacement mechanism for recovery.
For a snapshot shared by many consumers, or to let a slow client digest a large trigger-order set while buffering live updates, use the REST snapshot read instead.
| Reason | Meaning |
|---|---|
triggered | Condition met; the order was placed on the book |
canceled | Cancelled by the user |
reduceOnlyCanceled | Reduce-only order cancelled because the position closed |
marginCanceled | Cancelled due to insufficient margin |
rejected | Rejected by the matching engine |
siblingFilledCanceled | A paired TP/SL order triggered, cancelling this one |
liquidatedCanceled | Cancelled because the position was liquidated |
reason is informational — treat every remove as terminal regardless of its value. New reason values may appear as HyperCore adds order statuses, so do not branch on an exhaustive set.
{
"method": "unsubscribe",
"subscription": { "type": "tpslUpdates", "coins": ["BTC", "ETH"] }
}tpslUpdates carries no per-market seq or prev_seq; gap detection is server-side, so there is no client sequence bookkeeping. See detecting gaps.
- Persist
cursorafter applying a message. - On reconnect, supply
cursorin the subscription object. - A message with
isSnapshot: truereplaces your local state. Any message without it is a diff that must chain onto your previous state. - If continuity is broken, a fresh message with
isSnapshot: trueis pushed to you.isSnapshotis the only continuity signal you need to handle — receiving it means discard local state and adopt the supplied snapshot.