# Admin API reference

The Admin REST API provides programmatic access to manage uproot experiments.
All endpoints are located under `/admin/api/v1/` and require Bearer token authentication, except where noted.

!!! note "Generated from FastAPI OpenAPI"
    This page is generated by `scripts/generate_admin_api_docs.py` from FastAPI’s OpenAPI schema. A running uproot server also exposes FastAPI’s live schema at `/openapi.json` and interactive documentation at `/docs` and `/redoc`.

## Authentication

All requests must include an `Authorization` header with a valid API token:

```http
Authorization: Bearer YOUR_API_TOKEN
```

To enable API access, add one or more tokens in your project’s `main.py`:

```python
upd.API_KEYS.add("YOUR_API_TOKEN")
```

## Errors

Errors are returned as JSON with a `detail` field:

```json
{"detail": "Session not found"}
```

These status codes are shared by many endpoints and are not repeated below:

| Status | Meaning |
|--------|---------|
| `400` | The request is invalid, e.g. an unknown configuration or a duplicate name |
| `401` | The Bearer token is missing or invalid |
| `404` | A session, player, room, configuration, digest, or pipeline named in the request does not exist |
| `422` | Parameters or request body do not match the expected types; `detail` is a list of problems |

The **Responses** tables below list successful responses and errors specific to one endpoint.

## CLI access

The `uproot api` command calls these endpoints from the command line:

```bash
export UPROOT_API_KEY="YOUR_API_TOKEN"
uproot api sessions
uproot api sessions/mysession
uproot api rooms
uproot api rooms/waiting-room
uproot api sessions/mysession/online-players
uproot api sessions/mysession/players/ABC
uproot api -X POST sessions -d '{"config": "myconfig", "n_players": 4}'
uproot api -X PATCH sessions/mysession/active -d '{"active": false}'
uproot api -X POST sessions/mysession/players/advance -d '{"unames": ["ABC"]}'
```

## Dashboard and configurations

### `GET /admin/api/v1/configs/`

List all available configurations and apps.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/configs/{cname}/`

Get details for a configuration.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `cname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/dashboard/`

Get the same top-level aggregate shown on the admin dashboard.

!!! note
    The response contains `uproot_version`, `nudge_announcements` (whether the admin UI currently nudges you to check announcements), `configs`, `rooms`, and `active_sessions`.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

## Sessions

### `GET /admin/api/v1/sessions/`

List all sessions with their metadata.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/`

Create a new session with the specified configuration and players.

**Request body** (`SessionCreate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `config`{ .text-nowrap } | string | Yes | Configuration name |
| `n_players`{ .text-nowrap } | integer | Yes | Number of players to create (min: `0.0`) |
| `sname`{ .text-nowrap } | string or null | No | Custom session name (auto-generated if omitted) |
| `unames`{ .text-nowrap } | array[string] or null | No | Custom usernames for players |
| `settings`{ .text-nowrap } | object or null | No | Session settings |
| `simulate`{ .text-nowrap } | boolean | No | Enable response simulation (default: `False`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `201` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/`

Get detailed information about a specific session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/active/`

Set the active status of a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`SessionActive`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `active`{ .text-nowrap } | boolean | Yes | Whether the session is active |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/description/`

Update the description of a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`DescriptionUpdate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `description`{ .text-nowrap } | string | No | New description (empty to clear) (default: ``) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/initialize/`

Run new_session callbacks for a session that has not been initialized.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/settings/`

Update the settings of a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`SettingsUpdate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `settings`{ .text-nowrap } | object | Yes | New settings |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/testing/`

Set the testing mode of a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`SessionTesting`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `testing`{ .text-nowrap } | boolean | Yes | Whether testing mode is enabled |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

## Players

### `GET /admin/api/v1/sessions/{sname}/multiview/`

Get player metadata needed to reproduce the admin multiview.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/online-players/`

Get last-seen times and info for all players in a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/players/`

Get specified fields for all players in a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fields`{ .text-nowrap } | array[string] | No |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/advance/`

Advance specified players by one page.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/dropout/`

Mark specified players as manually dropped out.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/end/`

Move specified players to the end of the experiment.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/players/fields/`

Set arbitrary fields on specified players.

!!! note
    Field names must be valid Python identifiers (letters, digits, and underscores, not starting with a digit). They are checked before anything is written: if any name is invalid, the request fails with `400` and no player is changed.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersFields`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `fields`{ .text-nowrap } | object | Yes | Fields to set |
| `reload`{ .text-nowrap } | boolean | No | Whether to trigger page reload (default: `False`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/group/`

Manage group assignments for selected players.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersGroup`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `action`{ .text-nowrap } | string | Yes | Grouping action: same_group, reset, or by_size |
| `group_size`{ .text-nowrap } | integer | No | Group size for by_size (min: `1.0`; default: `1`) |
| `shuffle`{ .text-nowrap } | boolean | No | Shuffle players before grouping (default: `False`) |
| `reload`{ .text-nowrap } | boolean | No | Whether to trigger page reload (default: `False`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/initialize/`

Run new_player callbacks for players that have not been initialized.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/message/`

Send an admin message to specified players.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayerMessage`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `message`{ .text-nowrap } | string | Yes | Message to send |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/redirect/`

Redirect specified players to an external URL.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayerRedirect`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `url`{ .text-nowrap } | string | Yes | URL to redirect to (must start with http:// or https://) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/reload/`

Force page reload for specified players.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/revert/`

Revert specified players by one page.

!!! note
    Players cannot be reverted past the start of a round (`Rounds` or `Repeat`) or of an app, or from the end of the experiment, because `player.round` and `player.app` would not go back with them. All players are checked first: if any of them cannot be reverted, the request fails with `400` and no player is moved.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersAction`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames to act on (min items: `1`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/timeout/`

Adjust the page timeout for specified players.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayerTimeout`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `delta`{ .text-nowrap } | number | No | Timeout adjustment in seconds (default: `60.0`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/players/{uname}/`

Get specified fields for one player in a session.

!!! note
    Pass `fields` repeatedly to choose fields, e.g. `?fields=id&fields=page_order`. Omitting it returns the same default fields as the all-players endpoint.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `uname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fields`{ .text-nowrap } | array[string] | No |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

## Admin chat

### `GET /admin/api/v1/sessions/{sname}/admin-chat/`

Summarize admin chat state for each player in a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/admin-chat/`

Send an admin chat message to multiple players at once.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`AdminchatBroadcast`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `message`{ .text-nowrap } | string | Yes | Message to send |
| `enable_replies`{ .text-nowrap } | boolean or null | No | Optionally update whether all recipients may reply |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/players/admin-chat/replies/`

Enable or disable admin chat replies for multiple players.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Request body** (`PlayersChatReplies`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `unames`{ .text-nowrap } | array[string] | Yes | List of usernames (min items: `1`) |
| `enabled`{ .text-nowrap } | boolean | Yes | Whether player replies are enabled |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/players/{uname}/admin-chat/`

Get admin chat metadata and transcript for one player.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `uname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/sessions/{sname}/players/{uname}/admin-chat/`

Send an admin chat message to one player.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `uname`{ .text-nowrap } | string | Yes |  |

**Request body** (`AdminchatMessage`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `message`{ .text-nowrap } | string | Yes | Message to send |
| `enable_replies`{ .text-nowrap } | boolean or null | No | Optionally update whether the player may reply |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/sessions/{sname}/players/{uname}/admin-chat/replies/`

Enable or disable a player’s ability to reply in admin chat.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `uname`{ .text-nowrap } | string | Yes |  |

**Request body** (`AdminchatReplies`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `enabled`{ .text-nowrap } | boolean | Yes | Whether player replies are enabled |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

## Data export

### `GET /admin/api/v1/sessions/{sname}/data/`

Get all session data in display format, optionally filtered by timestamp.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `since`{ .text-nowrap } | number | No | Only return data updated since this epoch timestamp |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/data/export/`

Download a ZIP briefcase of session data, as in the admin UI. The briefcase always contains the ultralong, sparse, and latest formats, page times, a data dictionary, and integrity checksums. Passing gvar adds a grouped latest format on top.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `filetype`{ .text-nowrap } | string | No | Export file type: csv or jsonl |
| `gvar`{ .text-nowrap } | array[string] | No | Group-by variables for the optional grouped latest format |
| `filters`{ .text-nowrap } | boolean | No | Apply reasonable filters |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/zip`{ .text-nowrap } | ZIP briefcase |

---

### `GET /admin/api/v1/sessions/{sname}/data/jsonl/`

Download session data as JSONL (streaming).

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `format`{ .text-nowrap } | string | No | Export format: ultralong, sparse, or latest |
| `gvar`{ .text-nowrap } | array[string] | No | Group-by variables |
| `filters`{ .text-nowrap } | boolean | No | Apply reasonable filters |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/jsonl`{ .text-nowrap } | JSONL stream |

---

## Digests and pipelines

### `GET /admin/api/v1/sessions/{sname}/digests/`

Run all available app digests for a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/digests/html/`

Render the app-authored AdminDigest.html fragments shown by the admin UI.

!!! note
    `apps` lists every app with a digest. `html` only contains entries for apps that provide an `AdminDigest.html` template.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/digests/{appname}/`

Run one app digest for a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `appname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/digests/{appname}/html/`

Render one app-authored AdminDigest.html fragment.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `appname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `text/html`{ .text-nowrap } | Rendered fragment |

---

### `GET /admin/api/v1/sessions/{sname}/pipelines/`

List apps that provide a pipeline for a session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/pipelines/html/`

Render app-authored AdminPipeline.html fragments shown by the admin UI.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/sessions/{sname}/pipelines/{appname}/html/`

Render one app-authored AdminPipeline.html fragment.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `appname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `text/html`{ .text-nowrap } | Rendered fragment |

---

### `GET /admin/api/v1/sessions/{sname}/pipelines/{appname}/runs/`

Run an app pipeline without custom JSON data, matching the admin UI button.

!!! note
    This endpoint never passes data to the pipeline, even if you send a request body. Use `POST` to pass data.

!!! note
    If the pipeline returns a custom data export, it is downloaded as CSV or JSONL, depending on `filetype`. Any other result is returned as plain text. `filetype` must be `csv` or `jsonl`; any other value fails with `400` before the pipeline runs.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `appname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `filetype`{ .text-nowrap } | string | No | Export file type: csv or jsonl |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `text/plain`{ .text-nowrap } | Pipeline result |
| `200` | `text/csv`{ .text-nowrap } | Custom data export with `filetype=csv` |
| `200` | `application/jsonl`{ .text-nowrap } | Custom data export with `filetype=jsonl` |

---

### `POST /admin/api/v1/sessions/{sname}/pipelines/{appname}/runs/`

Run an app pipeline, optionally passing a JSON request body.

!!! note
    This endpoint accepts an optional JSON request body. The decoded body is passed to the app’s `pipeline()` as `data` (`None` if the body is empty). A body that is not valid JSON fails with `400`.

!!! note
    If the pipeline returns a custom data export, it is downloaded as CSV or JSONL, depending on `filetype`. Any other result is returned as plain text. `filetype` must be `csv` or `jsonl`; any other value fails with `400` before the pipeline runs.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sname`{ .text-nowrap } | string | Yes |  |
| `appname`{ .text-nowrap } | string | Yes |  |

**Query parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `filetype`{ .text-nowrap } | string | No | Export file type: csv or jsonl |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `text/plain`{ .text-nowrap } | Pipeline result |
| `200` | `text/csv`{ .text-nowrap } | Custom data export with `filetype=csv` |
| `200` | `application/jsonl`{ .text-nowrap } | Custom data export with `filetype=jsonl` |

---

## Rooms

### `GET /admin/api/v1/rooms/`

List all rooms with their configuration.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/rooms/`

Create a new room.

**Request body** (`RoomCreate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name`{ .text-nowrap } | string | Yes | Room name (min length: `1`) |
| `config`{ .text-nowrap } | string or null | No | Default configuration for sessions |
| `labels`{ .text-nowrap } | array[string] or null | No | Allowed labels for participants |
| `capacity`{ .text-nowrap } | integer or null | No | Maximum capacity |
| `open`{ .text-nowrap } | boolean or null | No | Whether the room is open for joining (defaults to true if sname is given, false otherwise) |
| `sname`{ .text-nowrap } | string or null | No | Associated session name |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `201` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/rooms/{roomname}/`

Get detailed information about a specific room.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/rooms/{roomname}/`

Update room settings, optionally associating an existing session (only when no session is currently associated).

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Request body** (`RoomUpdate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `config`{ .text-nowrap } | string or null | No | Default configuration |
| `labels`{ .text-nowrap } | array[string] or null | No | Allowed labels |
| `capacity`{ .text-nowrap } | integer or null | No | Maximum capacity |
| `open`{ .text-nowrap } | boolean or null | No | Whether the room is open (defaults to true if sname is given, otherwise unchanged) |
| `sname`{ .text-nowrap } | string or null | No | Existing session to associate with the room |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `DELETE /admin/api/v1/rooms/{roomname}/`

Delete a room (only when no session is associated).

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/rooms/{roomname}/capacity/`

Set a room’s capacity, even while a session is associated.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Request body** (`RoomCapacity`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `capacity`{ .text-nowrap } | integer or null | Yes | Maximum capacity (null for unlimited) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/rooms/{roomname}/close/`

Close a room, optionally disassociating its session first.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Request body** (`RoomClose`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `disassociate`{ .text-nowrap } | boolean | No | If true, disassociate the session before closing (default: `False`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/rooms/{roomname}/online/`

Get online status for a room’s waiting area.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `PATCH /admin/api/v1/rooms/{roomname}/open/`

Set a room’s open status without requiring disassociation.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Request body** (`RoomOpen`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `open`{ .text-nowrap } | boolean | Yes | Whether the room should be open |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/rooms/{roomname}/sessions/`

Create a new session within a room, by default using the room’s config.

!!! note
    If `config` is omitted, the room’s default configuration is used. If the room has none either, the request fails with `400`.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Request body** (`RoomSessionCreate`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `config`{ .text-nowrap } | string or null | No | Configuration name (defaults to the room’s config) |
| `n_players`{ .text-nowrap } | integer | Yes | Number of players (min: `0.0`) |
| `assignees`{ .text-nowrap } | array[string] or null | No | Labels to assign to players |
| `settings`{ .text-nowrap } | object or null | No | Session settings |
| `sname`{ .text-nowrap } | string or null | No | Custom session name |
| `unames`{ .text-nowrap } | array[string] or null | No | Custom usernames |
| `no_grow`{ .text-nowrap } | boolean | No | Lock capacity to n_players (default: `False`) |
| `simulate`{ .text-nowrap } | boolean | No | Enable response simulation (default: `False`) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `201` | `application/json`{ .text-nowrap } | Successful response |

---

### `DELETE /admin/api/v1/rooms/{roomname}/sessions/`

Disassociate a room from its current session.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `roomname`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

## System

### `GET /admin/api/v1/announcements/`

Fetch announcements from upstream.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/announcements/dismiss/`

Silence the admin UI’s nudge to check announcements.

!!! note
    The nudge stays silent for ten years. The dashboard’s `nudge_announcements` reflects this.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/auth/login/`

Create the same browser admin session token as submitting /admin/login/.

!!! note
    This endpoint does not require a Bearer token.

!!! note
    Login attempts are rate-limited per IP address. After 50 failed attempts within one hour, the IP is blocked for six hours. Requests from localhost are exempt.

**Request body** (`AuthLogin`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `user`{ .text-nowrap } | string | No | Admin username (default: `admin`) |
| `pw`{ .text-nowrap } | string | No | Admin password (default: ``) |
| `token`{ .text-nowrap } | string | No | Auto-login token (default: ``) |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `201` | `application/json`{ .text-nowrap } | Successful response |
| `401` | `application/json`{ .text-nowrap } | Invalid admin credentials |
| `429` | `application/json`{ .text-nowrap } | Too many failed login attempts |

---

### `POST /admin/api/v1/auth/logout-all/`

Revoke all browser admin sessions for the token’s user, matching /admin/status/logout-all/.

!!! note
    This revokes browser admin-login sessions. It does not revoke API keys.

**Request body** (`AuthToken`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auth_token`{ .text-nowrap } | string | Yes | Value of the uauth browser cookie |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `POST /admin/api/v1/auth/logout/`

Revoke one browser admin session token, matching /admin/logout/.

!!! note
    This revokes browser admin-login sessions. It does not revoke API keys.

**Request body** (`AuthToken`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auth_token`{ .text-nowrap } | string | Yes | Value of the uauth browser cookie |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/auth/sessions/`

Get information about active authentication sessions.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `DELETE /admin/api/v1/auth/sessions/{user}/`

Revoke all browser admin sessions for one user.

!!! note
    This revokes browser admin-login sessions for the named user. It does not revoke API keys.

**Path parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user`{ .text-nowrap } | string | Yes |  |

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---

### `GET /admin/api/v1/database/dump/`

Download a complete machine-readable database dump.

!!! note
    The response is a gzip-compressed MessagePack dump intended for `uproot restore`, not JSON.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/gzip`{ .text-nowrap } | Gzip-compressed database dump |

---

### `GET /admin/api/v1/praise/`

Fetch the same praise text shown by the admin UI.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `text/plain`{ .text-nowrap } | Praise text |
| `502` | `application/json`{ .text-nowrap } | Praise could not be fetched from upstream |

---

### `GET /admin/api/v1/project/archive/`

Download a reproducible .tar.gz archive of the project code, excluding files ignored by .gitignore.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/gzip`{ .text-nowrap } | Gzip-compressed tar archive of the project |

---

### `GET /admin/api/v1/status/`

Get status information.

**Responses**:

| Status | Content | Description |
|--------|---------|-------------|
| `200` | `application/json`{ .text-nowrap } | Successful response |

---
