What you get
- Identical event format to Dome — same 16 fields, same field names, same types
- Pre-chain delivery: events arrive 3-5 seconds before on-chain confirmation (and before Dome)
- All existing filters work:
condition_ids,wallets,tokens,slugs,side,min_size - One subscription type change:
"dome"instead of Dome’s"orders"
Quick start
1. Get an API key
Sign up at polynode.dev to get your API key.2. Connect
Replace your Dome WebSocket URL with polynode’s:3. Subscribe
The subscribe message changes slightly. Dome usedplatform and version fields that polynode doesn’t need:
4. Process events
No changes needed. The event format is identical:Event format
Every event is a flat object with 16 fields, matching Dome’s format exactly.Wrapper
Data fields
| Field | Type | Description |
|---|---|---|
order_hash | string | EIP-712 order hash. Persistent across partial fills of the same limit order. Use this to track order fill status. |
user | string | Address of the order placer. The order_hash belongs to this address. |
taker | string | Counterparty address. On the taker’s own fill event, this is the exchange contract address (see Order perspective below). |
tx_hash | string | On-chain transaction hash. |
side | string | "BUY" or "SELL" |
price | number | Fill price as a decimal (e.g. 0.65). |
shares | number | Raw token amount with 6 decimal precision (e.g. 25000000 = 25 tokens). |
shares_normalized | number | Human-readable token amount (e.g. 25.0). |
token_id | string | Polymarket conditional token ID. |
token_label | string | Outcome name (e.g. "Yes", "No", "Up", "Down"). |
condition_id | string | Polymarket condition ID for the market. |
market_slug | string | URL slug for the market. |
title | string | Human-readable market title. |
timestamp | number | UNIX timestamp in seconds when the event was detected. |
block_number | null | Always null for pre-chain events. polynode detects settlements from the mempool before they confirm on-chain. |
log_index | null | Always null for pre-chain events. |
Example event
Order perspective
Each on-chain settlement produces multiple fill events, one perOrderFilled log. This is identical to how Dome works.
Maker fill events: user is the maker’s address, taker is the actual taker’s wallet address, order_hash is the maker’s EIP-712 order hash.
Taker fill events: user is the taker’s address, taker is the exchange contract address (not a real wallet). The order_hash is the taker’s EIP-712 order hash.
The exchange contract address depends on the market type:
| Market type | Exchange contract |
|---|---|
| Standard (neg_risk = false) | 0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e |
| Neg-risk (neg_risk = true) | 0xc5d563a36ae78145c45a50134d48a1215220f80a |
OrderFilled event reflects this, and both Dome and polynode pass it through as-is.
To find your order’s fills: Check if event.user === yourWallet. When it matches, event.order_hash is your order’s hash.
Copy trading example
If you’re building a copy trading system that tracks orders by hash:Full migration example
Complete before/after showing the Dome to polynode migration:What changes
| Dome | polynode | |
|---|---|---|
| WebSocket URL | wss://ws.domeapi.io/{key} | wss://ws.polynode.dev/ws?key={key} |
| Subscribe type | "orders" | "dome" |
| Subscribe fields | platform, version required | Not needed |
| Ack message | {"type": "ack"} | {"type": "subscribed"} |
| Event format | 16 fields | Same 16 fields |
block_number | Block number (integer) | null (pre-chain) |
log_index | Log index (integer) | null (pre-chain) |
| Delivery speed | On-chain confirmation (~2s block time) | Pre-chain mempool detection (3-5s earlier) |
What stays the same
- All 16 data fields:
order_hash,user,taker,tx_hash,side,price,shares,shares_normalized,token_id,token_label,condition_id,market_slug,title,timestamp,block_number,log_index - One event per order fill (not bundled)
order_hashbelongs touser- Taker fills show exchange contract as
taker - All filter types:
condition_ids,wallets,tokens,slugs,side,min_size
Filters
The dome subscription supports all standard polynode filters:Differences from Dome
block_number and log_index are always null. polynode detects settlements from the Polygon mempool before they are included in a block. This is why events arrive 3-5 seconds before Dome. The tradeoff is that block-level fields aren’t available at detection time.
Minor floating-point precision differences on price and shares. polynode computes fill amounts from transaction calldata, while Dome reads from on-chain OrderFilled event logs. In rare cases (~1% of fills), this produces sub-penny price differences (e.g. 0.76 vs 0.7599999821) or shares off by 1 unit in millions. All other fields are byte-identical.
No subscription_id in event wrapper. Dome includes a subscription_id field in every event message. polynode does not include this field, consistent with all other polynode subscription types. If your code reads msg.subscription_id, it will be undefined but this should not affect event processing.
