---
title: "Paginated catalog of verified cross-venue matched markets"
method: GET
path: "/matched-markets"
tags: ["Sports"]
---

# Paginated catalog of verified cross-venue matched markets

`GET /matched-markets`

## Request

- Base URL: `https://data.kairos.trade`
- URL: `https://data.kairos.trade/matched-markets`
- Auth: none required

Returns embedding-verified cross-venue market matches (verified matches only), joined against market metadata for display (title, ticker, images, expiry, status). `min_similarity` is clamped server-side to never go below a minimum threshold regardless of what the caller passes. Pairs are dropped if either correlation side has expired, if either side references a provider that is unknown or not currently indexing-enabled, or if either side's resolved market status is settled/closed/resolved; a side with no metadata available (unmirrored rather than de-indexed) is kept with null display fields. `has_more` reflects whether the underlying page (before the live-status post-filter) was full, so it is not a strict function of the returned `count`/`pairs` length. `total` is only computed (filters applied before the live-status post-filter) when `include_total=true`. This is treated as a primary, non-additive endpoint: any backend failure returns 503 rather than a degraded/empty result.

## Query parameters

- `limit` integer
- `offset` integer
- `cursor` string
- `provider` string
- `min_similarity` number, double
- `sort_by` 'similarity' | 'updated_at'
- `include_total` boolean

## Response `200`

A page of verified cross-venue matched market pairs.

- SportsMatchedMarketsResponse
  - `pairs` SportsMatchedMarketPair[], required
    - `a` SportsMatchedMarketSide, required
      - `provider_id` integer, required
      - `provider` string, required
      - `market_id` string, required
      - `title` string, nullable, required: Null if metadata for this side's market isn't available.
      - `ticker` string, nullable, required
      - `image` string, nullable, required
      - `icon` string, nullable, required
      - `expires_at` string, date-time, nullable, required
      - `category` string, nullable, required: Canonical title-cased category, or null when the market is uncategorised.
    - `b` SportsMatchedMarketSide, required
      - `provider_id` integer, required
      - `provider` string, required
      - `market_id` string, required
      - `title` string, nullable, required: Null if metadata for this side's market isn't available.
      - `ticker` string, nullable, required
      - `image` string, nullable, required
      - `icon` string, nullable, required
      - `expires_at` string, date-time, nullable, required
      - `category` string, nullable, required: Canonical title-cased category, or null when the market is uncategorised.
    - `similarity` number, double, required
    - `updated_at` string, date-time, required
  - `count` integer, required: Number of pairs on this page after live-status post-filtering (may be less than limit).
  - `limit` integer, required
  - `offset` integer, required
  - `has_more` boolean, required: Whether the underlying page (before live-status post-filtering) was full — not a strict function of count.
  - `next_cursor` string, nullable: Opaque cursor for the next keyset page. Present when cursor mode is requested.
  - `catalog_version` string: Full-set fingerprint shared by every page in one cursor walk.
  - `total` integer: Only present when include_total=true. Total matching-pair count under the pre-live-filter query filters.

## Other responses

- `400`: Unknown provider name, or sort_by is not one of the supported columns.
- `409`: The correlation catalogue changed during a cursor walk. Discard accumulated pages and restart with an empty cursor.
- `422`: Request failed FastAPI parameter validation.
- `429`: Rate limit exceeded for this route's sliding window, keyed on the session `sub` when authenticated and on the trusted client IP otherwise. Honor `Retry-After`. A per-API-key data ceiling (set per credential) rejects with `{"detail": "API key data rate limit exceeded"}` instead of the `error` envelope below.
- `503`: The correlation store could not be queried.

---

[API](https://skmtc.dev/kairos/apis/kairos-data-api.md) - [All operations](https://skmtc.dev/kairos/apis/kairos-data-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kairos/apis/kairos-data-api/revisions/cf6b76079e38?raw)
