Skip to main content

Connection

Open a WebSocket connection to the gateway and authenticate with your Falcon API token as a Bearer credential. Your token is verified at the connection upgrade, so only authenticated clients stream.
WebSocket URL
HTTP Header (sent on the upgrade request)
Connect from your backendStream from a server-side client (Node, Python, Go) and send your token in the Authorization header — the standard setup for production streaming. Keep your API token server-side. See Authentication for how to obtain a token.

Event types

Every stream is identified by an event type. Today polymarket.trade is live, the first of more to come. Access to each type is governed by your plan. Call GET /event-types for the catalog you’re authorized for — it returns each type’s field schema, including a per-field filterable flag that tells you exactly which fields you can filter on.
cURL
200 Response (abridged)
Abridged — schema.fields lists all 24 fields of polymarket.trade. See Event messages for the full payload.

Subscribe

Once connected, send a subscribe frame. Each frame can open multiple subscriptions at once — pass one entry per stream in the subscriptions array. Omit filters (or pass {}) to receive every event of that type.

Subscribe to all trades

JSON client to server

Subscribe to one market

JSON client to server
The server replies with a subscribed acknowledgement listing the event types it granted and a unique id for each subscription. Keep each id — you need it to unsubscribe. The filters you sent are echoed back when present.
JSON server to client
Control messages vs. eventsAcknowledgements, errors, and notices carry an action field (subscribed, error, rate_limit, …). Data events instead carry a type and a data object. Branch on whichever field is present. Mixed frames are handled gracefully — the acknowledgement grants every type your plan includes, so the rest of the subscription always goes through.

Filters

Filters are matched server-side. Only the filterable fields below are accepted — pass any combination as key/value pairs inside filters. To track multiple wallets or markets at once, open one subscription per target (each with its own id). Filterable fields: proxy_wallet, slug, condition_id, event_slug, outcome, outcome_index, side, asset, maker, taker, transaction_hash, order_hash. GET /event-types is the authoritative source for which fields are filterable on each event type. To follow several wallets or markets, open one subscription per target — each gets its own id for independent unsubscribe.

Build a Subscription

Pick your filters and copy the generated subscribe frame — or a ready-to-run Node or Python client — straight into your app.

Event messages

Each event is a JSON frame carrying the event type, its source, the delivery timestamp, and a data object with the trade. Here is a live polymarket.trade event (long hashes abbreviated):
JSON server to client

Filterable fields

The fields you can filter on (from /event-types). Every event also carries the additional non-filterable fields shown in the payload above.

Unsubscribe

Stop one or more streams by sending an unsubscribe frame with the subscription_ids returned when you subscribed. The server confirms with an unsubscribed acknowledgement.
JSON client to server
JSON server to client

Connection lifecycle

Heartbeat

Connections are kept healthy by a built-in ping/pong heartbeat. Most WebSocket libraries respond to pings automatically, so there’s nothing to implement — your stream stays alive as long as your client is connected.

Reconnection

Connections are long-lived. For a resilient client, reconnect automatically with exponential backoff and re-send your subscribe frames once reconnected — the standard pattern for any streaming integration. A close with code 4001 is simply a cue to reconnect to a fresh upstream feed, and deploys roll out with graceful connection draining so reconnects stay clean. You can confirm gateway health any time with GET /health (returns 200 OK).

Rate limits and quotas

Streaming allowances depend on your plan. The gateway enforces limits in-band so your client always knows what happened.
  • Active subscriptions — Your plan caps how many concurrent subscriptions you can hold on one connection.
  • Message rate — If you exceed your delivery quota, the server sends a rate_limit frame and may pause delivery until the window resets.
  • Subscribe in one frame — Batch multiple streams in a single subscribe message; each entry counts toward your subscription limit.
  • One connection is all you need — Multiplex every stream on a single WebSocket instead of opening many connections.
JSON server to client
Scale up any timeNeed higher subscription or message limits? Upgrade your plan from the Falcon dashboard.

Errors and notices

The gateway always answers — any protocol issue comes back as a clear, in-band error message that names the relevant types and a human-readable message, so your client knows exactly what to do. For example, requesting a type your plan doesn’t include yet:
JSON server to client
Filtering on a non-filterable field:
JSON server to client
Authentication is checked at the connection upgrade with a standard 401, so only valid tokens stream.

Node.js (ws)

Node.js

Python (websockets)

Python

Need more streams?

More event types are on the way. To request early access or a dedicated event type, reach us at contact@heisenberg.so.