Market maker
Stream Quote Requests
Subscribe to all active quote requests in real time via Server-Sent Events.
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.
Sent immediately on connection. Confirms your identity.
Sent at the start of the initial snapshot (on new connection or reconnect). All currently active quote requests follow before
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.
Sent when a request you have already seen changes to a new
Sent when the initial snapshot is finished. After this, the stream switches to incremental updates only.
Sent when a previously seen quote request is no longer active. Remove it from your local state. The
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
Every field above is always present. For the full auction mechanics, see
Early cashout.
The taker-fee rate is read once per connection (server-side), so
Authentication
API key required. Pass your market maker API key in theX-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.
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.
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.Reconnection
Every SSE event includes anid: 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.
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_stakeis the net stake the MM underwrites:user_stake = bet_amount − taker_fee, wheretaker_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 anduser_stake24.75. Pricepayout_oddsand size collateral againstuser_stake, notbet_amount.bet_amountstays 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 asquote_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 updatedversionandrequest_hash; you don’t need to withdraw the old one.
