Skip to content
Alchemy Logo

tpslUpdates stream

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"] }
}

ParameterTypeRequiredSourceDescription
coinsstring[]NoAlchemy extensionMarkets 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
      }
    ]
  }
}

FieldTypeDescription
heightintegerBlock height.
timeintegerBlock timestamp in milliseconds.
isSnapshotbooleantrue when the message contains a complete replacement snapshot; absent or false for an incremental update.
diffs[].typestringadd or remove.
diffs[].oidintegerOrder ID.
diffs[].coinstringMarket symbol.
diffs[].userstringAddress that placed the order.
diffs[].sidestringB for buy, A for sell.
diffs[].triggerPxstringPrice at which the order triggers.
diffs[].limitPxstringLimit price applied once triggered.
diffs[].szstringOrder size. "0.0" indicates a position-level TP/SL sized by the position rather than a fixed quantity.
diffs[].triggerConditionstringHuman-readable condition, for example Price above 50000.
diffs[].orderTypestringFor example Stop Market, Take Profit Limit.
diffs[].isPositionTpslbooleanTrue when attached to a position rather than standing alone.
diffs[].reduceOnlybooleanTrue when the order can only reduce a position.
diffs[].timestampintegerOrder creation time in milliseconds.
diffs[].reasonstringPresent on remove only. Why the order left the book.

  • Trigger orders are immutable. There is no update operation — a modified order appears as a remove followed by an add with a new oid
  • A remove is 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.

ReasonMeaning
triggeredCondition met; the order was placed on the book
canceledCancelled by the user
reduceOnlyCanceledReduce-only order cancelled because the position closed
marginCanceledCancelled due to insufficient margin
rejectedRejected by the matching engine
siblingFilledCanceledA paired TP/SL order triggered, cancelling this one
liquidatedCanceledCancelled 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 cursor after applying a message.
  • On reconnect, supply cursor in the subscription object.
  • A message with isSnapshot: true replaces 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: true is pushed to you. isSnapshot is the only continuity signal you need to handle — receiving it means discard local state and adopt the supplied snapshot.
Was this page helpful?