The fill event
Every field of a pushed trade.
The fill event
Both channels deliver the same fill object as data. The webhook body is {"type":"fill","data":{…}}; the WebSocket frame is the same plus session and seq. Each channel stamps its own tPush.
{ "type": "fill", "data": { "eventId": "137:93912410:0x8f2c…a91b:0x4d0e…77c3:41", "chain": 137, "entityId": "0x9a3f…21e8", "wallet": "0x5b71…0cd2", "ts": "2026-09-16 14:02:11", "block": 93912410, "blockHash": "0x8f2c…a91b", "txHash": "0x4d0e…77c3", "logIndex": 41, "exchange": "pm_ctf_v2", "side": "BUY", "role": "taker", "tokenId": "3200000000…", "price": "0.570000", "shares": "3200000000", "usdc": "1824000000", "fee": "0", "tDetect": "2026-09-16T14:02:11.412Z", "tPush": "2026-09-16T14:02:11.733Z", "marketTitle": "Will the Fed cut rates in October?", "conditionId": "0x5f1e…c2a9" } }
| eventId | string | Stable id for this fill, unique per delivery: chain, block, block hash, tx, log index. Deduplicate on this. |
| chain | number | 137 (Polygon). Present so an id is never ambiguous if we add a chain. |
| entityId | 0x address | The entity you subscribed to, identifying the trader rather than necessarily the signing address. |
| wallet | 0x address | The address that actually traded. One entity usually has several. |
| ts | string (UTC) | Block timestamp, UTC. The send time differs; see the latency page for that gap. |
| block | number | Block the fill was included in. |
| blockHash | 0x hash | Hash of that block. If a reorg re-includes the same tx, the hash differs and it is a new event. |
| txHash | 0x hash | Transaction hash. |
| logIndex | number | Position of the log inside the block. |
| exchange | string | Which Polymarket exchange contract matched it, e.g. pm_ctf_v2. |
| side | "BUY" | "SELL" | Direction from this wallet's point of view. |
| role | "maker" | "taker" | Whether this wallet was the maker or the taker. Only takers pay a fee. |
| tokenId | string (uint256) | The outcome token (ERC-1155 id), as a decimal string because it does not fit in a JS number. |
| price | string (decimal) | Price per share in USDC, as a decimal string. |
| shares | string (integer) | Integer, 6 decimals implied (micro-shares). 3200000000 is 3,200 shares. |
| usdc | string (integer) | Integer, 6 decimals implied (micro-USDC). 1824000000 is $1,824. |
| fee | string (integer) | Cash fee charged by the contract, micro-USDC. Zero for makers. |
| tDetect | string (ISO 8601) | When we saw the block, our clock (UTC). Push only. |
| tPush | string (ISO 8601) | When this channel sent it, our clock (UTC); tPush − tDetect is what the latency page measures. Push only. |
| marketTitle? | string | The market's title, when we already have it cached; absent otherwise. Push only. |
| conditionId? | 0x hash | The market's condition id, sent together with marketTitle. Push only. |
Amounts are integers with six implied decimals, sent as strings. They are the values the contracts emitted; we do not convert them to floats, because a file people reconcile against a chain explorer must not have been rounded on the way out. Divide by 1,000,000 for display.
The rows GET /v1/account/fills replays carry the ledger fields only: tDetect, tPush, marketTitle and conditionId are not in them.
On a reorg we do not retract anything. If a transaction is re-included in a competing block you receive a second event with a different blockHash. The block hash is therefore part of eventId. Deduplicating on the transaction hash alone would drop a real fill.