Open Order
List resting orders.
Resting orders are the ones waiting to open or close a basket: triggers, TWAP schedules, and ladders.
Each is an instruction that has not run yet. Once one fires, what it did is an execution, and the resting order stays here until it is spent or cancelled. A long-running instruction such as a TWAP is on this page for its whole life while producing an execution per slice. See Orders and Executions.
| Order | Endpoint |
|---|---|
| Triggers | GET /triggers |
| TWAP schedules | GET /schedules |
| Ladders | GET /ladders |
Triggers
curl "https://pro-gateway.pearprotocol.io/triggers?status=ACTIVE" \
-H "x-api-key: $PEAR_API_KEY" \
-H "x-trade-account-id: $TRADE_ACCOUNT_ID"{
"limit": 50,
"triggers": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tradeAccountId": "5e7a1b20-8c34-4d19-b6f0-a1c2d3e4f567",
"connector": "hyperliquid",
"status": "ACTIVE",
"intent": "OPEN",
"type": "MARKET",
"bracketType": "NONE",
"condition": {
"type": "ratio",
"data": { "priceSource": "mid", "symbol_a": "0", "symbol_b": "1", "track": "TROUGH", "threshold": 24 }
},
"context": {
"type": "MARKET",
"legs": [
{ "symbol": "0", "side": "BUY", "mode": "USD", "amount": "500" },
{ "symbol": "1", "side": "SELL", "mode": "USD", "amount": "500" }
],
"attachedTriggers": []
},
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
]
}Useful fields when you reconcile:
| Field | Meaning |
|---|---|
intent | OPEN enters a basket, ADJUST resizes an open position, CLOSE is a take profit or stop loss on one. |
semanticBracketType | What the user asked for: TAKE_PROFIT, STOP_LOSS, or NONE. Optional. Read this, not bracketType. |
bracketType | Required on every trigger, and one of TAKE_PROFIT, STOP_LOSS, NONE. It is the crossing encoding Pear fires on, not user intent — see below. |
condition | The armed condition, including the track Pear derived from the bracket. |
context | The basket the trigger will place. On OPEN it also carries attachedTriggers, the close triggers that will be armed once it fires. On ADJUST and CLOSE it carries position, with the position's id and initialExposure. |
ladderId, ladderIndex | Present when the trigger is one rung of a ladder. |
parentTriggerId | Present when the trigger was attached to another order through attachTriggers. |
triggeredAt, cancelledAt, updatedAt | When the trigger fired, stopped, or last changed. |
cancelledReason | Why it stopped: USER, SYSTEM, POSITION_CLOSED, POSITION_NETTED, or POSITION_REVERSED. |
fills | The fills the trigger produced, already filtered to CONFIRMED and PROVISIONAL, so summing them is safe. |
trailing | Present on a trailing ADJUST or CLOSE trigger, with its trailing configuration. |
Read semanticBracketType, not bracketType
bracketType is the crossing encoding: the direction the gateway watches. For a price bracket on a short watched leg it is flipped on the wire, so a take profit can arrive as STOP_LOSS. Showing it to a user mislabels their order.
semanticBracketType is what the user asked for. It is optional, and absent when a legacy client's encoding cannot be recovered. When it is absent, show nothing rather than falling back to bracketType.
These endpoints are not filtered to resting orders
All three return an instruction's whole life, not just the part where it waits. The default is every state, so a fired trigger and a cancelled schedule come back alongside the live ones. Ask for status=ACTIVE to get only what is still resting:
GET /triggers?status=ACTIVE
GET /schedules?status=ACTIVETwo things to watch, both worth encoding once in your client:
- You query one word and read back another. A trigger is queried as
status=COMPLETEDbut reports itself as"status": "TRIGGERED". Filtering a response on the value you queried finds nothing. COMPLETEDis wider than it looks on a schedule. Querying it matches schedules that finished and schedules that failed, and the response tells them apart withCOMPLETEDorFAILED.
Query status= | Response status | |
|---|---|---|
| Triggers | ACTIVE, COMPLETED, CANCELLED | ACTIVE, TRIGGERED, CANCELLED |
| Schedules | ACTIVE, COMPLETED, CANCELLED | ACTIVE, COMPLETED, FAILED, CANCELLED |
| Ladders | no status filter | ACTIVE, COMPLETED, CANCELLED |
GET /ladders takes no status at all, so filter its results yourself. It returns each ladder with its rung triggers attached, ordered by ladderIndex, so a rung's own state is readable there. Read one ladder with GET /ladders/{ladderId}.
status accepts a comma-separated list on triggers and schedules, so ?status=ACTIVE,CANCELLED works.
GET /triggers also excludes triggers held in an internal IDLE state, in every status. IDLE is not part of the public trigger lifecycle and never appears in a response.
Each of the three pages with limit (default 20, maximum 2000) and cursor. All three accept connector and ignore it: the venue comes from the trade account in x-trade-account-id.
Live updates
For lifecycle updates, subscribe to user_events on the WebSocket and read trigger.created, trigger.triggered, trigger.converted, and trigger.cancelled. This is the channel scoped to your own accounts.
trigger_events is a different thing. It is a public channel, and it carries exactly one topic, trigger.triggered.public — no created, converted, or cancelled. Its accountIds parameter is a filter you supply over public traffic, not a scope to your own accounts. Use it to watch the market, not to track your own orders.
Cancel any of these from Managing Open Order.