This guide explains the API, fields, and includes an in-browser explorer.
Examples:
curl -s http://localhost:5000/api/v1/scores | jq '.match_count, .last_updated'
curl -s http://localhost:5000/api/v1/scores/court/3 | jq '.matches[] | {matchid, court, matchstatus}'
curl -s http://localhost:5000/api/v1/match/12345 | jq
curl -X POST http://localhost:5000/api/v1/tourid/7140 | jq
Notes: all endpoints return JSON; errors include an error field; timestamps are Unix seconds in the match objects and a formatted string in last_updated.
Run a request against this server directly from your browser.
Response will appear hereβ¦
Top-level (GET /api/v1/scores)
status: success or error text.filter: description of court filter applied.tournament_id: current tournament being scraped.last_updated: latest match timestamp (formatted string).refresh_interval_seconds: scraper interval.match_count: number of matches returned.matches: array of match objects (see below).Match object (common fields)
matchid (string): unique match id.matchname (string): display title.court (string): court label/number.matchstatus (string): IN PROGRESS, COMPLETED, UPCOMING/PLAN, TEST.timestamp (int): Unix seconds of last update for this match.is_plan (int): 1 if planned/upcoming; 0 otherwise.schedtime (string): scheduled start time (may be empty).winner (string/int): winner flag; winner_name (string): name if completed.player1, player2: player display names.player1_country, player2_country: 3-letter country codes.player1_full, player2_full, player1_surname, player2_surname: raw name fields as provided.sets_played_count: number of sets reported (may be 0 for planned).game1, game2: current game score for p1/p2 (live only).player2serve: "1" means p1 serving, "2" means p2 serving.lastservetype: raw serve type flag (if present).tournid, eventid, extmid: source identifiers.cam, cameraurl, camerarooturl: camera metadata if provided.stats_general, stats_match: stats availability flags.Set fields
setN_p1, setN_p2 are set games; setN_tb is tie-break value when relevant.Single-match endpoint
GET /api/v1/match/<match_id> returns { status, match } or 404 with { error }.Tournament switch
GET/POST /api/v1/tourid/<new_tour_id> returns { status, message, new_tournament_id }; errors include { error }.Overlays pick a match in this order:
?matchid=123 in the URL forces that match (if it exists).Examples:
Scoreboard: /caspar/scoreboard/?matchid=12345
Bug: /caspar/bug/?matchid=12345
# Quick links from dashboard cards:
# - Bug button: adds matchid automatically
# - Scoreboard button: adds matchid automatically
Tip: Use the dashboard card buttons (βBugβ or βScoreboardβ) to open the overlay with matchid pre-filled.
The vMix script in this repo (file: vmix/scripting) automatically toggles serve indicators in your
scoreboard title based on live API data.
What you need in vMix first
SCOREBOARD (or change SCOREBOARD variable in script).MATCHID.Text containing the current match ID.SERVE_1.Source and SERVE_2.Source.How to install and run in vMix
vmix/scripting.SCOREBOARD to your title input name if different from default.API_BASE_URL to your server, for example https://scores.nkpa.co.uk/api/v1/match or your local endpoint.MATCHID.Text on the scoreboard input to the match you want to track.What the script is doing
500ms.MATCHID.Text from the SCOREBOARD title input./api/v1/match/<matchid> to get match JSON.player2serve from the JSON response.1: shows SERVE_1.Source, hides SERVE_2.Source.2: hides SERVE_1.Source, shows SERVE_2.Source.Troubleshooting
Scoreboard input not found, check the input name matches SCOREBOARD.Match ID not found, ensure MATCHID.Text exists and is populated./api/v1/match/<matchid> in a browser and checking player2serve.Quick copy: vMix script
Use this when you need to paste directly into Settings -> Scripting in vMix.
{
"matchid": "56789",
"matchname": "Centre Court QF",
"court": "1",
"matchstatus": "IN PROGRESS",
"timestamp": 1712505600,
"is_plan": 0,
"schedtime": "2025-12-13 14:00",
"winner": null,
"winner_name": null,
"player1": "Alex Morton",
"player2": "Diego Alvarez",
"player1_country": "GBR",
"player2_country": "ESP",
"player1_surname": "Morton",
"player2_surname": "Alvarez",
"sets_played_count": 2,
"game1": "30",
"game2": "15",
"player2serve": "2",
"set1_p1": 6,
"set1_p2": 4,
"set2_p1": 3,
"set2_p2": 6,
"set2_tb": "0",
"set3_p1": null,
"set3_p2": null,
"tournid": "7140",
"eventid": "E123",
"extmid": "EXT-56789",
"cam": null,
"cameraurl": null,
"camerarooturl": null,
"stats_general": 1,
"stats_match": 1
}