Developer reference

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.

REST API WebSocket JSON Developer Examples
GET Live Matches JSON
GET /v1/table-tennis/matches/live

Authorization:
Bearer YOUR_API_KEY

{
  "data": [
    {
      "match_id": "match_tt_48291",
      "status": "live",
      "current_set": 4
    }
  ]
}
Integrate REST Endpoints Fixtures, rankings, statistics and history
Stream Live Events Points, sets and match-state changes
Implementation notice: Base URL, authentication method, endpoint paths, field names, request limits, ranking sources, WebSocket protocol, event names and response examples on this page are placeholders until the final production API specification is supplied. Replace all illustrative values before publishing.
Documentation overview

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
Quick start

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
      }
    }
  ]
}
Authentication

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
Coverage endpoint

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
    }
  }
}
Tournaments

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"
}
Fixtures

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"
  }
}
Live scores

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"
}
Match details

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.

Point-by-point events

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
Results

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}
  ]
}
Walkovers and retirements

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.

Players

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.

Rankings

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"
  }
}
Ranking history

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
    }
  ]
}
Statistics

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
  }
}
Head-to-head

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"]
  }
}
Historical data

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
Odds

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
Do not publish bookmaker, market or live-odds claims until production coverage and licensing are confirmed.
Predictions

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"
}
Prediction outputs are estimates, not guaranteed results. Availability and final response fields must be confirmed.
WebSocket

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
  }
}
WebSocket recovery

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.

Pagination

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
  }
}
Final pagination method may use pages, cursors or another production model.
Filtering

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
Rate limits

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
Errors

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"
  }
}
JavaScript example

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
  );
}
Python example

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"],
    )
PHP example

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
);
Caching

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
Stable identifiers

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.

Versioning

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
Production architecture

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
Production checklist

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
Frequently asked questions

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.

Start integrating table tennis data

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.

Chat on WhatsApp