Skip to main content

List your trades

Reverse-chronological. Paginate with the opaque 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.
  • nextCursor is null only on the last page — never a silent truncation. Keep requesting until it’s null.
  • limit caps the page size (max 200, default 50).
  • The legacy ?before=<ISO-8601> parameter still works for backward compatibility, but prefer cursor — it carries a unique tiebreaker so rows sharing the same createdAt (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, Z or ±hh:mm: 2026-10-01T08:30:00Z or 2026-10-01T10:30:00.250400+02:00. Up to microseconds are honoured. A time without a zone is rejected with 400 invalid_timestamp, not guessed.
  • Page with nextCursor until it is null. The cursor carries after, so cursor=<nextCursor> on its own stays inside the window.
  • An after in the future returns an empty page.
  • If you also send before without a cursor, after must be earlier than it; otherwise the answer is 400 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:
  1. Set after to the newest createdAt you have seen minus 60 seconds.
  2. Page until nextCursor is null.
  3. Upsert by id. The overlap returns trades you already have.
Setting after to exactly the newest createdAt you have seen can miss a trade for good. Always keep the 60-second overlap.
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

Returns { 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 on matched for every wallet fill.
  • vault_activity (trade_fill) and vault_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.
See WebSocket reference.