Skip to main content
Bid on the auction Totalis opens when a user leaves a parlay early. The bettor’s side is on Early cashout.

At a glance

  • A user can leave a live parlay early. Totalis opens an auction of about 10 seconds and broadcasts it to every maker on the stream you already consume.
  • You bid one all-in price. The highest live bid wins, and ties go to the earliest bid.
  • If the maker who backs the position wins, the position closes and the parlay shows as bought back.
  • If any other maker wins, the position transfers to them and stays open. The buyer gets no event today.
Every *_micro field is an integer of microUSDC (1000000 is 1.00 USDC). The money fields beside them (user_stake, mm_risk, total_payout, and the amount on the settlement event) are decimal USDC. payout_odds is a multiplier, not an amount. Both conventions appear in the same payload, so scale before you compare. See Glossary.

The two outcomes

An auction resolves one of two ways. The seller is paid the same either way. Your integration handles the two very differently. Your position goes to a ten second auction; the highest all-in bid wins and either closes the position or transfers it Your position goes to a ten second auction; the highest all-in bid wins and either closes the position or transfers it
Do not wait on bought_back to detect a win. If you bid on positions you do not already back, a win transfers the position to you and emits no event to you. Reconcile acquisitions from GET /v1/rfqs: an acquired position moves to your account as the bettor side.

How it works

1

Receive the auction

A cashout_request event arrives on GET /v1/mm/quote-requests/stream. It carries the position’s legs and economics.Auctions are broadcast, so you see exits on positions you have no relationship with.
2

Price the exit

Re-value the parlay at current odds, and read legs[].resolution carefully.
void beats everything. Any void leg cancels the whole position at settlement and refunds the stake, so the position is worth about the stake even if a sibling leg already resolved lost. With no void leg, one lost leg makes the parlay worthless.Nothing stops an auction opening on a position whose legs are already decided. resolution is your only defense.
3

Bid one all-in price

PUT your bid to /v1/mm/cashout-requests/{id}/quote before expires_at. price_micro is what the user receives, all-in.
4

Reconcile the outcome

If you win as the counterparty, you receive position:bought_back. If you win as anyone else, you acquire the position and receive no event. See Knowing you won.

The auction

price_micro is a single all-in figure. There is no direction field, no separate fee term, and no gross versus net. What you send is what the user sees on screen and walks away with. It can be below their stake. A losing parlay exits for less than it cost, and the user never pays more than their stake to leave. A bid may outlive the auction. Nothing tells you that your bid lost or lapsed, or that the auction closed, so age bids out locally against expires_at.
Your bid being best does not guarantee a fill. The user is only ever filled at a price they explicitly accepted. If the book moves down between their tap and their commit, the commit fails and nobody trades.

Knowing you won

There is no per-auction result event on the MM stream. A bought-back parlay reports a realized cashout P&L, not a win or loss. The exit is a real settlement, not a refund.

Errors

Every rejection reason for a cashout bid, including the commit-time ones you never see as an HTTP response, is on Errors.

Checklist

1

Handle the push

Handle cashout_request on the MM stream, and reconnect with last_event_id. With a 10 second lifetime, a reconnect gap means lost auctions.
2

Price from the payload

Price from legs, user_stake, and total_payout, respecting legs[].resolution. Those amounts are decimal USDC. Your bid is microUSDC.
3

Decide which lane you are in

Match the auction’s position_id against the position_id on GET /v1/mm/positions. A hit means you back the position and a win closes it. No hit means a win acquires it. Both ids are lowercase hex with no 0x, so they compare directly.
4

Bid and expire locally

Bid before expires_at, and age your own bids out locally. Keep free balance ahead of outstanding bids.
5

Split your alerting

Alert on 400, 401, and 403. Log 404 and race class 409 quietly.
6

Reconcile wins

Take closing wins from position:bought_back. Take acquisitions from GET /v1/rfqs, because nothing will tell you.