List your trades
cursor
echoed back as nextCursor. limit is capped at 200 (default 50). To fetch
only what is new since a point in time, add after
and follow Polling for new trades.
Response:
Pagination
This feed is keyset-paginated — the same scheme as/api/me/fees and
/api/me/balance-events.
- Each response carries a
nextCursor— an opaque token. Pass it back as?cursor=<nextCursor>to fetch the next (older) page. Treat it as a black box; don’t parse or construct it. nextCursorisnullonly on the last page — never a silent truncation. Keep requesting until it’snull.limitcaps the page size (max 200, default 50).- The legacy
?before=<ISO-8601>parameter still works for backward compatibility, but prefercursor— it carries a unique tiebreaker so rows sharing the samecreatedAt(common when one match writes several rows) are never skipped or duplicated at a page boundary.
Fetching trades after a time
after=<ISO-8601> returns only trades whose createdAt is strictly later
than that instant. It combines with cursor, before and marketId, and
the feed still runs newest first.
- Send an explicit zone,
Zor±hh:mm:2026-10-01T08:30:00Zor2026-10-01T10:30:00.250400+02:00. Up to microseconds are honoured. A time without a zone is rejected with400 invalid_timestamp, not guessed. - Page with
nextCursoruntil it isnull. The cursor carriesafter, socursor=<nextCursor>on its own stays inside the window. - An
afterin the future returns an empty page. - If you also send
beforewithout acursor,aftermust be earlier than it; otherwise the answer is400 invalid_range.
Polling for new trades
createdAt is the time matching started, not the moment the trade became
visible here. A trade can therefore appear after one with a later
createdAt. Poll with an overlap:
- Set
afterto the newestcreatedAtyou have seen minus 60 seconds. - Page until
nextCursorisnull. - Upsert by
id. The overlap returns trades you already have.
after selects trades by creation time only. A trade you already have is
not returned again when its status, txHash or settledAt changes. Keys
with the partner:trades:read scope can follow those changes on the
partner trades feed
(modifiedSince).
Fields
Lifecycle
A trade row is created on the matcher confirming a cross and progresses through a small set of public statuses until the chain-side settlement lands.
The
settlement_failed state is not exposed on this feed — that’s
an ops-only signal for chain reverts and is filtered server-side. If
your integration relies on txHash finality, gate on
status === "settled" and settledAt != null.
Adjustment
adjustment reflects the chain mechanism that backed the trade:
MINT / BURN occur only on YES/NO markets that match every order on
a single YES book, where opposite-outcome BUYs (or SELLs) can cross
each other. On other markets every fill is NONE, and so is a fill
where both sides traded the same outcome.
Fills for a single order
{ orderId, trades }: each trades entry has the same Trade
shape (without groupItemImageUrl), oldest first, for the fills that
touched this order. An order id you don’t own, or one that doesn’t
exist, returns 200 with trades: [] rather than 404.
Real-time
Three WebSocket channels surface the same lifecycle:user_fills— emitted onmatchedfor every wallet fill.vault_activity(trade_fill) andvault_positions(vault_position_balance_changed) — fire when the fill settles on-chain, with the chain-confirmed balance changes.token_trade_settlements— public per-token feed of settled trades.