> ## Documentation Index
> Fetch the complete documentation index at: https://copilot-api.nick3.top/llms.txt
> Use this file to discover all available pages before exploring further.

# Admin API endpoints for request inspection

> Reference for the Admin API endpoints that let you query request logs, account stats, and DB metadata programmatically from your own scripts or tooling.

The Admin API lets you query request history and account stats programmatically. It is the same data that powers the built-in admin UI at `/admin`, accessible as JSON so you can integrate it into your own scripts or monitoring tools.

## Access control

Access rules differ based on where requests originate:

| Origin                                     | Requirement                              |
| ------------------------------------------ | ---------------------------------------- |
| Loopback (`localhost`, `127.0.0.1`, `::1`) | No token required                        |
| Remote (any other hostname or IP)          | Requires `ADMIN_TOKEN` set on the server |

When `ADMIN_TOKEN` is set on the server, pass it in one of these headers:

| Header          | Format                          |
| --------------- | ------------------------------- |
| `x-admin-token` | `x-admin-token: <token>`        |
| `Authorization` | `Authorization: Bearer <token>` |

Tokens in URL query parameters are not supported.

<Warning>
  If you see `403 Forbidden`, the admin API is restricted to localhost and `ADMIN_TOKEN` is not set. If you see `401 Unauthorized`, `ADMIN_TOKEN` is set but the request did not include a valid token.
</Warning>

***

## GET /api/admin/meta

Returns metadata about the request history database, including the database file path and retention settings.

```bash theme={null}
curl http://localhost:4141/api/admin/meta
```

Example response:

```json theme={null}
{
  "dbPath": "/home/user/.local/share/copilot-api/admin.sqlite",
  "retentionDays": 14,
  "maxRows": 200000
}
```

***

## GET /api/admin/accounts

Lists accounts with their runtime status. Pass `include_stats=1` to include aggregated request statistics for each account.

```bash theme={null}
# Basic account list
curl "http://localhost:4141/api/admin/accounts"

# Include aggregated stats
curl "http://localhost:4141/api/admin/accounts?include_stats=1"
```

Example response with `include_stats=1`:

```json theme={null}
{
  "items": [
    {
      "account_id": "octocat",
      "account_type": "individual",
      "runtime": {
        "entitlement": 300,
        "remaining": 212,
        "unlimited": false,
        "failed": false
      },
      "stats": {
        "since_ms": 1735000000000,
        "request_count": 84,
        "error_count": 2,
        "tokens_total": 48200,
        "avg_duration_ms": 1340,
        "last_request_at_ms": 1735080000000
      }
    }
  ]
}
```

***

## GET /api/admin/requests

Queries request logs with optional filters and cursor-based pagination.

### Query parameters

| Parameter           | Type       | Default | Description                                                          |
| ------------------- | ---------- | ------- | -------------------------------------------------------------------- |
| `limit`             | number     | `50`    | Number of results to return. Maximum is `200`.                       |
| `cursor_id`         | number     | —       | Pagination cursor. Use `next_cursor_id` from the previous response.  |
| `account_id`        | string     | —       | Filter by account ID.                                                |
| `upstream_model`    | string     | —       | Filter by the model ID sent upstream to Copilot.                     |
| `client_model`      | string     | —       | Filter by the model ID requested by the client.                      |
| `upstream_endpoint` | string     | —       | Filter by upstream endpoint (e.g. `/v1/messages`).                   |
| `path`              | string     | —       | Filter by request path.                                              |
| `status`            | number     | —       | Filter by HTTP status code.                                          |
| `has_error`         | `1` or `0` | —       | Filter to requests that have (`1`) or do not have (`0`) an error.    |
| `from_ms`           | number     | —       | Filter to requests at or after this Unix timestamp in milliseconds.  |
| `to_ms`             | number     | —       | Filter to requests at or before this Unix timestamp in milliseconds. |

### Response fields

| Field            | Description                                              |
| ---------------- | -------------------------------------------------------- |
| `items`          | Array of request log entries.                            |
| `next_cursor_id` | Cursor to pass as `cursor_id` to retrieve the next page. |
| `has_more`       | `true` if additional pages exist.                        |

### Examples

<CodeGroup>
  ```bash Last 50 requests theme={null}
  curl "http://localhost:4141/api/admin/requests?limit=50"
  ```

  ```bash Failed requests only theme={null}
  curl "http://localhost:4141/api/admin/requests?has_error=1"
  ```

  ```bash Filter by account theme={null}
  curl "http://localhost:4141/api/admin/requests?account_id=octocat"
  ```

  ```bash Paginate with cursor theme={null}
  # Use next_cursor_id from the previous response
  curl "http://localhost:4141/api/admin/requests?cursor_id=<next_cursor_id>"
  ```
</CodeGroup>

***

## GET /api/admin/requests/:requestId

Returns a single request log entry by its ID.

```bash theme={null}
curl "http://localhost:4141/api/admin/requests/abc123"
```

Example response:

```json theme={null}
{
  "item": {
    "request_id": "abc123",
    "account_id": "octocat",
    "path": "/v1/messages",
    "upstream_endpoint": "/v1/messages",
    "client_model": "claude-opus-4-6",
    "upstream_model": "claude-opus-4-6",
    "http_status": 200,
    "duration_ms": 1243,
    "started_at_ms": 1735080000000
  }
}
```

***

***

## GET /api/admin/config

Returns the current server configuration. You can also use `POST /api/admin/config` to update configuration values without restarting the server. Changes made via the API are validated and applied immediately.

```bash theme={null}
# Read current config
curl http://localhost:4141/api/admin/config

# Update a config value (example: change logLevel)
curl -X POST http://localhost:4141/api/admin/config \
  -H "Content-Type: application/json" \
  -d '{"logLevel": "debug"}'
```

<Note>
  Unknown keys are rejected. Only fields documented in the [configuration reference](/configuration/config-file) are accepted.
</Note>

***

## Data storage and retention

Request history is stored in `admin.sqlite` in the app data directory:

* **Linux / macOS:** `~/.local/share/copilot-api/admin.sqlite`
* **Windows:** `%USERPROFILE%\.local\share\copilot-api\admin.sqlite`

The proxy stores **metadata only** — no GitHub or Copilot tokens, and no request or response content. Logs are retained for 14 days and the database is capped at 200,000 rows. Older entries are cleaned up automatically.
