Overview
Struct’s websocket API streams real-time Polymarket data directly to your application without polling REST. Connect once, subscribe to any number of rooms, and receive live updates for trades, prices, metrics, positions, PnL, order books, and more. Websockets are ideal for trading UIs, dashboards, and agents that need low-latency access to what’s happening on Polymarket right now. Every metric stream is backed by the same pre-computed materialised rows the REST API serves, so push values are consistent with what you’d pull on demand.Endpoints
There are two websocket endpoints:| Endpoint | Purpose |
|---|---|
wss://api.struct.to/ws | Rooms: subscribe to data streams by topic (trades, prices, metrics). |
wss://api.struct.to/ws/alerts | Alerts: webhook-style events pushed over the same connection. |
Authentication
Authenticate by appending your API key as a query parameter:token parameter. See Authentication for both flows.
Your first connection
Create an account
Sign up at struct.to/dashboard and create an organisation.
Generate an API key
Open the API Keys page in your dashboard and create a new key. Copy the value somewhere safe; you won’t be able to view it again. See Authentication for key types, JWT public keys, and rotation.
Open a connection
Use any WebSocket client to connect. The example below connects, subscribes to the Trades room for a specific market, and logs messages as they arrive.
Connection lifecycle
A typical session follows the same sequence for every room:Message protocol
All messages sent and received are JSON. Client messages use atype and payload envelope:
Joining and subscribing
Subscribing to a room is a two-step flow:- Join the room with
join_room. - Configure the subscription by sending a
room_messagewithaction: "subscribe"and any filters.
subscribe message. The new filters replace the previous ones. Subscribe server-side rather than filter client-side: server-side filtering is free, while client-side filtering still bills you for the message.
Unsubscribing
To stop receiving messages from a room, sendunsubscribe_all followed by leave_room:
Keepalive
Send a ping every 30 seconds to keep the connection alive:{ "type": "pong" }, which you can safely ignore. The TypeScript SDK handles ping/pong automatically.
Available rooms
Every room emits its own event type with a typed filter and payload. Click a room for the full schema.| Room ID | Purpose | Required filter |
|---|---|---|
polymarket_trades | Trades, redemptions, merges, oracle lifecycle. | None |
polymarket_oracle_events | UMA oracle lifecycle (proposals, disputes, resolutions). | None |
polymarket_asset_prices | Raw Chainlink price ticks for crypto assets. | None |
polymarket_asset_window_updates | Open/close candle ticks for crypto assets. | None |
polymarket_market_metrics | Per-market volume, holders, traders, OI. | condition_ids |
polymarket_event_metrics | Aggregated event metrics. | event_slugs |
polymarket_position_metrics | Per-outcome volume and trader counts. | position_ids |
polymarket_tag_metrics | Aggregated metrics per tag. | tags |
polymarket_trader_pnl | Global, market, and event PnL for tracked traders. | traders |
polymarket_trader_positions | Open and closed positions per wallet. | traders |
polymarket_accounts | pUSD, USDC.e, and MATIC balance updates. | wallets |
polymarket_order_book | CLOB bid/ask updates. | None |
polymarket_clob_rewards | CLOB reward configuration changes. | None |
polymarket_events_stream | Periodic snapshots of event lists at a configurable interval. | None |
polymarket_markets_stream | Periodic snapshots of market lists at a configurable interval. | None |
polymarket_position_liquidity | Per-position USD order-book liquidity. | None |
polymarket_market_liquidity | Per-market total USD order-book liquidity. | None |
polymarket_event_liquidity | Per-event total USD order-book liquidity. | None |
Reconnection
Subscriptions live only for the lifetime of the connection. If the socket drops, you must reconnect and resubscribe. Use exponential backoff with jitter so transient outages don’t turn into thundering-herd reconnects.Connection limits
Each plan has a cap on concurrent connections across your organisation. A single connection can subscribe to many rooms, so you rarely need more than a handful of sockets in practice.| Plan | Concurrent connections |
|---|---|
| Free | 1 |
| Hobby | 50 |
| Startup | 250 |
| Scale | 1,000 |
| Enterprise | Unlimited |
Next steps
- Browse the Rooms section for every available stream and its filters.
- Review WebSocket Pricing for per-message rates.
- Check out Alerts for webhook-style events over the same protocol.
- Read Best Practices for cost and resilience patterns.