Monitor TWAP
Track a running TWAP schedule.
A TWAP order is a schedule. List your schedules with GET /schedules (SDK: sdk.core.schedules.list) to see progress:
curl "https://pro-gateway.pearprotocol.io/schedules?status=ACTIVE" \
-H "x-api-key: $PEAR_API_KEY" \
-H "x-trade-account-id: $TRADE_ACCOUNT_ID"{
"limit": 50,
"schedules": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"connector": "hyperliquid",
"strategy": "TWAP",
"status": "ACTIVE",
"intent": "OPEN",
"executionType": "MARKET",
"positionKey": "9f2c4a7e10b3486d5c8e1a04b7d92f63c05e8a1b7d34f62089ac5e1f30b74d28",
"startAt": "2026-01-01T00:00:00.000Z",
"endAt": "2026-01-01T01:00:00.000Z",
"sliceIntervalSec": 300,
"sliceCount": 12,
"lastSliceAt": "2026-01-01T00:25:00.000Z",
"targetNotional": "1000",
"remainingNotional": "583.33",
"legs": [
{ "symbol": "0", "side": "BUY", "weight": 0.5 },
{ "symbol": "1", "side": "SELL", "weight": 0.5 }
],
"randomization": { "timingJitterBps": 0, "sizeJitterBps": 0 },
"fills": [],
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:25:00.000Z"
}
]
}Reading progress
targetNotional and remainingNotional are the progress fields. How far along the schedule is:
progress = (targetNotional - remainingNotional) / targetNotional| Field | Tells you |
|---|---|
targetNotional | The total USD the schedule set out to trade. |
remainingNotional | The USD it has left. It falls as slices fill. |
status | Whether the schedule is still working. |
sliceCount | How many slices the window is divided into. This is the planned count, recomputed from startAt, endAt, and sliceIntervalSec on every request. It is not a count of slices done. |
lastSliceAt | When the most recent slice went out. Compare it with sliceIntervalSec to see if the next one is due. |
positionKey | The basket the schedule works on. It matches the positionKey on GET /positions/lite. |
fills | The fills the schedule has produced so far, each with quantity, price, usd, and fees. |
cancelledAt, cancelledReason | Why it stopped, such as POSITION_CLOSED. |
There is no slices-done counter and no average-price field. Derive both from fills, with the caveat below.
fillsis unfiltered, and summing it double-counts. UnlikeGET /fills, a schedule'sfillsarray includes supersededRECONCILEDrows alongside theCONFIRMEDrows that replaced them. Drop every fill whosestatusisRECONCILEDbefore you aggregate quantity, notional, or fees. See Fills.
The exposure a running open TWAP has already built shows up in GET /positions as it fills, not only at the end.
A close TWAP is a different shape
intent: "CLOSE" returns positionId and initialExposure — the position it is unwinding and the exposure it started from. It carries no legs, targetNotional, or remainingNotional, so the progress formula above does not apply. Track a close TWAP through the position's shrinking exposure instead.
Query parameters
| Parameter | Values |
|---|---|
status | ACTIVE, COMPLETED, or CANCELLED, as a comma-separated list. Omitting it returns every state. |
limit | Default 20, maximum 2000. |
cursor | The nextCursor of the previous page. |
connector | Accepted and ignored. The venue comes from the trade account. |
Querying status=COMPLETED also returns schedules that failed; the response tells them apart with COMPLETED or FAILED. See Open Order.
Live updates
Subscribe to user_events on the WebSocket for schedule.created, the per-slice executions, schedule.completed, schedule.failed, and schedule.cancelled. Cancel a schedule from Managing Open Order.