Live tennis data: what you can read, and on which plan

Poll GET /matches?status=live for the current scoreline of every match in progress — that works on a free key with no card. Move up when you need the things a scoreline does not carry: individual match events, in-play statistics, match-winner market prices, model win-probability, or a streaming feed instead of a poll.

Everything below uses the base URL https://api.livetennisapi.com/api/public/v1 with an X-API-Key header, across ATP, WTA, Challenger and ITF, singles and doubles.

What counts as live data here?

Four different things, and they are not all on the same plan. Being explicit about that is the point of this page:

Which plan carries which

DataEndpointPlan
Live and upcoming matches, scoreline, players, fixtures GET /matches?status=liveFree — $0, no card
Completed results and the point-by-point tape GET /history/matches/{id}Basic — $9.99/mo
Match events and match-winner market prices GET /matches/{id}/events, /pricesPro — $29.99/mo
Model win-probability, in-play statistics, streaming push feed GET /matches/{id}/analysis, GET /ws-tokenUltra — $99.99/mo

Full plan comparison, annual pricing and the per-minute and per-day quotas are on the pricing page.

What a live response actually looks like

One detail catches almost every first integration: every score array is player-major. The first element is player one, the second is player two — not "home and away", and not ordered by who is winning.

{
  "id": 18953,
  "status": "live",
  "tour": "atp",
  "sets": [1, 0],
  "games": [[6, 3], [4, 4]],
  "points": ["40", "30"],
  "server": 1,
  "is_tiebreak": false
}

That reads: player one leads by a set, took the first 6–4, the second stands at 3–4, the game in progress is 40–30, and player one is serving.

Polling or streaming?

Poll REST if you need the scoreline. It needs no reconnection logic and it works on a free key. The free tier allows 30 requests a minute and 100 a day, and the daily cap is what binds first: poll the whole slate with one call rather than each match separately, and a live scoreboard costs two requests a minute however many matches are on.

Use the streaming push feed when you need every point as it happens and the gap between polls would change what your code does — per-point logic, or reacting where a twenty-second-old score is materially worse than a current one. That is the Ultra tier, reached by minting a short-lived token from GET /ws-token. The feed speaks the Centrifugo client protocol rather than plain JSON frames, so use the PushStream client in the official Python or JavaScript SDK rather than a bare WebSocket — it mints the token, subscribes, answers heartbeats and mints a fresh token on every reconnect, which is the part hand-rolled clients get wrong.

Starting in one call

curl -s "https://api.livetennisapi.com/api/public/v1/matches?status=live" \
  -H "X-API-Key: $LIVE_TENNIS_API_KEY"

A free key is instant and needs no card: get one here. The same key upgrades between plans without a line of code changing.

Live data — FAQ

Is there a free tennis live scores API?

Yes. The free tier returns live and upcoming matches with the full scoreline — sets, games, points, server and tiebreak flag — across ATP, WTA, Challenger and ITF, with no card required. It allows 30 requests a minute and 100 a day. The daily cap binds before the rate limit does, so poll the whole slate with GET /matches?status=live in one request rather than polling each match: the cost is then independent of how many matches are in play.

What is the difference between live scores and live match data?

The scoreline is the state a match has reached; live match data also covers what produced it and what it implies. Scores — sets, games, points, server — are on the free tier. Individual match events and match-winner market prices are Pro at $29.99 a month. Model win-probability and in-play serve and return statistics are Ultra at $99.99. Being able to read a scoreboard and being able to reason about a match in progress are different products, and they are priced differently.

Do I need a WebSocket for live tennis data?

Usually not. Polling GET /matches?status=live returns the current state of every live match and needs no reconnection handling. Reach for the streaming push feed when you can name a behaviour polling makes impossible — reacting to individual points, or acting where a twenty-second-old score is materially worse than a current one. That is the Ultra tier. Starting on REST and moving up when you hit a real limit is cheaper than maintaining a connection you do not yet need.

Which tours are covered live?

ATP, WTA, Challenger and ITF, singles and doubles, including qualifying draws. The lower tiers matter more than they sound: most of the tennis played on any given day is Challenger and ITF, and it is where coverage between providers differs most. Per-tour measured completeness is published at GET /history/coverage, each figure carrying its own as-of date, so you can check a slice rather than assume it.

How do I read the score arrays correctly?

Every array is player-major: the first element is player one, the second is player two. So "sets": [1, 0] means player one leads by a set, "games": [[6, 3], [4, 4]] means the first set finished 6–4 and the second stands at 3–4, and "server": 1 means player one is serving. This is the single detail that most often trips up a first integration, because the arrays look as though they should be ordered by match position rather than by player.

Full endpoint detail is in the live scores reference and the complete API reference. Plans and quotas: pricing.