Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions content/en/api-reference/sportsbooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ The `requires_tier` field indicates the minimum subscription tier needed to acce

<Callout type="info">
**Polymarket** and **Kalshi** are prediction market platforms. Unlike traditional sportsbooks, they use binary outcome contracts priced between $0 and $1. SharpAPI normalizes contract prices into standard odds formats (American, decimal, implied probability) so you can compare them directly with sportsbook odds. Kalshi is CFTC-regulated.

Polymarket rows additionally carry a `polymarketResolution` field reflecting the upstream UMA optimistic-oracle lifecycle (`settled_normal` / `voided` / `disputed` / `proposed` / `unknown`). See [Polymarket Resolution](/concepts/polymarket-resolution) for the per-value semantics and the upstream caveat that cancellation, participant withdrawal, and event-not-occurred all collapse to the single `voided` bucket.
</Callout>

## Sharp vs Soft Books
Expand Down
1 change: 1 addition & 0 deletions content/en/concepts/_meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export default {
"event-matching": "Event Matching",
"live-vs-prematch": "Live vs. Pre-Match",
"pinnacle-odds-changed-at": "Pinnacle `odds_changed_at`",
"polymarket-resolution": "Polymarket Resolution",
}
98 changes: 98 additions & 0 deletions content/en/concepts/polymarket-resolution.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: "Polymarket Resolution Status"
description: "How SharpAPI surfaces the upstream UMA optimistic-oracle resolution lifecycle on Polymarket markets — settled, voided, disputed, proposed."
---

import { Callout } from 'nextra/components'

# Polymarket Resolution Status

Polymarket is a prediction-market CLOB whose markets are graded by the [UMA optimistic oracle](https://docs.uma.xyz/), not by a sportsbook trading desk. When you read Polymarket odds through SharpAPI, the row may carry an extra field — `polymarketResolution` — that reflects where that market sits in the UMA resolution lifecycle.

This field is **Polymarket-only**. Other sportsbook rows (Pinnacle, DraftKings, FanDuel, etc.) do not carry it because their upstream wire formats don't emit an equivalent signal. See [Pinnacle wire survey](https://github.com/Mlaz-code/api-adapters/) for the parallel investigation that concluded the same field cannot be delivered for traditional books.

## When the field appears

| Market state | `polymarketResolution` |
|---|---|
| Actively trading | omitted (field not present) |
| Closed, resolved with a winner | `"settled_normal"` |
| Closed, voided / refunded | `"voided"` |
| Closed, UMA dispute in flight | `"disputed"` |
| Closed, UMA proposal submitted, dispute window open | `"proposed"` |
| Closed, lifecycle fields empty (legacy market) | `"unknown"` |
| Any non-Polymarket book | omitted |

The field is **additive**. Existing parsers that ignore unknown fields will continue to work unchanged.

## Value semantics

### `settled_normal`

The UMA oracle declared a winning outcome. In a binary market, exactly one outcome resolved to `$1.00` and the other to `$0.00`. This is the typical end state.

```json
{
"sportsbook": "polymarket",
"marketType": "binary",
"selection": "Yes",
"odds": -10000,
"polymarketResolution": "settled_normal",
"trueProbability": 1.0
}
```

### `voided`

The UMA oracle voided the market — both binary outcomes resolved to `$0.50` ("refund everyone"). This is the same wire signature for all of:

- A cancelled match (sporting event cancelled or abandoned)
- A participant withdrawing before the event
- The event never occurring (e.g. "Map 3 winner" when the series ended in 2 maps)
- Any other UMA-determined void

<Callout type="warning">
**Polymarket does not distinguish *why* a market was voided.** The human-readable reason lives in the off-chain UMA dispute thread on the UMA oracle frontend, not in the Polymarket API. If your application needs to know cancellation-vs-withdrawal-vs-no-event, that information cannot be sourced from Polymarket's wire — you would need to read the UMA dispute body directly.

This is an intentional design choice from UMA's optimistic-oracle architecture, not a SharpAPI omission. We chose to expose `voided` as a single bucket rather than guess from heuristics — per our [no-inference policy](https://github.com/Mlaz-code/api-adapters/), if upstream is ambiguous, we don't make a guess.
</Callout>

### `disputed`

The UMA proposer submitted a resolution that was challenged. The market is now in a UMA token-holder vote, typically 48 hours. The terminal resolution will eventually become `settled_normal` or `voided` once the vote concludes.

### `proposed`

The UMA proposer submitted a candidate resolution; the dispute window is open (typically 2 hours). The market will transition to `settled_normal` / `voided` once the window closes uncontested, or to `disputed` if challenged.

### `unknown`

The market is closed but the UMA lifecycle fields are empty. This happens on legacy Polymarket markets that pre-date UMA-status tracking, or on rare edge cases where the Gamma API doesn't surface lifecycle history. The field is `unknown` rather than guessing.

## Delayed resolution

Polymarket markets can resolve days or weeks after the underlying event ends. The `polymarketResolution` field appears whenever the upstream resolution lifecycle advances, even long after the market closed.

If your application processes resolution events (for grading, settlement reconciliation, etc.), watch the SSE stream / WebSocket for these late-arriving rows.

## Comparison with other books

| Book | Equivalent field? | Notes |
|---|---|---|
| **Polymarket** | `polymarketResolution` | 5-state enum, derived from UMA oracle |
| **Kalshi** | _(not yet)_ | Kalshi has settlement events but we don't surface them today — separate request |
| **Pinnacle** | _(not available upstream)_ | Pinnacle's wire emits no real-time reason field; `cancellationReason` exists only on the post-grading Lines API partner endpoint |
| **DraftKings / FanDuel / BetMGM / Caesars** | _(not available)_ | Suspended markets simply disappear from the feed; no status field is emitted |
| **OpticOdds (industry comparison)** | _(no reason)_ | Fixture-level `status: cancelled` exists but carries no reason; per-market objects have no status field |

The data customers want — a per-book settlement reason — is not industry-standard. Polymarket is the rare case where the upstream wire actually carries it, because UMA resolution is on-chain and publicly observable.

## Why the field is Polymarket-prefixed

We deliberately named the field `polymarketResolution` rather than a generic `resolutionStatus` so it's obvious the values are Polymarket-specific. A future Kalshi version would be a separate `kalshiResolution` field with its own enum — the wire formats are different enough that a unified enum would either be lowest-common-denominator (useless) or full of asterisks for "Polymarket-only" / "Kalshi-only" values.

## See also

- [Sportsbook list — prediction markets](/api-reference/sportsbooks#prediction-markets)
- [Odds API reference](/api-reference/odds)
- [Live vs. Pre-Match](/concepts/live-vs-prematch) — covers the related `marketStatus` semantics