Skip to main content
A persistent WebSocket connection that pushes every new tier=logical and tier=endgame opportunity at the exact moment the arb engine detects it — typically within 100ms of the underlying price/book event that triggered it.
Plus tier and above only. Free and Pro stay on REST polling (GET /v1/arb/live). This is the headline Plus differentiator — no quota burn, no missed signals.

Endpoint

Query parameters

WebSockets can’t carry custom Authorization headers reliably across proxies, so auth is via query param. Use HTTPS-equivalent transport security (this URL is TLS — never ws://).

Message types

Every message is a single JSON object with a type discriminator.

ready (sent once, on connect)

opportunity (zero or many — pushed as they fire)

Same shape as items in the opportunities array from GET /v1/arb/live, with a type: "opportunity" field added. The tier field is the actionable filter — only "logical" or "endgame" are pushed; "stable" / "stale" rows are kept off the push channel by design (they’re not tradable signals).

ping (every 25s if no opportunities)

Sent so a long-idle connection doesn’t get killed by intermediaries. Clients can ignore the body — receiving any message is enough proof of liveness. No client pong required.

Minimal Python client

Reconnect handling

Networks die. Add a backoff loop so a transient drop doesn’t lose you signals for the rest of the day:

What you don’t get

  • No historical replay. Connect = subscribe from now. If you disconnect for 5 minutes and reconnect, any signals fired during the gap are lost. Use GET /v1/arb/audit?window=24h to backfill if needed for analysis (note: settled-only, not real-time).
  • No order submission. PolyQuantLab is a research / signal API; execution stays on Polymarket. Pipe the message into your py-clob-client loop — see Auto-trade logical arbs.
  • No stable / stale rows. Those have ~0 expected edge after fees; surfacing them on the push channel would just waste your socket bandwidth and tempt bad trades. They remain available via REST GET /v1/arb/live.

Comparison vs REST polling