> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akaramarkets.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sessions catalog

> List the sessions you may watch — open or closed — across every sport

## Endpoint

```
GET /api/sessions
```

Top-level — no sport prefix. One call returns every session you may watch, across all sports.
Each session carries two orthogonal fields: **`league` says which competition it is** (a filter
and a label — access is granted per session, not per league); **`sport` says how to parse** (which
event vocabulary and state shape the feed speaks). `sessionId` is the `{session}` segment for `WS /api/subscribe/{session}` and
`GET /api/history/{session}` directly — the feed URLs carry no sport.

### Query parameters

| Parameter | Values                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                               |
| --------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`  | `open` (default) \| `closed`             | Which end of a session's open→closed lifecycle to list. `open` — sessions currently published and still streaming. `closed` — sessions that were published and have since closed: no longer streaming, but their full tape stays readable via [`/history`](/api-reference/history). Any other value is a `422`. A session that was never published appears in **neither** slice.                                                          |
| `league`  | any league slug (optional, single value) | Narrow the list to one league (e.g. `?league=nba`), composable with `status`. The filter only ever **narrows** what you may already see: it selects among the sessions you were granted plus the public ones, and never widens access. An unknown or misspelled league returns `200` with an empty list, not an error — new leagues join the vocabulary over time, so an unrecognised value is an empty result, never an existence probe. |
| `sandbox` | `true` (optional)                        | A **mode switch**, not a filter: list only your own [sandbox mock sessions](/sandbox) instead of real games. The default listing (no parameter) **never** contains sandbox sessions — a pipeline polling this catalog cannot ingest a mock by accident. Composable with `status` and `league`.                                                                                                                                            |
| `limit`   | positive integer (optional)              | Cap the number of rows returned to the first `N` in the status ordering — so `?status=closed&limit=25` is "the 25 most-recently-closed sessions". Bounds an otherwise unbounded history. Omitted (or a non-positive value) means no cap. Composable with `status` and `league`.                                                                                                                                                           |

### League slugs

`league` values are deliberately terse abbreviations. The vocabulary grows as new leagues go
live — each addition appears here, and every league always maps to exactly one `sport` value.
Currently:

| Slug    | League                |
| ------- | --------------------- |
| `nba`   | NBA                   |
| `wnba`  | WNBA                  |
| `ncaab` | NCAA Men's Basketball |
| `mlb`   | MLB                   |
| `wc`    | FIFA World Cup        |

### Authentication

A valid token is required — an `ss_` API key or JWT, sent as a Bearer token or the `?token=` query
parameter, the same credential as `/subscribe`. There is no anonymous access — every request
requires a valid token; a session being public waives the entitlement, not authentication.
Entitlements decide what you see (identically for both statuses):

| Caller           | Result                                                                                          |
| ---------------- | ----------------------------------------------------------------------------------------------- |
| Consumer         | `200` — the sessions your account was granted plus all public sessions, deduped, granted first. |
| Operator / scout | `200` — all sessions, unfiltered.                                                               |

See [Authentication](/authentication) for token formats.

### Error responses

| Status | Condition                          |
| ------ | ---------------------------------- |
| `401`  | Missing or invalid token           |
| `422`  | `status` is not `open` or `closed` |

***

## Response

```json theme={null}
{
  "sessions": [
    {
      "sessionId": "wc-arg-bra",
      "gameId": "sb-2026-07-09-arg-bra",
      "league": "wc",
      "sport": "soccer",
      "matchup": { "a": "Argentina", "b": "Brazil" },
      "score": { "a": 1, "b": 0 },
      "openedAt": "2026-07-09T17:45:00+00:00",
      "publishedAt": "2026-07-09T18:30:00+00:00",
      "closedAt": null,
      "historyAvailable": true
    }
  ]
}
```

| Field              | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sessionId`        | string         | The session id — the `{session}` segment for `/api/subscribe/{session}` and `/api/history/{session}`                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `gameId`           | string \| null | The game this session records — shared by all sessions covering the same game; `null` for manually-created sessions. This is what you group by if you want a game-level view                                                                                                                                                                                                                                                                                                                                                                                       |
| `league`           | string         | League slug (e.g. `nba`, `wnba`, `wc`). Entitlements are keyed by this — it decides whether the session appears in *your* catalog                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `sport`            | string         | Which sport this session is: `"basketball"`, `"soccer"`, `"baseball"`, or `"football"`. Always present — every league maps to exactly one sport, and sessions can only exist under a known league. Not needed for URL-building — it tells you which event vocabulary and state shape to parse the feed with. The same value also arrives **in-stream** — on the [WebSocket hello frame](/api-reference/websocket#connection-flow) and the [`/history` response](/api-reference/history#response) — so a stored session id is self-describing without a catalog row |
| `matchup`          | object         | The side display names `{ a, b }`, fixed when the session was created. Same value the WebSocket carries as the top-level `matchup` on every frame                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `score`            | object \| null | The score `{ a, b }`, aligned to `matchup`. On `status=open` rows it is the live running score; on `status=closed` rows it is the final score, fixed when the session ended. `null` when unavailable — a live session with no active feed, or a session that closed before scores were recorded. For a live session, the [WebSocket](/api-reference/websocket) carries the authoritative running score on every frame; this field is a convenience for a catalog-only view                                                                                         |
| `openedAt`         | string \| null | ISO-8601 timestamp when the session opened. `null` for sessions from before 2026-07-10 — the column postdates them; an exact backfill is pending                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `publishedAt`      | string \| null | ISO-8601 timestamp when the session was published to the catalog                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `closedAt`         | string \| null | ISO-8601 timestamp when the session closed. Always `null` on `status=open` rows; always set on `status=closed` rows                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `historyAvailable` | boolean        | Whether [`/history`](/api-reference/history) can serve this session's event log right now. Almost always `true`; `false` marks the rare session whose stored log was lost (storage incident) — its `/history` answers `410`, so skip the fetch. Open sessions are effectively always `true`                                                                                                                                                                                                                                                                        |

**Ordering** is newest-first within each status: `status=open` by `publishedAt` (most recently
published first), `status=closed` by `closedAt` (most recently closed first). An entitled caller sees
their granted sessions first, then the remaining public sessions, each block ordered the same way.

Sessions move from `status=open` to `status=closed` when they close — a finished session stops
streaming but stays discoverable here and readable via [`/history`](/api-reference/history).
