Managing Open Order
List, cancel, and change resting orders (triggers, schedules, ladders).
Resting orders, the ones that open or close a basket later, are triggers, TWAP schedules, and ladders. See Orders and Executions for how each relates to the executions and fills it produces.
| Order | List | Read one | Cancel one | Cancel all |
|---|---|---|---|---|
| Trigger | GET /triggers | — | PATCH /triggers/{triggerId}/cancel | PATCH /triggers/cancel-all |
| TWAP schedule | GET /schedules | — | PATCH /schedules/{scheduleId}/cancel | PATCH /schedules/cancel-all |
| Ladder | GET /ladders | GET /ladders/{ladderId} | POST /ladders/{ladderId}/cancel | — |
In the SDK these are sdk.core.triggers.list / .cancel / .cancelAll, sdk.core.schedules.list / .cancel / .cancelAll, and sdk.core.ladders.list / .get / .cancel.
Triggers and schedules have no single-resource endpoint. Find one by filtering its list.
Listing
All three lists are cursor-paginated and take cursor, limit, and connector. Beyond that they differ:
| List | Extra filters |
|---|---|
GET /triggers | status: ACTIVE, COMPLETED, CANCELLED. COMPLETED means the trigger fired. |
GET /schedules | status: ACTIVE, COMPLETED, CANCELLED. COMPLETED also returns schedules that failed. |
GET /ladders | None. There is no status filter, so cancelled and completed ladders come back with the active ones. Read status on each row. |
Ladder rungs are triggers
A ladder's rungs are ordinary triggers, and they appear in GET /triggers like any other. Three consequences:
PATCH /triggers/{triggerId}/cancelcan kill a single rung while its ladder stays active.PATCH /triggers/cancel-allkills every rung of every ladder on the account.- Rung-level state is easiest to read from
GET /ladders/{ladderId}, which returns the ladder with its child rungs in order.
Rungs do not count against the five active triggers per position limit.
Cancelling
A cancel takes no body:
curl -X PATCH "https://pro-gateway.pearprotocol.io/triggers/$TRIGGER_ID/cancel" \
-H "x-api-key: $PEAR_API_KEY" \
-H "x-trade-account-id: $TRADE_ACCOUNT_ID"Cancelling places no order and never unwinds what already happened. What it stops, and what it leaves behind, differs by type:
| Cancelling | Stops | Leaves |
|---|---|---|
| A trigger | The trigger firing. | Nothing, as long as it never fired. |
| A TWAP schedule | Its pending slices. | Every slice that already filled, as part of your position. |
| A ladder | Its unfired rungs. | Every rung that already filled. |
So a half-finished TWAP leaves you holding whatever it built. Read that exposure with GET /positions, and close it with POST /trade/{positionId}/close if you did not want it.
A trigger that has already fired cannot be cancelled at all: it is TRIGGERED, not ACTIVE, and the cancel returns 409. That is true even when the close it launched failed or filled only part of the basket, which is exactly the case where residual exposure is left behind. See Take Profit / Stop Loss.
Cancelling covers both kinds of trigger: the open triggers that would have entered a basket, and the take-profit and stop-loss triggers resting on an open position. Cancelling a stop loss leaves the position open and unprotected.
Find the ids to cancel with the list endpoints above, or from Open Order. Cancellations stream over the WebSocket as trigger.cancelled, schedule.cancelled, or ladder.cancelled.
Cancel-all covers the whole trade account
cancel-all is not scoped to a position. PATCH /triggers/cancel-all cancels every active trigger on the trade account — every stop loss and every take profit, on every open position, plus every ladder rung and every resting open trigger. PATCH /schedules/cancel-all does the same for schedules.
To clear the triggers on one position, list them and cancel them by id.
Both return the ids they cancelled. Both return 409 NOOP_ERROR when nothing is active — No active triggers to cancel and No active schedules to cancel. Treat that 409 as "nothing to do", not as a failure.
Cancel status rules differ
| Cancel | On a resting order | On one that is not active |
|---|---|---|
PATCH /triggers/{triggerId}/cancel | Cancels it | 409 RESOURCE_BUSY |
PATCH /schedules/{scheduleId}/cancel | Cancels it | 409 RESOURCE_BUSY |
POST /ladders/{ladderId}/cancel | Cancels its active rungs | Succeeds anyway. It only 404s on a ladder id that does not exist. |
The ladder cancel is safe to repeat, and tells you nothing about whether the ladder was still running. Read status from GET /ladders/{ladderId} if you need to know.
Changing a resting order
Resting orders are not edited in place. To change one, cancel it and create a new one with the updated terms:
| Order | Cancel | Then create |
|---|---|---|
| Trigger | PATCH /triggers/{triggerId}/cancel | POST /triggers/open or POST /triggers/close |
| TWAP schedule | PATCH /schedules/{scheduleId}/cancel | POST /schedules |
| Ladder | POST /ladders/{ladderId}/cancel | POST /ladders |
Cancel first, then create. The two calls are not atomic, so the market is unwatched in between. See Order Type for the shape of each.
Auto-rebalance is the exception
An auto-rebalance config can be changed in place, and swapped atomically:
| Action | Endpoint |
|---|---|
| Update fields | PATCH /rebalance/auto/{id} |
| Replace in one step | POST /rebalance/auto/{id}/replace |
| Cancel | POST /rebalance/auto/{id}/cancel |
It is a standing config rather than an instruction that fires once, which is why it behaves differently. Note that replace hands back a new config id. See Auto-Rebalance.