wss://partner-api.bravadotrade.com/stream/polymarket/partner and subscribe to open_orders:all to receive a live, normalized view of one user’s own open Polymarket orders. Bravado maintains the authoritative state for you — an initial REST snapshot merged under Polymarket’s user WebSocket, reconciled automatically after any disconnect — so you integrate against one stream instead of Polymarket’s REST and WebSocket, their auth, their heartbeats and their reconnect logic.
This is private, account-level data. Where the Live Trades and Order Books feeds are market-wide, this one is per-user: the request must resolve to one bound user — see Authentication. It is part of the Market Data product (
stream.read scope), and Bravado’s own client never sees the user’s Polymarket credentials.Authentication
The upgrade is signed with the same HMAC-SHA256 scheme as every other partner request —X-BRAVADO-API-KEY, X-BRAVADO-TIMESTAMP and X-BRAVADO-SIGNATURE over the canonical path, hashing the empty body of the bodyless GET. See Authentication for the signing rules.
Because the channel is per-user, the request must resolve to one bound user:
- A per-user key carries its binding — nothing more is needed.
- A master key must name the user with an
X-Partner-User-Idheader (thepartner_user_idyou provisioned the user under). This header is not part of the signed payload; it travels alongside the signed headers.
BINDING_REQUIRED error and does not open a session. (The public book channel on the same door needs no user and is unaffected.)
Connect
Sign the bare partner-door path, passX-Partner-User-Id for a master key, then subscribe in-band once the socket is open. (You may instead pass ?streams=open_orders:all on the URL; if you do, sign the path with that query.)
all — every open order for the account. Market, asset and side filters are a later addition; the open_orders:<…> namespace is reserved for them. open_orders is not an asset and holds no quota, so it does not count against the per-organisation asset limit — a book subscription and open_orders can share one socket.
Frames
Every frame carrieschannel: "open_orders", venue, seq (ours, monotonic per session — a snapshot resets it) and ts (our clock, in milliseconds). Sizes and prices are exact decimal strings, never JSON numbers — parse them with a decimal-safe type, not a float.
An order is removed from active state once its
order_closed frame is emitted.
snapshot
order_opened / order_updated
order_closed
reconciled
The normalized order
Status model
The normalizedstatus moves OPEN → PARTIALLY_FILLED → (FILLED | CANCELLED | EXPIRED) and is derived from sizes (filled_size against original_size), never from a venue string — a cancellation event is what sets CANCELLED. The raw venue status always rides along in venue_status, so an unrecognized venue status never silently changes the normalized one, and no venue information is lost.
Polymarket’s own order statuses are
live / matched / delayed / unmatched (the last two are sports matching-delay states), spelled both bare (LIVE) and prefixed (ORDER_STATUS_LIVE), case varying — all of which you receive verbatim in venue_status. delayed and unmatched are reported as a size-derived OPEN (an unmatched order is resting on the book, so it is open — we do not guess it cancelled).size_matched_final
On order_closed, this flags whether filled_size is the final, event-confirmed value. An event-driven close carries true. A close inferred by reconcile — an order that vanished from a fresh snapshot while the upstream was disconnected — carries false, because filled_size is the last value we saw and may be stale. Unknown is labelled, never guessed as zero.
Reconnect and reconcile
The upstream Polymarket connection is managed for you. On an upstream drop the session emits oneerror with code: "UPSTREAM_DISCONNECTED" (your downstream socket stays open), reconnects with jittered backoff, re-fetches the REST snapshot to completeness, diffs it against local state, emits the resulting order_opened / order_updated / order_closed frames, and closes with one reconciled summary.
A periodic reconcile — and a verify reconcile shortly after a subscription goes live — runs even on a healthy connection and always emits reconciled. So a client that stops seeing reconciled frames knows its data may be stale.
Reconnect and resubscribe if your own socket drops; you will receive a fresh snapshot. The server pings and closes a connection after missed pings; most WebSocket clients answer automatically.
Error codes
Error frames carry only{ code, message } and never expose Polymarket credentials or raw upstream errors.
Coverage
Polymarket only. Predict.fun publishes no order feed of this shape, soopen_orders is absent from the Predict.fun channel table and a subscription there answers UNKNOWN_STREAM.
Guarantees
- No Polymarket credential ever reaches you or a log — the wire shape has no credential field, and upstream identity fields (
owner,maker_address) are dropped. - No double-counting of fills —
filled_sizeis the venue’s authoritative cumulative; trade events refine fill tracking but never move it. - No leak onto a market-wide route —
open_orderslives only in the authenticated partner door’s per-user channel table; no public or market-wide route can address it.
Related
- Market Data overview.
- Authentication — the HMAC signing rules and master vs. user keys.
- Trade API — place and cancel the orders you are watching.
- Order Books WebSocket, live depth on the same door.