---
title: "The match's match-winner market (PRO)"
method: GET
path: "/markets"
---

# The match's match-winner market (PRO)

`GET /markets`

## Request

- Base URL: `https://api.livetennisapi.com/api/public/v1`
- URL: `https://api.livetennisapi.com/api/public/v1/markets`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

The match-winner market mapped to this match — `data` holds at most one object, and `meta.count` is 0 when nothing is mapped.

MATCH-WINNER ONLY. No handicaps or game spreads, no totals, no set-winner books, and no per-game or per-set derivative of any kind. A quote here is the probability that a player WINS THE MATCH. Venues do list tennis derivatives beside the match-winner book — game spreads such as "A (-3.5) vs B (+3.5)" among them — and this API deliberately publishes none of them: a derivative is refused at the mapping step so it can never be served as, or beside, a match-winner price (2026-09-22).

## Query parameters

- `match_id` integer, required

## Response `200`

Markets

- object
  - `data` Market[]
    - `id` integer
    - `question` string, nullable
    - `status` 'active' | 'resolved' | 'closed' | 'null', nullable
    - `volume` number, nullable
    - `liquidity` number, nullable
    - `end_date` string, date-time, nullable
    - `prices` Price[]: Prices endpoint / match detail only; newest first
      - `side` integer, nullable: 1 = players.p1's outcome, 2 = players.p2's - decided by our name-verified match-market mapping, never by the venue's own display order (the venue lists roughly half of all pairings the other way round). Fixed 2026-09-09: ticks served before that date followed the venue's display order, so on those markets side was reversed; the mapping is stored, so re-reading any tick now returns the correct side.
      - `bid` number, nullable
      - `ask` number, nullable
      - `mid` number, nullable: The venue's observed midpoint at the instant we polled or streamed it - never a model estimate. Only mid is always real; see synthetic.
      - `spread` number, nullable
      - `price_source` string, nullable: Feed category, e.g. prediction_market
      - `synthetic` boolean, nullable: true = bid/ask are estimated from mid (mid +/- 0.005, not a live order book) - mid itself is the venue's observed midpoint, never a model estimate; false = real top-of-book from the live order-book stream; null = unknown (older ticks). The live stream attaches when a match goes live, so pre-match ticks are synthetic: true by design.
      - `timestamp` string, date-time, nullable: When we observed this quote (UTC) - our observation clock, not a venue publication time.
  - `meta` object
    - `match_id` integer
    - `count` integer

## Other responses

- `400`: Bad query parameter
- `401`: Missing, unknown, or disabled credentials
- `403`: Your tier doesn't unlock this endpoint
- `429`: Rate limit exceeded (Retry-After header present). Three body shapes, told apart by `error` and `scope`: the per-MINUTE limit (`rate_limited`, with `upgrade_url`, `tier` and `price` naming the next tier up); the per-DAY quota (`rate_limited` with `scope: "day"`, `limit_per_day`, and `resets_at` — the absolute ISO instant the daily window resets); and `abuse_throttled` with `retry_at_epoch` — a 24-hour block applied to clients that keep hammering far past their cap, which a well-behaved retry loop never sees. Fix the loop rather than retrying through it.

---

[API](https://skmtc.dev/livetennisapi/apis/live-tennis-api.md) · [All operations](https://skmtc.dev/livetennisapi/apis/live-tennis-api/llms.txt) · [OpenAPI document](https://skmtc.dev/livetennisapi/apis/live-tennis-api/revisions/7881947e8e43?raw)
