> ## Documentation Index
> Fetch the complete documentation index at: https://285e39fd5e337e58f16290.sightscreen.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Matches

> Match listing, live scores, match following, and Live Activity endpoints.

## Endpoint reference

| Method   | Route                                  | Auth  | Purpose                         |
| -------- | -------------------------------------- | ----- | ------------------------------- |
| `GET`    | `/matches`                             | User  | List matches with filters       |
| `GET`    | `/matches/live`                        | User  | All currently live matches      |
| `POST`   | `/matches/:matchId/activity-token`     | User  | Register/rotate LA update token |
| `POST`   | `/matches/:matchId/activity-dismissed` | User  | User dismissed a Live Activity  |
| `POST`   | `/user/follow/match`                   | User  | Follow a match                  |
| `PATCH`  | `/user/follow/match/:id/team`          | User  | Change supported team           |
| `DELETE` | `/user/follow/match/:id`               | User  | Unfollow a match                |
| `GET`    | `/admin/sportmonks/fixtures`           | Admin | Fetch fixtures from SportMonks  |
| `POST`   | `/admin/cache/clear`                   | Admin | Clear cached match data         |
| `GET`    | `/admin/cache/stats`                   | Admin | View cache statistics           |

***

## List matches

### GET /matches `User`

List matches with optional filters. Returns paginated results.

<ParamField query="league" type="string">
  Filter by league ID.
</ParamField>

<ParamField query="status" type="string">
  Filter by match status. Values: `upcoming`, `live`, `completed`.
</ParamField>

<ParamField query="from" type="string">
  ISO 8601 date string. Only return matches starting after this date.
</ParamField>

<ParamField query="to" type="string">
  ISO 8601 date string. Only return matches starting before this date.
</ParamField>

<Tabs>
  <Tab title="Request">
    ```
    GET /matches?league=bbl&status=live&from=2026-01-01&to=2026-03-31
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "matches": [
        {
          "id": "match-001",
          "league": "bbl",
          "status": "live",
          "teamA": { "id": "team-1", "name": "Sydney Sixers" },
          "teamB": { "id": "team-2", "name": "Melbourne Stars" },
          "startTime": "2026-01-15T18:00:00Z"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

### GET /matches/live `User`

Returns all currently live matches across all leagues. No query parameters.

```json theme={null}
{
  "matches": [
    {
      "id": "match-001",
      "status": "live",
      "league": "bbl",
      "score": { ... }
    }
  ]
}
```

***

## Live Activity management

These endpoints manage the Live Activity lifecycle for a match on the user's device.

### POST /matches/:matchId/activity-token `User`

Register or rotate a Live Activity update token for a specific match. The iOS app calls this after starting a Live Activity to give the backend the token needed to push updates.

<ParamField path="matchId" type="string" required>
  The match ID this token is associated with.
</ParamField>

<ParamField body="activityToken" type="string" required>
  The Live Activity push token from ActivityKit.
</ParamField>

<Tabs>
  <Tab title="Request">
    ```json theme={null}
    {
      "activityToken": "d8a3f1b2c4e5..."
    }
    ```
  </Tab>

  <Tab title="Response (200)">
    ```json theme={null}
    {
      "ok": true
    }
    ```
  </Tab>
</Tabs>

<Note>
  Tokens rotate when iOS restarts a Live Activity. The app should call this endpoint each time it receives a new token from ActivityKit.
</Note>

### POST /matches/:matchId/activity-dismissed `User`

Called when the user dismisses a Live Activity on their device. Triggers two actions:

1. Unfollows the match for this user (equivalent to `DELETE /user/follow/match/:id`).
2. Ends all Live Activity records for this user on the match.

<ParamField path="matchId" type="string" required>
  The match whose Live Activity was dismissed.
</ParamField>

<Tabs>
  <Tab title="Request">
    ```
    POST /matches/match-001/activity-dismissed
    ```
  </Tab>

  <Tab title="Response (200)">
    ```json theme={null}
    {
      "ok": true
    }
    ```
  </Tab>
</Tabs>

<Note>
  The dismissal delay is controlled by `LA_DISMISSAL_DELAY_MINUTES`. The backend waits this period before actually ending the LA, in case the user re-opens the app.
</Note>

***

## Match following

These endpoints manage which matches a user follows. Following a match enables Live Activity updates and score tracking.

<Note>
  See the [Match following](/business-flows/match-following) business flow for the full end-to-end journey.
</Note>

### POST /user/follow/match `User`

Follow a match. If the match is currently live, the backend also:

1. Creates pending Live Activity records for all of the user's registered devices.
2. Sends a push-to-start token via APNs to boot the Live Activity on each device.

<ParamField body="matchId" type="string" required>
  The match to follow.
</ParamField>

<ParamField body="teamId" type="string">
  Optional. The team the user supports in this match. Used to personalize the Live Activity display.
</ParamField>

<Tabs>
  <Tab title="Request">
    ```json theme={null}
    {
      "matchId": "match-001",
      "teamId": "team-1"
    }
    ```
  </Tab>

  <Tab title="Response (201)">
    ```json theme={null}
    {
      "followId": "follow-abc123",
      "matchId": "match-001",
      "teamId": "team-1",
      "liveActivityCreated": true
    }
    ```
  </Tab>
</Tabs>

<Note>
  `liveActivityCreated` is `true` when the match is live and LA records were created. It is `false` for upcoming matches -- the MatchOrchestrator will create LA records when the match goes live.
</Note>

### PATCH /user/follow/match/:id/team `User`

Change the supported team for a match the user is already following.

<ParamField path="id" type="string" required>
  The followed match ID.
</ParamField>

<ParamField body="teamId" type="string" required>
  The new team to support.
</ParamField>

### DELETE /user/follow/match/:id `User`

Unfollow a match. In addition to removing the follow record, this endpoint ends all active Live Activities for this user on the match by sending `end` events via APNs.

<ParamField path="id" type="string" required>
  The followed match ID.
</ParamField>

<Tabs>
  <Tab title="Response (200)">
    ```json theme={null}
    {
      "ok": true,
      "liveActivitiesEnded": 2
    }
    ```
  </Tab>
</Tabs>

***

## Admin match data

### GET /admin/sportmonks/fixtures `Admin`

Fetch fixtures directly from the SportMonks API. Useful for debugging data discrepancies.

### POST /admin/cache/clear `Admin`

Clear cached live match data. Forces the next poll cycle to fetch fresh data from SportMonks.

<ParamField body="matchId" type="string">
  Clear cache for a specific match. Omit to clear all cached data.
</ParamField>

### GET /admin/cache/stats `Admin`

View cache hit/miss statistics and memory usage.
