Skip to main content
Zero code changes required for most clients. All existing subscriptions, filters, and event fields continue to work unchanged. V2 adds new fields and new event types alongside V1 — nothing was removed or renamed.

TL;DR

Polymarket is migrating from V1 contracts (USDC.e collateral) to V2 contracts (pUSD collateral). The WebSocket service now handles both — V1 and V2 events flow through the same channels and subscription semantics. Four additive changes:
  1. New version field on order_filled, activity, and lifecycle events (1 or 2)
  2. New builder and metadata fields on V2 order_filled events
  3. New collateral channel for pUSD deposit/withdrawal events
  4. New condition_prepared event type on the lifecycle channel

Breaking Change: token_registered Only Fires for V1

V2 exchanges no longer emit TokenRegistered. If you use token_registered as your “new market” signal, you’ll miss V2 markets.Migration: subscribe to the new condition_prepared event type on the lifecycle channel. It fires for both V1 and V2 markets — it’s the upstream signal from the shared ConditionalTokens contract.
EventV1 MarketsV2 Markets
token_registeredYesNo longer emitted
condition_preparedYes (new)Yes (new)
condition_resolutionYesYes
The condition_prepared event fires earlier than token_registered. For binary markets (most Polymarket markets), the service derives token IDs deterministically from condition_id + is_neg_risk and includes them in the tokens array — no extra API call needed. Token labels are placeholders ("Yes" / "No"); resolve canonical labels from Gamma/CLOB if needed. Non-binary markets have tokens: null.

New Fields on Existing Events

Trade events (order_filled)

V1 fills are byte-identical to pre-migration plus a single new version field:
{
  "event_type": "order_filled",
  "side": "BUY",
  "price": 0.61,
  "shares_normalized": 2.564101,
  "status": "confirmed",
  "version": 1
}
V2 fills add builder and metadata (bytes32 hex, zero until Polymarket populates them):
{
  "event_type": "order_filled",
  "side": "BUY",
  "price": 0.45,
  "shares_normalized": 1.81818,
  "status": "confirmed",
  "version": 2,
  "builder": "0x0000...0000",
  "metadata": "0x0000...0000"
}
V2 fee semantics:
  • No fee_refund events on V2 — V2 has no refund flow. The net fee is emitted directly on order_filled at match time.
  • V1 fee_refund behavior is unchanged.

Lifecycle events

Now carry a version field (1 or 2) indicating which contracts emitted them. All other fields unchanged.

Activity events

Now carry a version field. Currently always 1 — V2 activity (split/merge/redeem on V2 contracts) uses the same V1 emission path for now.

New Channel: collateral

V2 replaces USDC.e with pUSD as the trading collateral. When users deposit/withdraw, the pUSD contract emits Wrapped / Unwrapped events. These flow through a new opt-in collateral channel. Subscribe:
{
  "action": "subscribe",
  "platform": "polymarket",
  "version": 1,
  "type": "collateral",
  "filters": { "users": ["0x..."] }
}
Accepts users filter or wildcard. Does not accept condition_ids, market_slugs, or token_ids — collateral flow isn’t tied to a market. Event shape:
{
  "event_type": "polyusd_wrapped",
  "user": "0x3b27d0fb...",
  "asset": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
  "amount": 45000000,
  "amount_normalized": 45,
  "tx_hash": "0x...",
  "timestamp": 1776638042,
  "version": 2
}
  • event_type: "polyusd_wrapped" (deposit: underlying → pUSD) or "polyusd_unwrapped" (withdrawal: pUSD → underlying)
  • user: end-recipient of the operation
  • asset: underlying ERC-20 address (typically USDC.e)
  • amount / amount_normalized: 6-decimal (same as USDC)
Activity events (splits, merges, redeems) are not mixed into the collateral channel. Subscribe to both if you need full wallet flow.
See Collateral Events for the full event reference.

Accepted Channel Types

typeStatus
ordersUnchanged
activityUnchanged — pUSD events not mixed in
lifecycleUnchanged filters; may deliver condition_prepared
oracleUnchanged
orderbookUnchanged
collateralNew

Contract Addresses

RoleAddress
V2 CTF Exchange0xe111180000d2663c0091e4f400237545b87b996b
V2 NegRisk Exchange A0xe2222d279d744050d28e00520010520000310f59
V2 NegRisk Exchange B0xe2222d002000ba0053cef3375333610f64600036
PolyUSD (pUSD)0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb
ConditionalTokens (V1+V2)0x4D97DCd97eC945f40cF65F87097ACe5EA0476045

Backwards-Compatibility Guarantees

  • No field removed, no field renamed, no filter semantic changed.
  • V1 clients that don’t parse version, builder, or metadata will ignore them — same JSON shape as before plus extra keys.
  • Clients with strict JSON schemas that reject unknown properties need a one-line schema update (allow additional properties, or add the new optional fields).
  • Clients with a closed enum for event_type should add "condition_prepared", "polyusd_wrapped", "polyusd_unwrapped" if they want to surface those.

1

Update your event handlers (optional)

Read the new version field on trade/activity/lifecycle events if you want to branch on V1 vs V2 behavior.
2

Fix token discovery (required if you relied on token_registered)

If you used token_registered as your “new market” signal, add a handler for condition_prepared. Query Gamma or CLOB by condition_id to resolve token IDs.
3

Subscribe to collateral (optional)

If you track wallet deposit/withdrawal flow, subscribe to the new collateral channel with type: "collateral".
4

Relax strict schema validation (if applicable)

If your JSON parser rejects unknown keys, add version, builder, metadata as optional fields — or allow additional properties.