Live Tennis API — Full Reference
Version 1.0 · OpenAPI 3.1.0 ·
Interactive reference ·
OpenAPI spec ·
livetennisapi.com
This is the plain-text reference. It contains the same content as the
interactive documentation but requires no JavaScript, so it can be read by search engines,
answer engines and any HTTP client.
Real-time tennis scores, player data, match-winner market prices, and
model-driven match analysis. Read-only.
Access is tiered (BASIC / PRO / ULTRA): match events and market prices
need PRO; model analysis, live model fields (win_probability_p1,
danger) and the WebSocket feed need ULTRA. A call above your tier
returns 403 {"error":"upgrade_required"}.
All timestamps are UTC ISO 8601 with a Z suffix. List endpoints return
{data, meta}; single resources return the object directly. Ignore
unknown fields — additive changes land within v1.
A native WebSocket live feed (ULTRA) exists at /ws under the same base
URL — see the API documentation for the frame protocol (subscribe with
{"action":"subscribe","topics":["live-scores"]}; server pushes
score frames + ping heartbeats).
Base URL
https://api.livetennisapi.com/api/public/v1
Authentication
Send your API key as a bearer token or in the X-API-Key header — either works.
The /health endpoint needs no key.
Authorization: Bearer twjp_...
X-API-Key: twjp_...
Plans
| Plan | Unlocks | Rate limit | Price |
| BASIC | Matches, scores, players, fixtures, history | 60/min · 10,000/day | $9.99/mo |
| PRO | Adds match events and market prices | 300/min · 100,000/day | $29.99/mo |
| ULTRA | Adds model analysis, win_probability_p1, danger, and the WebSocket feed | 600/min · 500,000/day | $99.99/mo |
Calling an endpoint above your plan returns 403 {"error":"upgrade_required"} —
never a silent empty result. See pricing.
Official client libraries
Conventions
- Timestamps are UTC ISO 8601 with a
Z suffix.
- List endpoints return
{data, meta}; single resources return the object directly.
limit defaults to 50; the API rejects anything above 200. Paginate with offset.
- Ignore unknown fields. Additive changes ship within
v1, so a client that
rejects unrecognised fields will break. Every official SDK parses permissively.
- Score shape:
sets is [sets_p1, sets_p2].
games is [games_p1, games_p2] where each side is a per-set list —
so [[6,3,2],[4,6,1]] reads 6-4, 3-6, 2-1. It is player-major, not set-major.
Endpoints
GET /health
Liveness probe (no auth)
Plan required: — · operationId: healthCheck
Responses
Response fields
| Field | Type | Description |
|---|
status | string | |
version | string | |
Example
curl https://api.livetennisapi.com/api/public/v1/health
GET /matches
List matches by lifecycle status (BASIC)
Plan required: BASIC · operationId: listMatches
Parameters
| Name | In | Type | Required | Notes |
|---|
status | query | string (live, upcoming, completed) | no | Default live. |
limit | query | integer | no | Default 50. |
offset | query | integer | no | Default 0. |
Responses
| Status | Meaning |
|---|
200 | Matches with latest score |
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) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/matches \
-H "Authorization: Bearer twjp_..."
GET /matches/{matchId}
Full match detail (BASIC; +market PRO, +analysis ULTRA)
Plan required: ULTRA · operationId: getMatch
Parameters
| Name | In | Type | Required | Notes |
|---|
matchId | path | integer | yes | |
Responses
| Status | Meaning |
|---|
200 | Match with score; market embed at PRO+, analysis embed at ULTRA |
401 | Missing, unknown, or disabled credentials |
403 | Your tier doesn't unlock this endpoint |
404 | No such resource, or no data yet |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
id | integer | |
tournament | string | |
surface | string or null (hard, clay, grass, null) | |
indoor | boolean | |
format | string or null (BO3, BO5, null) | |
round | string or null | |
status | string (upcoming, live, completed, cancelled) | |
event_status | string or null | |
is_doubles | boolean | |
scheduled_time | string or null | |
players | object | |
score | object or null | |
winner | integer or null | Completed matches only — derived from final sets |
analysis | object | ULTRA only (absent below) |
market | object or null | PRO+ only (absent below) |
Example
curl https://api.livetennisapi.com/api/public/v1/matches/18953 \
-H "Authorization: Bearer twjp_..."
GET /matches/{matchId}/score
Current score only — lowest-latency REST read (BASIC)
Plan required: BASIC · operationId: getMatchScore
Parameters
| Name | In | Type | Required | Notes |
|---|
matchId | path | integer | yes | |
Responses
| Status | Meaning |
|---|
200 | Current score (ULTRA adds win_probability_p1 + danger) |
401 | Missing, unknown, or disabled credentials |
404 | No such resource, or no data yet |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
sets | array of integer | |
games | array of array of integer | [games_p1, games_p2]; each a per-set list |
points | array of string | |
server | integer or null (1, 2, null) | |
is_tiebreak | boolean | |
win_probability_p1 | number or null | |
danger | number or null | |
timestamp | string or null | |
Example
curl https://api.livetennisapi.com/api/public/v1/matches/18953/score \
-H "Authorization: Bearer twjp_..."
GET /matches/{matchId}/events
Match events, newest first (PRO)
Plan required: PRO · operationId: listMatchEvents
Parameters
| Name | In | Type | Required | Notes |
|---|
matchId | path | integer | yes | |
limit | query | integer | no | Default 50. |
offset | query | integer | no | Default 0. |
Responses
| Status | Meaning |
|---|
200 | Events |
401 | Missing, unknown, or disabled credentials |
403 | Your tier doesn't unlock this endpoint |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/matches/18953/events \
-H "Authorization: Bearer twjp_..."
GET /matches/{matchId}/analysis
Model analysis for a match (ULTRA)
Plan required: ULTRA · operationId: getMatchAnalysis
Parameters
| Name | In | Type | Required | Notes |
|---|
matchId | path | integer | yes | |
Responses
| Status | Meaning |
|---|
200 | Thesis + profile (either may be null) |
401 | Missing, unknown, or disabled credentials |
403 | Your tier doesn't unlock this endpoint |
404 | No such resource, or no data yet |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
thesis | object or null | |
profile | object or null | |
Example
curl https://api.livetennisapi.com/api/public/v1/matches/18953/analysis \
-H "Authorization: Bearer twjp_..."
GET /players
Search players by name (BASIC)
Plan required: BASIC · operationId: searchPlayers
Parameters
| Name | In | Type | Required | Notes |
|---|
search | query | string | no | |
limit | query | integer | no | Default 50. |
offset | query | integer | no | Default 0. |
Responses
| Status | Meaning |
|---|
200 | Players (ranked first; no stats object on the list) |
401 | Missing, unknown, or disabled credentials |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/players \
-H "Authorization: Bearer twjp_..."
GET /players/{playerId}
One player's bio + ranking + cached stats (BASIC)
Plan required: BASIC · operationId: getPlayer
Parameters
| Name | In | Type | Required | Notes |
|---|
playerId | path | integer | yes | |
Responses
| Status | Meaning |
|---|
200 | Player with stats ({ratings, season}) |
401 | Missing, unknown, or disabled credentials |
404 | No such resource, or no data yet |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
id | integer | |
name | string | |
tour | string or null | |
country | string or null | |
ranking | integer or null | |
ranking_points | integer or null | |
ranking_movement | string or null (up, down, same, null) | |
hand | string or null (R, L, null) | |
backhand | integer or null (1, 2, null) | |
birthday | string or null | |
is_doubles_team | boolean | |
stats | object | Single-player endpoint only |
Example
curl https://api.livetennisapi.com/api/public/v1/players/1104 \
-H "Authorization: Bearer twjp_..."
GET /markets
Match-winner market(s) for a match (PRO)
Plan required: PRO · operationId: listMarkets
Parameters
| Name | In | Type | Required | Notes |
|---|
match_id | query | integer | yes | |
Responses
| Status | Meaning |
|---|
200 | Markets |
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) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/markets \
-H "Authorization: Bearer twjp_..."
GET /markets/{matchId}/prices
Market + recent price ticks per side, newest first (PRO)
Plan required: PRO · operationId: getMarketPrices
Parameters
| Name | In | Type | Required | Notes |
|---|
matchId | path | integer | yes | |
limit | query | integer | no | Default 50. |
Responses
| Status | Meaning |
|---|
200 | Market with prices |
401 | Missing, unknown, or disabled credentials |
403 | Your tier doesn't unlock this endpoint |
404 | No such resource, or no data yet |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
id | integer | |
question | string or null | |
status | string or null (active, resolved, closed, null) | |
volume | number or null | |
liquidity | number or null | |
end_date | string or null | |
prices | array of object | Prices endpoint / match detail only; newest first |
Example
curl https://api.livetennisapi.com/api/public/v1/markets/18953/prices \
-H "Authorization: Bearer twjp_..."
GET /history/matches
Completed matches, newest first, with derived winner (BASIC)
Plan required: BASIC · operationId: listCompletedMatches
Parameters
| Name | In | Type | Required | Notes |
|---|
limit | query | integer | no | Default 50. |
offset | query | integer | no | Default 0. |
Responses
| Status | Meaning |
|---|
200 | Completed matches (winner = 1|2|null, from final sets) |
401 | Missing, unknown, or disabled credentials |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/history/matches \
-H "Authorization: Bearer twjp_..."
GET /fixtures
Upcoming scheduled fixtures, earliest first (BASIC)
Plan required: BASIC · operationId: listFixtures
Parameters
| Name | In | Type | Required | Notes |
|---|
limit | query | integer | no | Default 50. |
offset | query | integer | no | Default 0. |
Responses
| Status | Meaning |
|---|
200 | Name-only fixtures (players not yet resolved to ids) |
401 | Missing, unknown, or disabled credentials |
429 | Rate limit exceeded (Retry-After header present) |
Response fields
| Field | Type | Description |
|---|
data | array of object | |
meta | object | |
Example
curl https://api.livetennisapi.com/api/public/v1/fixtures \
-H "Authorization: Bearer twjp_..."
WebSocket feed (ULTRA)
A native WebSocket live feed is available at https://api.livetennisapi.com/api/public/v1/ws. Subscribe with
{"action":"subscribe","topics":["live-scores"]} or
{"action":"subscribe","topics":["match:<id>"]}. The server acknowledges with a
subscribed frame, then pushes score frames on every change plus a
ping heartbeat roughly every 15 seconds.
Schemas
Error
| Field | Type | Description |
error | string | |
Score
ULTRA adds win_probability_p1 + danger.
| Field | Type | Description |
sets | array of integer | |
games | array of array of integer | [games_p1, games_p2]; each a per-set list |
points | array of string | |
server | integer or null (1, 2, null) | |
is_tiebreak | boolean | |
win_probability_p1 | number or null | |
danger | number or null | |
timestamp | string or null | |
Player
| Field | Type | Description |
id | integer | |
name | string | |
tour | string or null | |
country | string or null | |
ranking | integer or null | |
ranking_points | integer or null | |
ranking_movement | string or null (up, down, same, null) | |
hand | string or null (R, L, null) | |
backhand | integer or null (1, 2, null) | |
birthday | string or null | |
is_doubles_team | boolean | |
stats | object | Single-player endpoint only |
Match
| Field | Type | Description |
id | integer | |
tournament | string | |
surface | string or null (hard, clay, grass, null) | |
indoor | boolean | |
format | string or null (BO3, BO5, null) | |
round | string or null | |
status | string (upcoming, live, completed, cancelled) | |
event_status | string or null | |
is_doubles | boolean | |
scheduled_time | string or null | |
players | object | |
score | object or null | |
winner | integer or null | Completed matches only — derived from final sets |
MatchDetail
| Field | Type | Description |
id | integer | |
tournament | string | |
surface | string or null (hard, clay, grass, null) | |
indoor | boolean | |
format | string or null (BO3, BO5, null) | |
round | string or null | |
status | string (upcoming, live, completed, cancelled) | |
event_status | string or null | |
is_doubles | boolean | |
scheduled_time | string or null | |
players | object | |
score | object or null | |
winner | integer or null | Completed matches only — derived from final sets |
analysis | object | ULTRA only (absent below) |
market | object or null | PRO+ only (absent below) |
Analysis
| Field | Type | Description |
thesis | object or null | |
profile | object or null | |
Market
| Field | Type | Description |
id | integer | |
question | string or null | |
status | string or null (active, resolved, closed, null) | |
volume | number or null | |
liquidity | number or null | |
end_date | string or null | |
prices | array of object | Prices endpoint / match detail only; newest first |
Price
| Field | Type | Description |
side | integer or null | 1 = p1's outcome, 2 = p2's |
bid | number or null | |
ask | number or null | |
mid | number or null | |
spread | number or null | |
timestamp | string or null | |
Event
| Field | Type | Description |
type | string (break, set_won, game_won, momentum_run) | |
player | integer or null (1, 2, null) | |
timestamp | string or null | |
Fixture
| Field | Type | Description |
id | integer | |
event_date | string or null | |
tour | string or null | |
tournament | string or null | |
round | string or null | |
surface | string or null | |
player1_name | string or null | |
player2_name | string or null | |
status | string or null | |
Generated from openapi.yaml by
livetennisapi/openapi.
Questions or a spec mismatch? Open an issue.