Endpoints

Five read-only endpoints, all under https://api.scored.app/v1. Each returns { success, message, data }; the shapes below are the contents of data.

Shared query parameters

  • leagueUID — restrict to one league.
  • teamUID — restrict to one team (results and fixtures).
  • sportId — restrict to one sport (results and fixtures).
  • status — restrict results by fixture status.
  • page — page number for the paginated endpoints.

Any UID you pass must belong to your own organisation. A foreign or malformed one is 404.

GET /v1/results

Completed match results, newest first, paginated. This is the endpoint behind a "latest results" table.

{
  "results": [
    {
      "fixtureUID": "aaaaaaaa-0000-0000-0000-000000000031",
      "startTime": "2026-08-16T04:00:00.000Z",
      "facility": { "facilityUID": "fac-1", "name": "Court 1" },
      "league": {
        "leagueUID": "aaaaaaaa-0000-0000-0000-000000000005",
        "name": "Tuesday Night Netball",
        "style": "#1d4ed8",
        "partnerships": null,
        "sportId": 2,
        "sport": "Netball"
      },
      "teamOne": {
        "teamUID": "858bf080-5413-11f0-b70c-0ab4d4ca3065",
        "name": "Eagles",
        "logoUrl": "https://...webp",
        "score": 47,
        "skins": [12, 11, 13, 11],
        "skinsWon": 3,
        "tableRank": 1, "played": 14, "wins": 8, "losses": 5, "draws": 1,
        "for": 620, "against": 540, "totalPoints": 25
      },
      "teamTwo": { "...": "same shape" },
      "defaultedTeamUID": null
    }
  ],
  "pagination": { "page": 1, "totalPages": 3, "total": 58 }
}

skins is the score broken down within the match. For period sports it is the score in each period; for cricket it is the partnership scores. It is an empty array for sports that do not break a score down.

On the league block, style is the league's branding colour — a CSS colour or gradient string chosen in Scored, there so your own page can match the league's look. It is not a competition format, and it is null when no colour has been set. partnerships is a cricket setting and is null for other sports.

GET /v1/standings/:leagueUID

The ladder for one league, already ordered — position is 1 for the top of the table. The league UID goes in the path, not the query string.

[
  {
    "position": 1,
    "team": { "teamUID": "858bf080-...", "name": "Eagles", "logoUrl": "https://...webp" },
    "grade": { "name": "Division 1", "rank": 1 },
    "played": 14,
    "wins": 8,
    "losses": 5,
    "draws": 1,
    "for": 620,
    "against": 540,
    "points": 25
  }
]

GET /v1/fixtures

Scheduled matches, paginated — the endpoint behind a "this weekend" list. Unlike results, a fixture may not have been played yet, so there are no scores.

{
  "fixtures": [
    {
      "fixtureUID": "aaaaaaaa-0000-0000-0000-000000000031",
      "status": "Scheduled",
      "startTime": "2026-08-23T04:00:00.000Z",
      "facility": { "facilityUID": "fac-1", "name": "Court 1" },
      "league": { "leagueUID": "...", "name": "Tuesday Night Netball", "sportId": 2, "sport": "Netball" },
      "teamOne": { "teamUID": "...", "name": "Eagles", "logoUrl": "https://...webp" },
      "teamTwo": { "teamUID": "...", "name": "Falcons", "logoUrl": null }
    }
  ],
  "pagination": { "page": 1, "totalPages": 2, "total": 24 }
}

A team block is null when the fixture has no team on that side yet — a bye, or a draw that has not been filled in.

GET /v1/teams

Season totals per team. Accepts leagueUID. Returns an array, not a paginated object.

[
  {
    "team": { "teamUID": "858bf080-...", "name": "Eagles", "logoUrl": "https://...webp" },
    "leagueUID": "aaaaaaaa-0000-0000-0000-000000000005",
    "stats": {
      "runs": 1967,
      "wickets": 43,
      "avgRunRate": 10.85,
      "wins": 8,
      "draws": 0,
      "losses": 5,
      "highestTeamScore": 472
    }
  }
]

The statistics are sport-appropriate — the fields above are a cricket league. leagueUID is null for a team not tied to a single league.

GET /v1/players

Per-player season statistics. Accepts leagueUID. This endpoint returns an empty list until your organisation opts in — see Player data before you build against it.

[
  {
    "player": {
      "userUID": "cd044be9-0308-4e6b-8248-1cc7d3051247",
      "name": "Daniel Sutherland",
      "profilePictureUrl": "https://...webp",
      "country": "NZ"
    },
    "stats": {
      "matches": 37,
      "totalRuns": 666,
      "totalBallsFaced": 345,
      "totalWickets": 0,
      "totalOvers": 37,
      "totalRunsConceded": 419,
      "fours": 49,
      "sixes": 1,
      "sevens": 7,
      "catches": 0,
      "runouts": 0,
      "stumps": 0,
      "highestScore": 72,
      "avgEconomyRate": 5.95,
      "avgStrikeRate": 152.02
    }
  }
]

A worked example

Putting one league's ladder on your own site, cached for a minute so page views never reach the rate limit:

// server-side, so the key is never sent to the browser
const LEAGUE = "aaaaaaaa-0000-0000-0000-000000000005";

export async function getLadder() {
  const response = await fetch(
    `https://api.scored.app/v1/standings/${LEAGUE}`,
    {
      headers: { "X-Api-Key": process.env.SCORED_API_KEY },
      next: { revalidate: 60 },
    },
  );

  if (!response.ok) {
    // 404 means the league UID is not one of ours; 429 means slow down.
    throw new Error(`Scored API returned ${response.status}`);
  }

  const { data } = await response.json();
  return data; // already ordered by position
}

How the contract changes

/v1 is append-only. New fields may appear, but existing fields will not be renamed, retyped or removed within the version — so read the fields you need and ignore the rest rather than validating the whole object strictly. A breaking change would arrive as /v2, with /v1 still answering.

Endpoints
Public API