Skip to main content
A real-time tape of every confirmed Polymarket OrderFilled event, for all wallets or for a set of wallets you choose. Each frame is one fill row read from the chain record after its block is final in our warehouse. For the lowest-latency (pre-block) signal, use the mempool feed instead.
  • Venue: Polymarket only.
  • Exchange scope: CLOB V2. Fills from the CTF Exchange V2 and the NegRisk CTF Exchange V2. ExchangeV3 (combo markets, live since about 2026-11-02) fills are not on this tape yet. Combo settlements have their own combos stream.
  • Credential: a Market Data key (stream.read), signed like Live Trades with path set to /stream/polymarket/partner/fills. Metered like Live Trades.

Connect and subscribe

A new connection subscribes to nothing. Subscribe in band:
Resume. Send the block_number and log_index of the last frame you processed. The server replays everything after it, then continues live. A token that is too old is refused with RESUME_TOO_STALE. Without a token, the stream starts at the current tip.

Frame

Money and shares are fixed-scale decimal strings (6 decimals), never JSON numbers. An unknown price is null, never 0. One match produces several frames. Polymarket emits one OrderFilled per order in a match: one for each maker order, plus one for the taker order. Each is its own frame.
string
The owner of this row’s order (the maker of this OrderFilled). side, shares_normalized and price are from this owner’s point of view.
string
BUY or SELL.
string
Shares filled, 6 decimals.
string
pUSD per share, 6 decimals, from the exact integer ratio. null when it cannot be computed.
integer
Block time, unix seconds.
string
Chain coordinates (block_number is a decimal string).
integer
Log index in the block. (block_number, log_index) is the resume token.
string
<tx_hash>:<log_index>, the chain-log identity of the fill. Use it to drop duplicates across your own reconnects.
string
The fee charged to this row’s order, pUSD, 6 decimals, as logged on chain. The taker order usually pays it; maker rows are usually "0.000000".
string
taker when this row is the taker order’s fill, else maker. Absent when it cannot be determined.
string
The raw taker of the log: the counterparty (the taker order’s owner) on a maker row, and the exchange contract itself on the taker-order row.
string | null
The builder code (bytes32) of this row’s own order: the taker’s builder on the taker-order row, each maker’s own builder on its row. null means the order carried no builder code. Absent means it is not known on this read path (a resumed wallet-set replay does not carry it).
string
Market metadata for the token, looked up server-side. Each field is absent when we have no value for it (for example, a market synced moments ago). It is never sent as "", 0 or false to mean unknown.
Builder attribution. Summing volume per builder over frames is correct attribution: each row carries its own order’s builder. The sum across all builders is routed order volume, about 2× the matched volume, because both sides of a match are rows. The builder’s share of the fee is not on chain: one fee is charged per order and paid to Polymarket’s fee receiver. Builder fees are not served on this tape.
dedup_key changed format on 2026-11-12: from tx_hash:token_id:user to tx_hash:log_index (for example "0x…:71321045…:0x…" → "0x…:4"). The old key collided for distinct fills of one wallet in one transaction, and those fills were dropped as duplicates. If you only compare dedup_key values, accept the new format and nothing else changes. If you parsed it, read tx_hash and log_index from their own fields.
  • Mempool feed: the same fills before the block, with the pending → mined lifecycle.
  • Live Trades: the venue trade feed.