Skip to main content
GET
Open a Server-Sent Events (SSE) stream to receive all active quote requests in real time. This is the primary integration path for market makers — use it instead of polling. The stream emits new requests as they arrive, updates when requests change, and notifies when requests expire.

Authentication

API key required. Pass your market maker API key in the X-API-Key header.

SSE event types

This stream sends seven event names. Their spelling isn’t consistent: quote_request and quote_request_expired are underscore-separated, while quote_request:updated is colon-separated. The subsections below — and their <Warning>s — cover why:

connected

Sent immediately on connection. Confirms your identity.

snapshot_begin

Sent at the start of the initial snapshot (on new connection or reconnect). All currently active quote requests follow before snapshot_complete.

quote_request

Sent when a new quote request is created, and once for each active request replayed during the initial snapshot. This is the primary event you price against.

quote_request:updated

Sent when a request you have already seen changes to a new version — the user edited the legs or the bet amount. The payload is identical to quote_request (with the incremented version and new request_hash). Any quote you submitted for the prior version is automatically invalidated; re-price and submit a new quote against the new version and request_hash. You do not need to withdraw the prior quote — it never blocks the new submission.
This is a distinct event name from quote_request. If your client only registers a listener for quote_request, it will miss every version bump. Register a listener for quote_request:updated as well (or, with a raw SSE parser, branch on the event: field).

snapshot_complete

Sent when the initial snapshot is finished. After this, the stream switches to incremental updates only.

quote_request_expired

Sent when a previously seen quote request is no longer active. Remove it from your local state. The reason field tells you why it closed, and lets you distinguish a lost auction from an abandoned or timed-out one: won is true only when reason is committed and your quote was the one selected; otherwise false (including every cancelled/expired close). A committed close with won: false means you were out-bid — the user took another market maker’s quote. The winning maker’s identity and odds are never disclosed. won is omitted on the rare committed close where the outcome is indeterminate (e.g. the event was produced by a previous server instance during a deploy). Treat an absent won as unknown — don’t record it as a loss.

cashout_request

Sent when a user opens an early cashout auction on a position, and once for each active auction replayed during the initial snapshot. These arrive on the same stream and are broadcast to every market maker — including positions you do not back. Bid with PUT /v1/mm/cashout-requests/{id}/quote. To pass, submit nothing; there is no decline endpoint. The auction lives about 10 seconds — see Early cashout.
This is a distinct event name from quote_request, with a different payload — it carries cashout_request_id (not id) and the on-chain position_id. Branch on the SSE event: field (or register a dedicated cashout_request listener) to tell a cashout auction apart from a forward quote request.
string
required
The auction id. Pass it as {id} when you bid. Note the name: this payload has no id field, unlike quote_request.
string
required
The on-chain position id (32 hex chars, no 0x). Use it to look the position up in your own book and decide whether you are its counterparty — that determines your economics.
array
required
The position’s legs. Each carries id, event_ticker, market_ticker, side (yes / no), venue, and resolution.resolution is one of unresolved, won, lost, void, and it is your only protection against pricing an already-decided parlay. void overrides the others: any void leg cancels the whole position at settlement and refunds the stake, so the position is worth roughly user_stake even when a sibling leg reads lost. Absent a void leg, one lost leg makes the parlay worthless.
number
required
Decimal USDC. The net stake the counterparty underwrites (bet_amount − taker_fee) — the same quantity as on quote_request, and the reference point for the exit price: a bid above it means the user leaves in profit, below it at a loss.
number
required
Decimal USDC. The counterparty’s locked risk on the position. Pricing context only — do not compute the counterparty bid ceiling from it. The server derives that ceiling from total_payout − user_stake; the two are stored separately and can disagree in the last decimal.
number
required
Decimal USDC. What the position pays if every leg wins, and the hard ceiling on any bid: price_micro <= round(total_payout * 1e6), or the bid is rejected price_above_max_payout.
number
required
The accepted quote’s payout multiplier — pricing context, not an amount and never a bid term. For auctions on positions created before this field was carried it is reconstructed from total_payout / user_stake and can be off in the 5th or 6th decimal, so do not reconcile against it exactly.
integer
required
The auction’s version, 1 today. A cash-out auction is never re-versioned mid-flight the way a forward quote request can be, so there is no cashout_request:updated event to handle.
string
required
ISO 8601 close time of the auction, about 10 s out. Bid before it. This is not the position’s market-end horizon, which is not on this payload — so you cannot pre-filter for the near-close cutoff, and a bid on a position close to its market end is rejected MARKET_NEAR_CLOSE. Treat that as an ordinary lost auction.
Every field above is always present. For the full auction mechanics, see Early cashout.

Reconnection

Every SSE event includes an id: field. Persist this value. On reconnect, pass it as the last_event_id query parameter to replay any events you missed instead of receiving the full snapshot again.
The taker-fee rate is read once per connection (server-side), so user_stake on a long-lived stream reflects the rate in effect when you connected. If the fee rate changes, reconnect to pick up user_stake values computed at the new rate.

Notes

  • Net stake. user_stake is the net stake the MM underwrites: user_stake = bet_amount − taker_fee, where taker_fee = floor(bet_amount_micro × taker_fee_bps / 10000) is computed in integer microUSDC (1 USDC = 1e6 micro) — e.g. a 25.00 bet at 100 bps gives a 0.25 fee and user_stake 24.75. Price payout_odds and size collateral against user_stake, not bet_amount. bet_amount stays the user’s gross wager but is not the quoting base when the taker fee is on (taker_fee_bps > 0); when the fee is off, user_stake == bet_amount.
  • The stream automatically excludes quote requests created by your own user account.
  • A version change arrives as quote_request:updated (a new request arrives as quote_request). Your prior version quote is invalidated automatically — it leaves the book immediately and never blocks a new quote. Re-price and submit a new quote with the updated version and request_hash; you don’t need to withdraw the old one.

Errors