How to Track Polymarket UMA Disputes in Real Time with WebSockets
Track Polymarket UMA disputes as they happen. How the Optimistic Oracle works, what disputes look like in live data, and a Python WebSocket example.
A Polymarket market does not pay out when the game ends. It pays out when UMA's Optimistic Oracle settles it. Most of the time that is quiet and fast. But when someone disputes the proposed answer, the market does not resolve on time. Positions stay locked. The answer can flip.
If you run a bot, a dashboard or a trading desk, you want to know about a dispute in seconds, not hours later. This guide shows how.

What you will learn
How a Polymarket market moves through UMA's Optimistic Oracle
What disputes looked like in our live sample (about 97 hours of live frames, Oct 6–19, 2026)
How to stream proposals, disputes and settlements over a WebSocket
How to handle the pending-then-confirmed pair, de-duplicate, and alert
What you will need
Python 3.10 or newer, and
pip install websocketsA Bravado account on a paid plan, with a WebSockets API key that has the
stream.readscopeBRAVADO_API_KEYandBRAVADO_API_SECRETset in your server environment
How does Polymarket resolve a market with UMA?
Polymarket uses UMA's Optimistic Oracle. "Optimistic" means an answer is accepted unless someone challenges it. The flow has five steps.
1. Proposal
When the event ends, anyone can propose the outcome. The proposer posts a bond, typically $750 according to Polymarket's docs.
2. Challenge window
The proposal is then open to challenge. Polymarket's docs give a 2-hour challenge period. If no one disputes, the proposal is accepted and the market resolves.
3. Dispute
Anyone can dispute within the window by posting a counter-bond, typically the same $750. Per Polymarket's docs, the first dispute starts a new proposal round. If the second proposal is also disputed, the question escalates to UMA's DVM.
4. DVM vote
The DVM is UMA's token-holder vote. Polymarket's docs describe a 24–48 hour debate period, then about 48 hours of voting.
5. Settlement
The final answer is written on-chain. Winning shares become redeemable at $1. Losing shares go to $0.

Path | Steps | Typical time (Polymarket docs) |
|---|---|---|
No dispute | Propose → settle | ~2 hours |
One dispute | Propose → dispute → propose again → settle | One more proposal round |
Two disputes | Propose → dispute → propose → dispute → DVM vote → settle | 4–6 days |
Why do UMA disputes matter to traders and bots?
A dispute changes three things.
Timing. The market will not settle at the end of the expected window. Capital stays locked.
Outcome risk. The next proposal can carry a different answer. In one market in our sample the answer flipped from yes to no.
Your data model. An event that has visibly ended is not the same as a settled market. Wait for the
settledframe before treating a position as realized.
If you show balances, book PnL or quote prices near resolution, you need dispute events as they happen.
What did disputes look like in our sample?
We streamed Bravado's /uma/ws feed and kept every live frame. The sample is about 97 hours of live frames between Oct 6 and Oct 19, 2026. Every number below is from that sample. Treat the numbers as a snapshot, not a census.
1. Disputes are rare
In our sample | Count |
|---|---|
Questions with a proposal | 94,728 |
Questions with a dispute | 151 |
Questions settled | 91,497 |
Dispute frames (pending + confirmed) | 260 |
That is about 0.16% of proposed questions. But one event skews it. On Oct 18, 90 markets on a single football match, FK Polissia vs. FK Dynamo Kyiv, were disputed within about 10 minutes. Leave that match out and 61 questions were disputed, about 0.06%, or roughly 1 in 1,550.
So disputes are rare, and they come in bursts. One bad proposal batch can put dozens of markets on hold at once.
2. Most disputes are on sports markets

Category | Proposed questions | Disputed questions | Share disputed |
|---|---|---|---|
Sports | 82,764 | 138 (48 without the Polissia match) | 0.17% (0.06%) |
Weather | 2,626 | 1 | 0.04% |
Crypto | 2,803 | 1 | 0.04% |
Politics | 894 | 1 | 0.11% |
Other | 5,641 | 10 | 0.18% |
Sports dominates because sports dominates proposals. 87% of proposed questions in our sample were sports. Even without the Polissia match, 48 of the remaining 61 disputes were sports. Categories are our own grouping by market title, so treat the small rows as rough.
Real examples from our sample:
KBO: Doosan Bears vs. Samsung Lions. Proposed "yes", disputed, re-proposed "no", settled "no".
Paolini vs. Spasov: Match O/U 23.5 and O/U 22.5. Two lines on the same match were disputed together.
FK Polissia vs. FK Dynamo Kyiv. 90 markets on one match were disputed between 9:48 and 9:59 AM ET on Oct 18: exact scores, spreads, over/unders and "Will FK Polissia win on 2026-10-18?".
Soccer player props, such as "Wil Trapp: 1+ assists" and "Albert Rusnák: 1+ assists". A batch was disputed within minutes on Oct 11.
Will Party U win the second-most seats in the 2026 Israeli legislative election?
Saudi Arabia military action against Yemen on September 20? Disputed on Oct 19.
Disputes cluster. When one line on a match is wrong, the sibling lines often are too. Group alerts by match so one event does not send you 90 separate messages.
3. Disputes usually come early in the window

We measured the time from a confirmed proposal to a confirmed dispute where we saw both (37 disputes in our sample).
In our sample | Value |
|---|---|
Disputes within 2 hours of the proposal | 27 |
Median time to dispute (those 27) | about 19 minutes |
Disputed within 10 minutes | 12 of 27 |
The other 10 came more than 2 hours after the proposal.¹ So a 2-hour timer is not a safe "no dispute is coming" signal. Wait for the settled frame.
4. Most undisputed markets settle in about 2 hours, but not all

For 55,118 undisputed questions in our sample, we saw both the confirmed proposal and the settlement.
Settled after the proposal (in our sample) | Questions | Median |
|---|---|---|
Under 90 minutes | 25,926 (47%) | 21 minutes |
90–135 minutes | 28,734 (52%) | 121 minutes |
Over 135 minutes | 458 (1%) | n/a |
There are two clear groups. One settles right after the 2-hour default. The other settles about 15–55 minutes after the proposal.² Do not hard-code 2 hours. Let the stream tell you.
5. The mempool gives you a head start
In our sample, many proposals and disputes arrived twice: first with "seen_pending": true and block: 0, then again with a real block once mined.
In our sample | Value |
|---|---|
Disputes first seen as pending | 103 of 151 |
Pending-to-confirmed lead (median) | about 1.2 seconds |
Pending-to-confirmed lead (middle half) | 0.6–1.7 seconds |
A second is small. It matters if you need to pull quotes before a dispute is on-chain.
How do you stream UMA disputes with a WebSocket?
1. Know the frame
Every message on /uma/ws is a uma frame. Bravado's docs list these fields:
Field | Meaning |
|---|---|
|
|
|
|
| UMA adapter question id, the stable key for a resolution |
| CTF condition id, to join with positions and trades |
| Addresses |
| Exact int256 price, hex |
| Micro-USDC string, on settlement |
| Oracle request time, unix seconds |
| Market question |
| On-chain location. |
|
|
Here is a real pending dispute frame from our sample (trimmed):
The confirmed frame followed 1.6 seconds later with the real block, the same tx, and "answer": "no". The answer on a pending frame can read other. Use the confirmed frame's answer.
2. Authenticate
The upgrade is signed with HMAC-SHA256. Sign timestamp, GET, /uma/ws and the SHA-256 of an empty body, joined by newlines. Send three headers: X-BRAVADO-API-KEY, X-BRAVADO-TIMESTAMP (unix ms) and X-BRAVADO-SIGNATURE. Make a new signature on every reconnect. Our listener sends no subscribe message; frames arrive after the signed upgrade.
3. Filter, pair, de-duplicate and alert
What the code does:
Filters to
stage == "disputed". Change the filter to watch proposals or settlements too.Pairs the pending and confirmed frames. They share
question_idandtx. You get one early alert and one confirmation.De-duplicates on
(question_id, tx, seen_pending). A re-proposal and a second dispute on the same question have a newtx, so they alert again. That is what you want: a second dispute means a DVM vote.Reconnects with a new signature each time.
4. Plan for reconnects
Any long-lived WebSocket can drop. Reconnect with backoff and a fresh signature, as the example does. Your client can miss frames while it is disconnected. To reduce that, you can run two connections and de-duplicate by seq. To check what you missed after a drop, query the REST endpoint GET /uma/recent?stage=disputed.
5. Follow one market
To follow a single market, filter on question_id or condition_id on your side. To check a market's full state at any time, call GET /uma/question?id=<question_id> or GET /uma/market?condition_id=<condition_id>.
Why use Bravado's UMA API and WebSocket?
You can read UMA events from the chain yourself. Then you need to index the oracle and adapter contracts, decode the ProposePrice, DisputePrice and Settle logs, classify the int256 price, and map each question back to a market.
Bravado's UMA API does that work for you:
One stream for the lifecycle. In our sample it carried 94,728 proposed, 151 disputed and 91,497 settled questions.
Decoded answers.
answeris alreadyyes,no,50-50,too-earlyorother.price_rawkeeps the exact value.Mempool head start. In our sample, 103 of 151 disputes arrived first with
seen_pending: true, a median 1.2 seconds before the confirmed frame.Joinable ids.
condition_idmatches the rest of Bravado's market data.REST for state.
GET /uma/question,GET /uma/marketandGET /uma/recent.
UMA access needs a paid plan. The Free plan cannot access UMA. The stream costs 0.75 credit per delivered UMA data message under unified billing. Heartbeats, errors and idle time are not billed. Pending and confirmed updates count as separate messages. A REST read costs 1 credit. See the UMA API docs and API credits.
Conclusion
Disputes are rare. In our sample about 0.16% of proposed questions were disputed, and well over half of those came from one match. When it happens, it delays resolution and can change the answer. The fix is simple. Stream every UMA frame, filter for disputed, pair the pending and confirmed frames, and alert. Never assume a market is final until you see settled.
Next steps:
Building a general Polymarket stream? Read our Polymarket WebSocket guide.
Booking PnL on resolved markets? Read how to calculate Polymarket PnL.
Ready to build? Start with the UMA API docs.
Notes
¹ Ten disputes in our sample came 2 to 11 hours after the proposal, for example a batch of soccer player props on Oct 11. Polymarket's docs give a 2-hour challenge period, and a dispute can only land inside it. These requests most likely had a longer challenge window. UMA's docs say each request can set its own. The frame does not carry the liveness value, so we could not confirm it. We left these 10 out of the median.
² About 47% of undisputed questions in our sample settled 15–55 minutes after the proposal. A shorter challenge window on those requests is the likely reason, but the frame does not carry the liveness value, so we report this group separately and do not guess the setting. All timings use the send timestamps (ts_sent) of the confirmed frames.
Read more blogs
Trading insights, market analysis, and strategies for Polymarket prediction markets.





