Table Tennis API Documentation for Developers
Integrate fixtures, live scores, point-by-point events, results, tournaments, players, rankings, statistics, head-to-head records, historical data and real-time WebSocket streams through a developer-friendly Table Tennis API.
GET /v1/table-tennis/matches/live Authorization: Bearer YOUR_API_KEY { "data": [ { "match_id": "match_tt_48291", "status": "live", "current_set": 4 } ] }
Build With Table Tennis Data
This documentation structure is designed for developers building live-score apps, ranking dashboards, tournament trackers, analytics products, broadcaster tools, prediction systems and commercial table-tennis applications.
REST endpoints are used for complete state and historical resources. WebSocket is used for supported incremental live events such as point won, set won, match started and match completed.
Production applications should always verify competition coverage, data depth, plan limits and licensing before depending on a specific endpoint.
API Reference at a Glance
| Resource | Purpose |
Example route Illustrative only |
|---|---|---|
| Coverage | Discover supported competitions and features | /v1/table-tennis/coverage |
| Tournaments | List and retrieve tournament resources | /v1/table-tennis/tournaments |
| Fixtures | Retrieve scheduled matches | /v1/table-tennis/matches |
| Live Scores | Retrieve active match state | /v1/table-tennis/matches/live |
| Results | Retrieve completed matches and set history | /v1/table-tennis/results |
| Players | Retrieve player profiles | /v1/table-tennis/players |
| Rankings | Retrieve current and historical rankings | /v1/table-tennis/rankings |
| Statistics | Retrieve player and performance metrics | /v1/table-tennis/players/{id}/statistics |
| Head-to-Head | Compare two players | /v1/table-tennis/head-to-head |
| Historical Data | Query previous matches and ranking snapshots | /v1/table-tennis/history |
| WebSocket | Stream supported live events | wss://stream.example.com/v1/table-tennis |
Make Your First API Request
Illustrative Base URL
https://api.example.com/v1
Request
GET https://api.example.com/v1/table-tennis/matches/live
Authorization: Bearer YOUR_API_KEY
Accept: application/json
Response
{
"data": [
{
"match_id": "match_tt_48291",
"status": "live",
"tournament": {
"id": "tournament_211",
"name": "Example International Open"
},
"player_a": {
"id": "player_tt_101",
"name": "Player A"
},
"player_b": {
"id": "player_tt_204",
"name": "Player B"
},
"sets": {
"player_a": 2,
"player_b": 1
},
"current_set": {
"number": 4,
"player_a": 8,
"player_b": 6
}
}
]
}
Authenticate API Requests
The examples below use Bearer authentication as a placeholder. Replace this with the final production authentication mechanism.
Authorization: Bearer YOUR_API_KEY
Security Guidance
- Keep permanent API keys on your backend
- Do not expose private keys in browser JavaScript
- Use environment variables or a secure secret store
- Rotate credentials immediately if they are exposed
- Never log full production API keys
- Use HTTPS for REST and WSS for WebSocket
Check Competition Coverage
Verify whether the competition supports fixtures, live scores, point-by-point data, statistics, rankings, history and WebSocket before depending on a feature.
GET /v1/table-tennis/coverage
?competition_id=competition_tt_001
{
"data": {
"competition": {
"id": "competition_tt_001",
"name": "Example Tournament"
},
"coverage": {
"fixtures": true,
"results": true,
"live_scores": true,
"point_by_point": false,
"statistics": true,
"rankings": false,
"head_to_head": true,
"historical_results": true,
"websocket": false
}
}
}
List Table Tennis Tournaments
GET /v1/table-tennis/tournaments
Possible Filters
| Parameter | Example | Purpose |
|---|---|---|
| date_from | 2026-08-01 | Return tournaments beginning after a selected date |
| date_to | 2026-08-31 | Limit the tournament period |
| status | active | Filter by documented tournament state |
| country | EX | Filter where location metadata is supported |
| page | 1 | Paginate tournament results |
Example Tournament Response
{
"id": "tournament_211",
"name": "Example International Open",
"status": "active",
"start_date": "2026-08-05",
"end_date": "2026-08-10",
"country": "EX"
}
Retrieve Scheduled Table Tennis Matches
GET /v1/table-tennis/matches
Example Query
GET /v1/table-tennis/matches
?date=2026-08-07
&tournament_id=tournament_211
&status=scheduled
Example Fixture
{
"match_id": "match_tt_48291",
"status": "scheduled",
"scheduled_at": "2026-08-07T13:00:00Z",
"round": "quarterfinal",
"best_of": 7,
"tournament": {
"id": "tournament_211",
"name": "Example International Open"
},
"player_a": {
"id": "player_tt_101",
"name": "Player A"
},
"player_b": {
"id": "player_tt_204",
"name": "Player B"
}
}
Retrieve Live Table Tennis Matches
GET /v1/table-tennis/matches/live
Example Live Match
{
"match_id": "match_tt_48291",
"status": "live",
"best_of": 7,
"sets": {
"player_a": 2,
"player_b": 1
},
"set_history": [
{
"set": 1,
"player_a": 11,
"player_b": 7
},
{
"set": 2,
"player_a": 9,
"player_b": 11
},
{
"set": 3,
"player_a": 11,
"player_b": 6
}
],
"current_set": {
"number": 4,
"player_a": 8,
"player_b": 6
},
"updated_at": "2026-08-07T06:20:00Z"
}
Retrieve One Match
GET /v1/table-tennis/matches/{match_id}
Example
GET /v1/table-tennis/matches/match_tt_48291
Use the match endpoint after reconnecting from WebSocket, when opening a match detail page or when you need the authoritative current state.
Retrieve Match Events
GET /v1/table-tennis/matches/{match_id}/events
Illustrative Point Event
{
"event_id": "event_tt_90018",
"match_id": "match_tt_48291",
"type": "point_won",
"sequence": 73,
"set_number": 4,
"player_id": "player_tt_101",
"score": {
"player_a": 8,
"player_b": 6
},
"created_at": "2026-08-07T06:20:00Z"
}
Possible Event Types
- match_started
- point_won
- set_started
- set_won
- match_completed
- walkover
- retirement
- match_status_changed
Retrieve Completed Match Results
GET /v1/table-tennis/results
Example Query
GET /v1/table-tennis/results
?date=2026-08-07
&tournament_id=tournament_211
Example Result
{
"match_id": "match_tt_48291",
"status": "completed",
"winner_id": "player_tt_101",
"sets": {
"player_a": 4,
"player_b": 2
},
"set_history": [
{"set": 1, "player_a": 11, "player_b": 7},
{"set": 2, "player_a": 9, "player_b": 11},
{"set": 3, "player_a": 11, "player_b": 6},
{"set": 4, "player_a": 8, "player_b": 11},
{"set": 5, "player_a": 11, "player_b": 9},
{"set": 6, "player_a": 11, "player_b": 5}
]
}
Handle Exceptional Match States
Do not invent unplayed point or set scores. Preserve the official match status supplied by the API.
Walkover
Use the documented status and winner where supplied.
Retirement
Preserve the real score at retirement and the retired player.
Delayed
Keep the scheduled match visible with the correct official state.
Cancelled
Do not treat a cancelled match as a completed competitive result.
Retrieve Table Tennis Player Profiles
GET /v1/table-tennis/players
GET /v1/table-tennis/players/{player_id}
Example Player
{
"id": "player_tt_101",
"name": "Player A",
"nationality": "EX",
"current_ranking": 8,
"profile": {
"status": "active"
}
}
Final player fields should reflect the production source and available licensing.
Retrieve Current Table Tennis Rankings
GET /v1/table-tennis/rankings
?ranking_date=latest
&page=1
&page_size=100
Example Ranking Record
{
"ranking_date": "2026-08-03",
"position": 8,
"previous_position": 10,
"movement": 2,
"points": 6420,
"player": {
"id": "player_tt_101",
"name": "Player A",
"nationality": "EX"
}
}
Retrieve Historical Rankings for One Player
GET /v1/table-tennis/players/{player_id}/rankings
?date_from=2025-01-01
&date_to=2026-08-07
{
"data": [
{
"date": "2026-06-01",
"position": 11,
"points": 5740
},
{
"date": "2026-07-06",
"position": 10,
"points": 6100
},
{
"date": "2026-08-03",
"position": 8,
"points": 6420
}
]
}
Retrieve Player Statistics
GET /v1/table-tennis/players/{player_id}/statistics
Example Filters
GET /v1/table-tennis/players/player_tt_101/statistics
?season=2026
&recent_matches=10
Example Statistics Response
{
"player_id": "player_tt_101",
"matches": {
"played": 42,
"won": 31,
"lost": 11,
"win_percentage": 73.8
},
"sets": {
"won": 112,
"lost": 66,
"win_percentage": 62.9
},
"form": {
"last_10": [
"W", "W", "L", "W", "W",
"W", "L", "W", "W", "W"
],
"current_win_streak": 5
}
}
Compare Two Table Tennis Players
GET /v1/table-tennis/head-to-head
?player_a_id=player_tt_101
&player_b_id=player_tt_204
&limit=10
Example H2H Response
{
"summary": {
"meetings": 10,
"player_a_wins": 6,
"player_b_wins": 4,
"player_a_sets_won": 24,
"player_b_sets_won": 19
},
"recent_form": {
"player_a": ["W", "W", "L", "W", "W"],
"player_b": ["W", "L", "W", "L", "W"]
}
}
Query Historical Table Tennis Data
Historical depth should be verified per competition and data category.
GET /v1/table-tennis/history
?player_id=player_tt_101
&date_from=2025-01-01
&date_to=2026-08-07
Historical Resources May Include
- Completed matches
- Set-by-set results
- Tournament history
- Ranking snapshots
- Player statistics
- Head-to-head meetings
Retrieve Odds Where Available
Odds should be treated as a separately covered and licensed product.
GET /v1/table-tennis/odds
?match_id=match_tt_48291
Retrieve Prediction Data Where Available
GET /v1/table-tennis/predictions
?match_id=match_tt_48291
Illustrative Response
{
"match_id": "match_tt_48291",
"probabilities": {
"player_a": 0.61,
"player_b": 0.39
},
"model_version": "MODEL_VERSION"
}
Connect to the Real-Time Table Tennis Stream
Illustrative WebSocket URL
wss://stream.example.com/v1/table-tennis
Browser clients should use a short-lived token or another approved client-safe mechanism rather than exposing permanent API credentials.
Illustrative Subscription
{
"action": "subscribe",
"channel": "table_tennis_match_events",
"match_ids": [
"match_tt_48291"
]
}
Illustrative Point Event
{
"event_id": "event_tt_90018",
"match_id": "match_tt_48291",
"type": "point_won",
"sequence": 73,
"set_number": 4,
"player_id": "player_tt_101",
"score": {
"player_a": 8,
"player_b": 6
}
}
Reconnect and Reconcile State Safely
1. Detect connection loss
2. Mark the match as reconnecting
3. Wait using controlled backoff
4. GET /matches/{match_id}
5. Replace local state with authoritative state
6. Reopen WebSocket
7. Authenticate
8. Resubscribe
9. Resume from supported sequence or replay position
10. Continue processing new events
Do not assume every event was received during a network interruption.
Paginate Large API Responses
Use pagination for tournaments, matches, players, rankings and historical resources when result sets are large.
GET /v1/table-tennis/rankings
?page=2
&page_size=100
Illustrative Pagination Object
{
"pagination": {
"page": 2,
"page_size": 100,
"total_items": 500,
"total_pages": 5
}
}
Common API Filters
| Filter | Example | Typical use |
|---|---|---|
| date | 2026-08-07 | Retrieve matches on one date |
| date_from | 2026-01-01 | Start of a historical range |
| date_to | 2026-08-07 | End of a historical range |
| tournament_id | tournament_211 | Limit results to one tournament |
| player_id | player_tt_101 | Retrieve resources for one player |
| status | live | Filter by documented resource state |
| sort | desc | Control result order |
Respect Plan Request Limits
Final request quotas and burst limits must come from the approved pricing structure.
Illustrative Response Headers
X-RateLimit-Limit: PLAN_LIMIT
X-RateLimit-Remaining: PLAN_REMAINING
X-RateLimit-Reset: RESET_TIMESTAMP
Recommended Client Behaviour
- Cache data shared by many users
- Avoid polling rankings like live scores
- Use exponential backoff after temporary errors
- Respect Retry-After where supplied
- Monitor quota usage before it reaches a plan limit
Handle API Errors Consistently
| Status | Meaning | Recommended action |
|---|---|---|
| 400 | Invalid request | Check parameters and request format |
| 401 | Authentication failed | Check API credentials |
| 403 | Access not allowed | Check plan, permissions or competition access |
| 404 | Resource not found | Check IDs and coverage |
| 422 | Validation error | Correct invalid parameter values |
| 429 | Rate limit reached | Back off and respect reset guidance |
| 500 | Server error | Retry safely with backoff |
| 503 | Temporary service unavailable | Retry later and use cached state where safe |
Illustrative Error Response
{
"error": {
"code": "INVALID_PARAMETER",
"message": "The tournament_id value is invalid.",
"request_id": "request_abc123"
}
}
Table Tennis API Example in JavaScript
const response = await fetch(
'https://api.example.com/v1/table-tennis/matches/live',
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json'
}
}
);
if (!response.ok) {
const body = await response.text();
throw new Error(
`API request failed (${response.status}): ${body}`
);
}
const payload = await response.json();
for (const match of payload.data) {
console.log(
match.player_a.name,
match.sets.player_a,
'-',
match.sets.player_b,
match.player_b.name
);
}
Table Tennis API Example in Python
import requests
response = requests.get(
"https://api.example.com/v1/table-tennis/matches/live",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
},
timeout=15,
)
response.raise_for_status()
payload = response.json()
for match in payload["data"]:
print(
match["player_a"]["name"],
match["sets"]["player_a"],
"-",
match["sets"]["player_b"],
match["player_b"]["name"],
)
Table Tennis API Example in PHP
<?php
$url = 'https://api.example.com/v1/table-tennis/matches/live';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Accept: application/json',
],
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) {
throw new RuntimeException(
'API request failed with HTTP ' . $status
);
}
$data = json_decode(
$body,
true,
512,
JSON_THROW_ON_ERROR
);
Cache Data According to How Often It Changes
| Resource | Recommended strategy |
|---|---|
| Live match state | Short-lived shared cache or WebSocket-updated state |
| Fixtures | Refresh around schedule changes |
| Results | Refresh after match completion, then cache longer |
| Rankings | Refresh after a new supported ranking release |
| Statistics | Refresh after relevant matches complete |
| Historical data | Long cache where licensing permits storage |
Build Around IDs, Not Display Names
Player names, tournament names and labels may change. Production applications should use stable IDs to connect data.
player_id
match_id
tournament_id
competition_id
ranking_id
event_id
Display names should be treated as presentation fields rather than database keys.
API Versioning
The illustrative examples use a version prefix in the URL.
/v1/table-tennis/...
Production Versioning Should Define
- How breaking changes create a new version
- How long older versions remain supported
- How deprecations are announced
- How fields are added without breaking clients
- How WebSocket event schema changes are handled
Recommended Production Integration
Your Web / Mobile Clients
↓
Your Backend API
↓
Cache / Match State Store
↓
Table Tennis REST API
For live products:
Table Tennis WebSocket API
↓
Connection Worker
↓
Validation + Deduplication
↓
Shared Match State
↓
Your WebSocket / SSE Layer
↓
Your Clients
Why Use a Backend Layer?
- Protect private API credentials
- Reduce duplicate upstream requests
- Cache shared data
- Control rate limits
- Normalise errors
- Store live event IDs
- Fan real-time events out to many users
Table Tennis API Production Checklist
- Confirm competition coverage before launch
- Keep permanent API keys on the backend
- Use stable IDs throughout your database
- Respect plan quotas and rate limits
- Cache slower-changing data
- Store completed set history
- Handle walkovers and retirements explicitly
- Make WebSocket event processing idempotent
- Track event sequence values where supported
- Reconcile state after WebSocket reconnects
- Log request IDs for debugging
- Monitor stale data and connection health
- Confirm storage and redistribution rights
- Pin your integration to a documented API version
Table Tennis API Documentation FAQs
What can I access through the Table Tennis API?
Depending on coverage, the API can expose fixtures, live scores, results, players, rankings, statistics, H2H and historical data.
Does the API support point-by-point scoring?
Point-level data may be available for supported competitions and plans.
Can I retrieve player rankings?
Ranking endpoints can provide current and historical ranking data where supported.
Does the API support WebSocket?
WebSocket can deliver supported live events such as points, sets and match-state changes.
Should I call the API directly from my browser?
Permanent private API credentials should stay on your backend.
How do I handle rate limits?
Cache shared data, reduce unnecessary polling and respect final production limit headers.
Can I retrieve historical data?
Historical depth depends on competition, data type and selected plan.
Can I use the data commercially?
Commercial display, storage and redistribution rights depend on the final licence and plan.
Are these endpoint URLs final?
No. The URLs and field names on this draft documentation page are illustrative until the production API specification is supplied.
Build With the Table Tennis API
Confirm competition coverage and pricing, then integrate fixtures, live scores, rankings, statistics, H2H and real-time events using the production API specification.