PearPear
API IntegrationTrade Activity

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.

OrderEndpoint
TriggersGET /triggers
TWAP schedulesGET /schedules
LaddersGET /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:

FieldMeaning
intentOPEN enters a basket, ADJUST resizes an open position, CLOSE is a take profit or stop loss on one.
semanticBracketTypeWhat the user asked for: TAKE_PROFIT, STOP_LOSS, or NONE. Optional. Read this, not bracketType.
bracketTypeRequired on every trigger, and one of TAKE_PROFIT, STOP_LOSS, NONE. It is the crossing encoding Pear fires on, not user intent — see below.
conditionThe armed condition, including the track Pear derived from the bracket.
contextThe 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, ladderIndexPresent when the trigger is one rung of a ladder.
parentTriggerIdPresent when the trigger was attached to another order through attachTriggers.
triggeredAt, cancelledAt, updatedAtWhen the trigger fired, stopped, or last changed.
cancelledReasonWhy it stopped: USER, SYSTEM, POSITION_CLOSED, POSITION_NETTED, or POSITION_REVERSED.
fillsThe fills the trigger produced, already filtered to CONFIRMED and PROVISIONAL, so summing them is safe.
trailingPresent 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=ACTIVE

Two things to watch, both worth encoding once in your client:

  • You query one word and read back another. A trigger is queried as status=COMPLETED but reports itself as "status": "TRIGGERED". Filtering a response on the value you queried finds nothing.
  • COMPLETED is wider than it looks on a schedule. Querying it matches schedules that finished and schedules that failed, and the response tells them apart with COMPLETED or FAILED.
Query status=Response status
TriggersACTIVE, COMPLETED, CANCELLEDACTIVE, TRIGGERED, CANCELLED
SchedulesACTIVE, COMPLETED, CANCELLEDACTIVE, COMPLETED, FAILED, CANCELLED
Laddersno status filterACTIVE, 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.

On this page