PredictorSDK

List matched sports events

Lists the sports events that more than one venue has matched, soonest scheduled start first, with cursor-based pagination (default limit=25, max 100).

GET
/v1/matching-markets/sports

Lists the sports events that more than one venue has matched, soonest scheduled start first, with cursor-based pagination (default limit=25, max 100). A game stays listed through the day after its scheduled date (America/New_York), so the first events can be games that have already been played; include_settled=true adds older ones. Coverage is NBA, WNBA, NHL, MLB, and NFL; data[].league names the league and is the first segment of the canonical event_id. Every event has one shape for every venue: it lists its participants and submarkets, and each submarket lists the venue markets matched to it in source_markets[]. Every one of those carries the same references: provider, the provider's own parent event_id for GET /v1/events/{event_id}, its market_id for GET /v1/markets/{market_id}, and outcome IDs mapped to canonical outcomes. A page covers events whose full-game moneyline is matched, and each carries only that submarket; include_submarkets=true adds every other matched submarket, and events matched only on spreads, totals, team totals or props.

Each event says when it is scheduled. scheduled_date is the game's calendar day in America/New_York and is always present; scheduled_start is its start time in UTC when a venue published one, and null when the venues published only a date.

Games whose date has passed are excluded unless you ask for them with include_settled=true. Narrow the list with league, scheduled_date and participant: each is a membership filter on the same matched set, they compose, and pagination.total counts the filtered set rather than every event. To look events up by an identifier you already hold, a canonical event_id or a venue's own market, slug, event, outcome token or conditionId, use GET /v1/matching-markets/sports/lookup: it answers in one call, in full, and says what each identifier found, which a page cannot.

Player props use strict settlement-equivalent matching by default. Set include_submarkets=true&player_prop_match=same_prop to compare roster-verified props with the same player, game, statistic, full-game period, and threshold even when settlement rules differ or remain unverified. Each player prop includes a nine-dimension rule matrix. This policy applies only to player props, not game lines; a same-prop match is not a guarantee of identical payouts or a perfect hedge.

Every moneyline, spread, total and team total carries settlement_equivalence: whether the venues in the submarket settle a tied game, overtime and extra innings, and a line that lands exactly the same way. Send include_rules=true to also get the rows behind it, rule_comparisons: three rows, tie, overtime and push, with each venue's value, a description and a link to the evidence. They are left out by default because they are most of an event's size. The matrix is published beside the match and never changes which venues are paired: a venue that settles an NFL tie differently from another is still in the submarket, and the matrix says so. A rule nobody has written down is unknown, and unknown never means equivalent.

A team total is a team's own total (market_type=team_total, "the Eagles over 24.5 points"), not the game's: its subject is the team, its metric is points, and two venues' lines are one submarket only for the same team, period and line. Today it is matched for the NFL, on Kalshi and Polymarket.

Matching runs continuously in the background and this endpoint reads the stored result, so every response carries snapshot.observed_at: how old the venue data behind it is. Check it before treating an event a response does not contain as unmatched — an empty page from a snapshot that stopped updating looks exactly like one from a current snapshot.

Authorization

BearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

limit?integer

Maximum number of matched events to return per page. Range 1–100, default 25.

Range1 <= value <= 100
Default25
cursor?string

Opaque cursor from a previous response's pagination.next_cursor (nextCursor in TypeScript, NextCursor in Go). Must be used with the same filter set — a cursor from include_settled=true cannot be replayed against include_settled=false, and a cursor from one league, scheduled_date or participant cannot be replayed under another; either returns 400.

league?string

Restrict the list to one league, matched against each event's own league value. Without it every league is listed.

Only the leagues listed here are accepted, case-insensitively. Any other value returns 400 listing them — an unrecognized filter is never ignored, because a silently dropped filter returns a full page that looks filtered.

pagination.total counts only that league's events, and cursors are bound to the filter that created them: replay a next_cursor with the same filters, or start again from the first page.

Value in

  • "nba"
  • "wnba"
  • "nfl"
  • "mlb"
  • "nhl"
scheduled_date?string

Restrict the list to the games on one calendar day, as YYYY-MM-DD in America/New_York: the scheduled_date each event publishes. That is the day its event_id ends in, or later for a postponed game. A game that starts at 8:30 PM Eastern on the 20th is on the 20th, although its scheduled_start is on the 21st in UTC.

The default population is today's games plus a one-day grace (see include_settled), so a date further in the past matches nothing unless include_settled=true, which also reads the days of the settled archive. Any value that is not a calendar date in that form returns 400. pagination.total counts only that day's events, and cursors are bound to the filter.

Formatdate
participant?string

Restrict the list to events that have a participant with this key (participants[].key, such as okc), matched case-insensitively. Participant keys are unique only within a league: la is the Rams in the NFL and the Sparks in the WNBA, so pair this with league unless you want both. Send one key; a comma-joined value is a 400. pagination.total counts only the matching events, and cursors are bound to the filter.

include_settled?boolean

Selects which events this request draws from. Defaults to false: the current games, meaning events whose scheduled start has not certainly passed — today's games, plus a one-day grace so a late start that runs past midnight Eastern is never dropped mid-play. Set it to true to also get the settled archive: events that left the live matching run, usually because the venues settled or delisted them, kept for 30 days. That adds games whose date is further in the past, including ones a venue still lists as open, and games a venue cancelled, which can be future-dated: Polymarket resolves a game that was never played 50-50, as it did a postseason game its series never needed, before its scheduled day. The default population leaves a cancelled game out, so false never lists a game that was not played.

Venues settle and delist a game's markets at different times, so the endpoint filters on the game's own date (its scheduled start, and never earlier than the date its event_id ends in) rather than on an upstream status. Nothing is reported as settled that the venue has not settled; these events are simply not current, which is what the default page is for. A postponed game takes its new date, so its event stays current until the makeup game.

A game that has started is served with the fullest mapping it had — the version from before its first venue settled and delisted it — rather than only the venues still listing it. That holds in the default population too, so today's finished games stay listed with every venue until they are past-dated; with true it holds for older games as well. Games archived before 2026-10-04 21:26 UTC kept only the venues that still listed them when they left (usually two), and age out of the 30-day archive by 2026-11-04.

Defaultfalse
player_prop_match?string

Player-prop admission policy. It requires include_submarkets=true; with include_submarkets=false, which is the default on a page, it is a 400. Matched case-insensitively. strict (the default) includes only groups of at least two distinct providers with verified player/game/stat/threshold/side identity and a completely reviewed equivalent settlement profile. same_prop retains exact prop identity but also admits different or unverified settlement rules, identified by settlement_equivalence and rule_comparisons. Unknown rules never prove equivalence. Applies with include_settled; cursors cannot be reused between policies. Does not change game-line matching or the default moneyline projection. Historical snapshots without verified player identity do not expose props.

Default"strict"

Value in

  • "strict"
  • "same_prop"
include_submarkets?boolean

When true, each event lists every matched submarket (spreads, totals, period lines and player props) instead of only its full-game moneyline, and events matched only on those submarkets are included too. When false, an event appears only when its full-game moneyline is matched, so submarkets is never empty. Defaults to false, which keeps a page small. Every submarket has the same shape, so code written against the moneyline reads the rest unchanged. This is an identity mapping only; fetch current status, quotes, and liquidity from the referenced market resources. Explicit player_prop_match requires this to be true.

Such pages are large: on 2026-10-04 a 50-event page with every submarket was about 880 KB (190 KB gzipped), and a 20-event player_prop_match=same_prop page about 3 MB. Send Accept-Encoding: gzip and a smaller limit when you need them.

include_rules?boolean

When true, every moneyline, spread and total also lists rule_comparisons: the three rows (tie, overtime and push), each with every source market's value, a description and an evidence link, that sit behind its settlement_equivalence. When false, the default, a game line carries settlement_equivalence alone: the verdict is always there and only the rows are left out. The rows are about 60% of an event's bytes on a busy football slate, so ask for them when you want the evidence. A player prop always carries its own matrix, whatever this is. The flag changes what each event lists and never which events a page returns, so a cursor works with either value.

Defaultfalse

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/matching-markets/sports"

{  "data": [    {      "event_id": "nba-okc-sas-2026-10-20",      "sport": "basketball",      "league": "nba",      "title": "Oklahoma City Thunder vs. San Antonio Spurs",      "scheduled_start": "2026-10-20T23:30:00.000Z",      "scheduled_date": "2026-10-20",      "participants": [        {          "key": "okc",          "name": "Oklahoma City Thunder",          "role": "away"        },        {          "key": "sas",          "name": "San Antonio Spurs",          "role": "home"        }      ],      "submarkets": [        {          "key": "moneyline|full|winner",          "market_type": "moneyline",          "segment": "full",          "display_name": "Winner",          "metric": "winner",          "outcomes": [            {              "key": "winner:okc",              "label": "Oklahoma City Thunder win",              "type": "participant",              "side": "win"            },            {              "key": "winner:sas",              "label": "San Antonio Spurs win",              "type": "participant",              "side": "win"            }          ],          "source_markets": [            {              "provider": "kalshi",              "event_id": "KXNBAGAME-26OCT20OKCSAS",              "market_id": "KXNBAGAME-26OCT20OKCSAS-OKC",              "market_name": "Oklahoma City wins",              "outcomes": [                {                  "canonical_outcome_key": "winner:okc",                  "label": "Yes",                  "outcome_id": "yes",                  "side": "yes"                },                {                  "canonical_outcome_key": "winner:sas",                  "label": "No",                  "outcome_id": "no",                  "side": "no"                }              ]            },            {              "provider": "kalshi",              "event_id": "KXNBAGAME-26OCT20OKCSAS",              "market_id": "KXNBAGAME-26OCT20OKCSAS-SAS",              "market_name": "San Antonio wins",              "outcomes": [                {                  "canonical_outcome_key": "winner:sas",                  "label": "Yes",                  "outcome_id": "yes",                  "side": "yes"                },                {                  "canonical_outcome_key": "winner:okc",                  "label": "No",                  "outcome_id": "no",                  "side": "no"                }              ]            },            {              "provider": "sxbet",              "event_id": "L19766755",              "market_id": "0xb4d047a709aae881e5ccad9d123592967644ee1df1f17078c762b388e41b81c5",              "market_name": "San Antonio Spurs vs Oklahoma City Thunder",              "outcomes": [                {                  "canonical_outcome_key": "winner:sas",                  "label": "San Antonio Spurs",                  "outcome_id": "outcomeOne"                },                {                  "canonical_outcome_key": "winner:okc",                  "label": "Oklahoma City Thunder",                  "outcome_id": "outcomeTwo"                }              ]            }          ],          "settlement_equivalence": "equivalent"        }      ]    },    {      "event_id": "nfl-pit-no-2026-10-25",      "sport": "football",      "league": "nfl",      "title": "Pittsburgh Steelers vs. New Orleans Saints",      "scheduled_start": "2026-10-25T17:00:00.000Z",      "scheduled_date": "2026-10-25",      "participants": [        {          "key": "pit",          "name": "Pittsburgh Steelers",          "role": "away"        },        {          "key": "no",          "name": "New Orleans Saints",          "role": "home"        }      ],      "submarkets": [        {          "key": "moneyline|full|winner",          "market_type": "moneyline",          "segment": "full",          "display_name": "Winner",          "metric": "winner",          "outcomes": [            {              "key": "winner:pit",              "label": "Pittsburgh Steelers win",              "type": "participant",              "side": "win"            },            {              "key": "winner:no",              "label": "New Orleans Saints win",              "type": "participant",              "side": "win"            }          ],          "source_markets": [            {              "provider": "polymarket",              "event_id": "nfl-pit-no-2026-10-25",              "market_id": "4551269",              "market_name": "Steelers vs. Saints",              "market_slug": "nfl-pit-no-2026-10-25",              "outcomes": [                {                  "canonical_outcome_key": "winner:pit",                  "label": "Steelers",                  "outcome_id": "115700113006785753352548302007769096699086928102312992900278010746804635156828"                },                {                  "canonical_outcome_key": "winner:no",                  "label": "Saints",                  "outcome_id": "16013029087006534797924862977185419395437649810045162973335886530817974510015"                }              ]            },            {              "provider": "sxbet",              "event_id": "L18900793",              "market_id": "0x001cd92a53345352d1e28da827c9f1cab0d417878de7e8f2e979c7dd58ba6c59",              "market_name": "New Orleans Saints vs Pittsburgh Steelers",              "outcomes": [                {                  "canonical_outcome_key": "winner:no",                  "label": "New Orleans Saints",                  "outcome_id": "outcomeOne"                },                {                  "canonical_outcome_key": "winner:pit",                  "label": "Pittsburgh Steelers",                  "outcome_id": "outcomeTwo"                }              ]            }          ],          "settlement_equivalence": "different"        }      ]    }  ],  "pagination": {    "limit": 25,    "total": 140,    "has_more": true,    "next_cursor": "eyJzIjoiNTRiYmFiZjEiLCJ0IjoiMjAyNi0wNi0wNlQwMDowMDowMFoiLCJpIjoibWxiLWJvcy1ueXktMjAyNi0wNi0wNiJ9"  },  "snapshot": {    "observed_at": "2026-10-03T23:11:41.515Z"  }}