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

POST /api/partner/startMatch

Configures 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
customerIDYesYour internal ID for the club/venue (mapped to our system during onboarding).
matchIDYesYour internal match ID — used to retrieve scores later.
courtNumberYesCourt number at the venue (corresponds to the physical scoreboard).
scheduledTimeNoScheduled start time in ISO 8601 format. Used for tournament grid display. If omitted, defaults to actual start time.
formatIdNoScoring format from getMatchFormats. If omitted, the scoreboard keeps its current format.
teamRed / teamBlueYesPlayer names (at least player1 for each team).
categoryNoMatch category (e.g. "Men's Singles", "Mixed Doubles").
roundNoRound number (e.g. 4 for quarter-finals, 2 for semi-finals).
bracketNoBracket name (e.g. "Main Draw", "Consolation").
Request
{
  "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
Response
{
  "success": true,
  "matchID": "your_internal_match_id",
  "deviceID": "24EC4A463394",
  "courtNumber": "1",
  "startTime": "2026-03-25T10:30:00.000Z"
}
json

Error responses

  • 400 — Missing required fields, unknown customerID, or unknown formatId.
  • 404 — No scoreboard found on the specified court.
  • 500 — Internal server error.
GET /api/partner/getScore

Retrieves 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.

Example
GET /api/partner/getScore?customerID=your_internal_club_id&matchID=your_internal_match_id
http
Response
{
  "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"
}
json

Error responses

  • 400 — Missing required parameters or unknown customerID.
  • 404 — Match not found.
  • 500 — Internal server error.
GET /api/partner/getDeviceStatus

Returns 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.

Example
GET /api/partner/getDeviceStatus?customerID=your_internal_club_id&courtNumber=1
http
Field Required Description
lastSettingsRequestNoISO timestamp of the scoreboard's last server check-in. A recent value means the scoreboard is online.
deviceIDNoInternal LedsCount scoreboard identifier.
encoderMacNoMAC of the streaming encoder paired with this court (empty if none).
encoderActiveNotrue when the encoder is currently connected to the server (live check).
youtubeStreamNotrue while a YouTube broadcast is running for this court.
youtubeStreamStartedAtNoISO timestamp when the current broadcast started (null when not streaming).
Response
{
  "success": true,
  "courtNumber": "1",
  "deviceID": "24EC4A463394",
  "lastSettingsRequest": "2026-03-25T09:45:12.000Z",
  "encoderActive": true,
  "encoderMac": "88A29E48E7B6",
  "youtubeStream": false,
  "youtubeStreamStartedAt": null
}
json
POST /api/partner/restartDevice

Remotely restarts a scoreboard.

Field Required Description
customerIDYesYour internal club/venue ID.
courtNumberYesCourt whose scoreboard should restart.
Request
{
  "customerID": "your_internal_club_id",
  "courtNumber": "1"
}
json
GET /api/partner/getAllScores

Returns the current score for all scoreboards at a venue. Useful for filling a "live scoreboard" grid across the tournament.

Example
GET /api/partner/getAllScores?customerID=your_internal_club_id
http
Field Required Description
customerIDYesYour internal club/venue ID.
GET /api/partner/getMatchFormats

Returns 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.

Response
{
  "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
GET /api/partner/getAllowedFormats

Returns 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.

Example
GET /api/partner/getAllowedFormats?customerID=your_internal_club_id&courtNumber=1
http
Field Required Description
customerIDYesYour internal club/venue ID.
courtNumberYesCourt number whose allowed formats to return.
Response
{
  "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
    }
  ]
}
json

Error responses

  • 400 — Missing required parameters or unknown customerID.
  • 404 — No scoreboard found on the specified court.
  • 500 — Internal server error.
POST /api/partner/callPager

Triggers 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
customerIDYesYour internal club/venue ID.
pagerNumberYesPager number to call (integer 0–999).
Request
{
  "customerID": "your_internal_club_id",
  "pagerNumber": 7
}
json
Response (delivered)
{
  "success": true,
  "status": "sent",
  "pagerReaderID": "AABBCCDDEEFF",
  "pagerNumber": 7
}
json
Response (rejected — number out of range)
{
  "success": false,
  "status": "rejected",
  "pagerReaderID": "AABBCCDDEEFF",
  "pagerNumber": 1500
}
json

Error 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.
POST /api/partner/startYoutubeStream

Starts 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
customerIDYesYour internal club/venue ID.
courtNumberYesCourt whose scoreboard should start streaming.
unlistedNoIf true, the YouTube broadcast is created as unlisted (only accessible via direct link). Defaults to the scoreboard's stored preference.
timerNoAuto-stop after N minutes (e.g. 60, 90, 120). 0 disables. Defaults to the scoreboard's stored preference.
freshMatchNoIf 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.
Request
{
  "customerID": "your_internal_club_id",
  "courtNumber": "1",
  "unlisted": false,
  "timer": 90,
  "freshMatch": true
}
json
Response
{
  "success": true,
  "courtNumber": "1",
  "broadcastId": "WB0OW-cwigM",
  "rtmpUrl": "rtmp://a.rtmp.youtube.com/live2/abcd-1234-…"
}
json

broadcastId 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.
POST /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
customerIDYesYour internal club/venue ID.
courtNumberYesCourt whose broadcast should stop.
Request
{
  "customerID": "your_internal_club_id",
  "courtNumber": "1"
}
json
Response
{
  "success": true,
  "courtNumber": "1"
}
json

Error responses

  • 400 — Missing fields or unknown customerID.
  • 404 — No scoreboard found on the specified court.
  • 500 — Internal server error.