Partner API
REST reference
HTTPS request/response. Base URL: https://webservices.ledscount.com. Authenticate every request with the X-API-Key header.
Base URL: https://webservices.ledscount.com
· Auth: X-API-Key
· Rate limit: 60 req/min
/api/partner/startMatchConfigures a physical scoreboard for a match. The scoreboard resets, displays the player names, applies the scoring format, and is immediately ready for the players to score.
| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal ID for the club/venue (mapped to our system during onboarding). |
| matchID | Yes | Your internal match ID — used to retrieve scores later. |
| courtNumber | Yes | Court number at the venue (corresponds to the physical scoreboard). |
| scheduledTime | No | Scheduled start time in ISO 8601 format. Used for tournament grid display. If omitted, defaults to actual start time. |
| formatId | No | Scoring format from getMatchFormats. If omitted, the scoreboard keeps its current format. |
| teamRed / teamBlue | Yes | Player names (at least player1 for each team). |
| category | No | Match category (e.g. "Men's Singles", "Mixed Doubles"). |
| round | No | Round number (e.g. 4 for quarter-finals, 2 for semi-finals). |
| bracket | No | Bracket name (e.g. "Main Draw", "Consolation"). |
{
"customerID": "your_internal_club_id",
"matchID": "your_internal_match_id",
"courtNumber": "1",
"scheduledTime": "2026-03-25T10:30:00.000Z",
"formatId": "A1",
"teamRed": {
"player1": "John Smith",
"player2": "Jane Doe"
},
"teamBlue": {
"player1": "Carlos Garcia",
"player2": "Maria Lopez"
},
"category": "Men's Singles",
"round": 4,
"bracket": "Main Draw"
}json{
"success": true,
"matchID": "your_internal_match_id",
"deviceID": "24EC4A463394",
"courtNumber": "1",
"startTime": "2026-03-25T10:30:00.000Z"
}jsonError responses
400— Missing required fields, unknown customerID, or unknown formatId.404— No scoreboard found on the specified court.500— Internal server error.
/api/partner/getScoreRetrieves the current score from the physical scoreboard.
Purpose: Call this endpoint whenever you need the current score — for example, to pre-fill the score entry in your UI when a referee opens a match, or to check if a match has finished (playing: false) so the bracket can be advanced automatically.
GET /api/partner/getScore?customerID=your_internal_club_id&matchID=your_internal_match_idhttp{
"success": true,
"matchID": "your_internal_match_id",
"courtNumber": "1",
"playing": true,
"score": {
"teamRed": {
"sets": [6, 4, 0],
"points": 30
},
"teamBlue": {
"sets": [3, 6, 0],
"points": 15
}
},
"teamServing": "teamRed",
"startedAt": "2026-03-25T10:30:00.000Z",
"lastPointAt": "2026-03-25T11:05:23.000Z"
}jsonError responses
400— Missing required parameters or unknown customerID.404— Match not found.500— Internal server error.
/api/partner/getDeviceStatusReturns the current state of a scoreboard and its paired streaming encoder (if any) on a specific court. Response fields are read-only — the table above describes them rather than parameters you send.
GET /api/partner/getDeviceStatus?customerID=your_internal_club_id&courtNumber=1http| Field | Required | Description |
|---|---|---|
| lastSettingsRequest | No | ISO timestamp of the scoreboard's last server check-in. A recent value means the scoreboard is online. |
| deviceID | No | Internal LedsCount scoreboard identifier. |
| encoderMac | No | MAC of the streaming encoder paired with this court (empty if none). |
| encoderActive | No | true when the encoder is currently connected to the server (live check). |
| youtubeStream | No | true while a YouTube broadcast is running for this court. |
| youtubeStreamStartedAt | No | ISO timestamp when the current broadcast started (null when not streaming). |
{
"success": true,
"courtNumber": "1",
"deviceID": "24EC4A463394",
"lastSettingsRequest": "2026-03-25T09:45:12.000Z",
"encoderActive": true,
"encoderMac": "88A29E48E7B6",
"youtubeStream": false,
"youtubeStreamStartedAt": null
}json/api/partner/restartDeviceRemotely restarts a scoreboard.
| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
| courtNumber | Yes | Court whose scoreboard should restart. |
{
"customerID": "your_internal_club_id",
"courtNumber": "1"
}json/api/partner/getAllScoresReturns the current score for all scoreboards at a venue. Useful for filling a "live scoreboard" grid across the tournament.
GET /api/partner/getAllScores?customerID=your_internal_club_idhttp| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
/api/partner/getMatchFormatsReturns all available scoring formats with their full configuration and multi-language descriptions.
Purpose: Allows you to map your own format definitions to ours, or present our supported formats to tournament organisers. The formatId can be passed when starting a match. This is not mandatory — the scoring format can also be configured directly on the scoreboard by the tournament organiser or referee.
{
"success": true,
"formats": [
{
"formatId": "A1",
"name": "Best of 3 sets (6 games, advantage)",
"shortName": "A1",
"sport": "tennis",
"descriptions": {
"en": "3 sets to 6 games, tiebreak at 6-6, advantage scoring",
"es": "3 sets a 6 juegos, tiebreak en 6-6, ventaja",
"fr": "3 sets de 6 jeux, tiebreak a 6-6, avantage",
"nl": "3 sets tot 6 games, tiebreak bij 6-6, voordeel"
},
"setsToWin": 1,
"gamesToWinSet": 6,
"tiebreakAt": 6,
"tiebreakPoints": 7,
"superTiebreak": false,
"deuceFormat": "advantage",
"active": true,
"category": "official"
}
]
}json/api/partner/getAllowedFormatsReturns the scoring formats permitted on a specific court. Some venues restrict which formats can be played on which court (e.g. only padel formats on padel courts). When no restriction is set on the court, all active formats are returned.
Purpose: When you let an operator pick a scoring format for a match, this endpoint gives you the list relevant for that court so the dropdown can be filtered correctly. The formats array is sorted by index. Each entry has the same shape as in getMatchFormats — refer there for the full field list.
GET /api/partner/getAllowedFormats?customerID=your_internal_club_id&courtNumber=1http| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
| courtNumber | Yes | Court number whose allowed formats to return. |
{
"success": true,
"courtNumber": "1",
"formats": [
{
"formatId": "A1",
"name": "Best of 3 sets (6 games, advantage)",
"shortName": "A1",
"descriptions": {
"en": "3 sets to 6 games, tiebreak at 6-6, advantage scoring",
"es": "3 sets a 6 juegos, tiebreak en 6-6, ventaja"
},
"active": true
}
]
}jsonError responses
400— Missing required parameters or unknown customerID.404— No scoreboard found on the specified court.500— Internal server error.
/api/partner/callPagerTriggers an RF call to a numbered pager on the venue's pager-reader (e.g. to alert a player that their court is ready). The endpoint waits for the pager-reader to confirm the RF burst before responding (typically 5–7 s), so the response status reflects whether the page actually went out.
| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
| pagerNumber | Yes | Pager number to call (integer 0–999). |
{
"customerID": "your_internal_club_id",
"pagerNumber": 7
}json{
"success": true,
"status": "sent",
"pagerReaderID": "AABBCCDDEEFF",
"pagerNumber": 7
}json{
"success": false,
"status": "rejected",
"pagerReaderID": "AABBCCDDEEFF",
"pagerNumber": 1500
}jsonError responses
400— Missing fields, unknown customerID, or pagerNumber outside 0–999.404— No pager reader assigned to this club.503— Pager reader not connected.504— status: "timeout" — no delivery confirmation within 10 s.500— Internal server error.
/api/partner/startYoutubeStreamStarts a YouTube live broadcast for the scoreboard on the specified court. The court must have a streaming encoder paired and online — the endpoint validates this with a live check before allocating any YouTube resources, so a stale encoder won't leave an orphan broadcast on YouTube.
A scoreboard score overlay (player names + live score) is rendered on the server and pushed to the encoder; the encoder ingests its USB camera and overlays the score before pushing RTMP to YouTube. Once the broadcast is created, the score overlay updates automatically every time the scoreboard reports a new point.
| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
| courtNumber | Yes | Court whose scoreboard should start streaming. |
| unlisted | No | If true, the YouTube broadcast is created as unlisted (only accessible via direct link). Defaults to the scoreboard's stored preference. |
| timer | No | Auto-stop after N minutes (e.g. 60, 90, 120). 0 disables. Defaults to the scoreboard's stored preference. |
| freshMatch | No | If true, the OSD's first frame uses 0–0 + the current player names instead of carrying over the previous match's score. Recommended right after startMatch. |
{
"customerID": "your_internal_club_id",
"courtNumber": "1",
"unlisted": false,
"timer": 90,
"freshMatch": true
}json{
"success": true,
"courtNumber": "1",
"broadcastId": "WB0OW-cwigM",
"rtmpUrl": "rtmp://a.rtmp.youtube.com/live2/abcd-1234-…"
}jsonbroadcastId is the YouTube broadcast ID — build a watch URL from it:
https://youtube.com/watch?v=<broadcastId>
.
Error responses
400— Missing fields, unknown customerID, or no encoder paired with the court.404— No scoreboard found on the specified court.500— Encoder offline, no YouTube refresh token configured for the club, or YouTube API failure.
/api/partner/stopYoutubeStream
Stops the YouTube live broadcast for the specified court. The broadcast is transitioned to complete on YouTube, the encoder is told to stop pushing RTMP, and all stream-side fields are wiped — the next start will allocate a fresh YouTube stream resource.
| Field | Required | Description |
|---|---|---|
| customerID | Yes | Your internal club/venue ID. |
| courtNumber | Yes | Court whose broadcast should stop. |
{
"customerID": "your_internal_club_id",
"courtNumber": "1"
}json{
"success": true,
"courtNumber": "1"
}jsonError responses
400— Missing fields or unknown customerID.404— No scoreboard found on the specified court.500— Internal server error.