Developer Platform

Open Scoreboard API

Technical documentation for the current v1 REST API, with copyable examples, route-by-route notes, and authenticated personal API key management.

Public developer docs

Player Lists

Player lists are the main public v1 resource for reusable participant directories, seeded roster data, and table-side player selection.

Available in v1

Use PUT /player-lists for idempotent full syncs, GET for reads, and PATCH /player-lists/{externalID} when you need incremental upserts or removals for integration-managed players only.

Collection routeGET/PUT /player-lists
Record routeGET/PATCH /player-lists/{externalID}
Paginationlimit + cursor

Implementation notes

  • PATCH preserves manually managed entries and touches only players mapped by the current connection.
  • Collection GET can return the full set or a paginated page depending on whether limit/cursor is provided.
  • External IDs are partner-owned identifiers and form the idempotency key for sync operations.

Endpoints

OpenAPI
PUT/player-lists

Create or replace a player list

Synchronize a full player-list record keyed by your externalID.

player_lists.write
Response

Returns the synchronized player list and mapped players.

curl
curl -X PUT https://your-domain.example/api/v1/player-lists \
  -H "Authorization: Bearer osb_test_your_key_here" \
  -H "Content-Type: application/json" \
  -H "OpenScoreboard-Request-ID: demo-request-001" \
  -d '{
    "externalID": "summer-open-singles",
    "name": "Summer Open Singles",
    "description": "Imported from the partner registration system",
    "players": [
      {
        "externalID": "player-1001",
        "firstName": "Ava",
        "lastName": "Nguyen",
        "country": "USA",
        "rating": 2142
      },
      {
        "externalID": "player-1002",
        "firstName": "Noah",
        "lastName": "Patel",
        "country": "CAN",
        "rating": 2091
      }
    ]
  }'
JavaScript
const baseURL = "https://your-domain.example/api/v1";
const apiKey = "osb_test_your_key_here";

async function api(path, init = {}) {
  const response = await fetch(`${baseURL}${path}`, {
    ...init,
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      "OpenScoreboard-Request-ID": "demo-request-001",
      ...(init.headers || {})
    }
  });

  const body = await response.json();
  if (!response.ok) {
    throw new Error(body.error?.message || "Request failed");
  }

  return body.data;
}

const playerList = await api("/player-lists", {
  method: "PUT",
  body: JSON.stringify({
    externalID: "summer-open-singles",
    name: "Summer Open Singles",
    description: "Imported from the partner registration system",
    players: [
      { externalID: "player-1001", firstName: "Ava", lastName: "Nguyen", country: "USA", rating: 2142 },
      { externalID: "player-1002", firstName: "Noah", lastName: "Patel", country: "CAN", rating: 2091 }
    ]
  })
});

console.log(playerList.externalID, playerList.players.length);
PATCH/player-lists/{externalID}

Patch only the integration-managed players

Incrementally upsert or remove mapped players without replacing the whole list.

player_lists.write
Response

Returns the updated player list.

  • Send upsert to replace specific mapped players by externalID.
  • Send removeExternalIDs to remove mapped players without touching manual entries.
curl
curl -X PATCH https://your-domain.example/api/v1/player-lists/summer-open-singles \
  -H "Authorization: Bearer osb_test_your_key_here" \
  -H "Content-Type: application/json" \
  -H "OpenScoreboard-Request-ID: demo-request-001" \
  -d '{
    "upsert": [
      {
        "externalID": "player-1001",
        "firstName": "Ava",
        "lastName": "Nguyen",
        "country": "USA",
        "rating": 2165
      }
    ],
    "removeExternalIDs": ["player-1999"]
  }'
JavaScript
const baseURL = "https://your-domain.example/api/v1";
const apiKey = "osb_test_your_key_here";

async function api(path, init = {}) {
  const response = await fetch(`${baseURL}${path}`, {
    ...init,
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      "OpenScoreboard-Request-ID": "demo-request-001",
      ...(init.headers || {})
    }
  });

  const body = await response.json();
  if (!response.ok) {
    throw new Error(body.error?.message || "Request failed");
  }

  return body.data;
}

await api("/player-lists/summer-open-singles", {
  method: "PATCH",
  body: JSON.stringify({
    upsert: [
      { externalID: "player-1001", firstName: "Ava", lastName: "Nguyen", rating: 2165 }
    ],
    removeExternalIDs: ["player-1999"]
  })
});