Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.struct.to/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Struct’s websocket API lets you stream real-time Polymarket data directly to your application without polling the REST API. 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.

Endpoints

There are two websocket endpoints available:
EndpointPurpose
wss://api.struct.to/wsRooms: subscribe to data streams by topic (trades, prices, metrics, etc.)
wss://api.struct.to/ws/alertsAlerts: receive webhook-style events pushed over the same connection
This guide covers the Rooms endpoint. See Alerts for the alerts endpoint.

Authentication

Authenticate by appending your API key as a query parameter:
wss://api.struct.to/ws?api-key=YOUR_API_KEY
Your API key is scoped to your organisation and inherits its plan’s connection cap, credit allowance, and rate limits.

Your First Connection

1

Create an account

Sign up at struct.to/dashboard and create an organisation.
2

Generate an API key

Navigate to the API Keys section in your dashboard and create a new key.
3

Open a connection

Use any WebSocket client to connect. Below is a JavaScript example that connects, subscribes to the Trades room for a specific market, and logs messages as they arrive.
const ws = new WebSocket("wss://api.struct.to/ws?api-key=YOUR_API_KEY");

ws.onopen = () => {
  ws.send(
    JSON.stringify({
      type: "join_room",
      payload: { room_id: "polymarket_trades" },
    }),
  );

  ws.send(
    JSON.stringify({
      type: "room_message",
      payload: {
        room_id: "polymarket_trades",
        message: {
          action: "subscribe",
          condition_ids: ["0xabc..."],
        },
      },
    }),
  );
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log(msg.type, msg.message);
};
4

Receive events

Messages arrive as JSON with a type field (the event name) and a message payload. See the individual room pages for the events each room emits.

Message Protocol

All messages sent and received are JSON. Client messages use a type and payload envelope:
{
	"type": "join_room",
	"payload": { "room_id": "polymarket_trades" }
}

Joining and Subscribing

Subscribing to a room is a two-step flow:
  1. Join the room with join_room.
  2. Configure the subscription by sending a room_message with an action: "subscribe" payload and any filters.
{
	"type": "room_message",
	"payload": {
		"room_id": "polymarket_trades",
		"message": {
			"action": "subscribe",
			"condition_ids": ["0xabc..."],
			"market_slugs": ["will-x-happen"]
		}
	}
}
You can update a subscription’s filters at any time by sending another subscribe message. The new filters replace the previous ones.

Unsubscribing

To stop receiving messages from a room, send unsubscribe_all followed by leave_room:
{
	"type": "room_message",
	"payload": {
		"room_id": "polymarket_trades",
		"message": { "action": "unsubscribe_all" }
	}
}
{
	"type": "leave_room",
	"payload": { "room_id": "polymarket_trades" }
}

Keepalive

Send a ping every 30 seconds to keep the connection alive:
{ "type": "ping" }
The server will respond with { "type": "pong" }, which you can safely ignore.

Connection Limits

Each plan has a cap on the number of concurrent websocket connections your organisation can have open at once:
PlanConcurrent connections
Free1
Hobby50
Startup250
Scale1,000
EnterpriseUnlimited
A single connection can subscribe to multiple rooms, so you rarely need more than a handful of connections in practice.

Next Steps

  • Browse the Rooms section to see every available stream and its filters.
  • Review Pricing to understand how websocket usage is billed.
  • Check out Alerts if you want webhook-style events over a websocket instead of HTTP POSTs.
Last modified on April 13, 2026