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

# Authenticate and Authorize All Requests to the Octop API

> Get a JWT access token via POST /api/auth/login, then include it as a Bearer token on every subsequent call to the Octop REST API.

Every Octop API call — except `/api/health`, `/api/setup/*`, and the OpenAPI schema — requires a JWT access token. Obtain the token by logging in with your credentials, then include it in the `Authorization` header of every subsequent request. Tokens expire after 24 hours by default; re-login to get a fresh one.

> [!WARNING]
>
> First-run credentials depend on how you installed Octop. After a bare-metal `octop init` / setup wizard, open `~/octop-login.txt` for the one-time setup password, then sign in with the admin username and password you created. After Docker first boot, sign in as `admin` / `Octop123` (also written to `/data/.octop/credential.txt`) unless you set `OCTOP_ADMIN_USERNAME` / `OCTOP_DEFAULT_PASSWORD`. Use those credentials for API login.

## Log in and get a token

**1. POST your credentials**

Send your `username` and `password` to the login endpoint:

```bash cURL theme={null}
curl -X POST http://127.0.0.1:8088/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username": "<your_username>", "password": "<your_password>"}'
```

```python Python theme={null}
import requests

resp = requests.post(
    "http://127.0.0.1:8088/api/auth/login",
    json={"username": "<your_username>", "password": "<your_password>"},
)
token = resp.json()["access_token"]
```

**2. Extract the access token**

The response body contains your JWT token along with your role and user details:

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "role": "admin",
  "user": {
    "id": 1,
    "username": "admin",
    "display_name": "Administrator"
  }
}
```

**3. Pass the token in the Authorization header**

Include the token as a Bearer credential on every subsequent request:

```bash cURL theme={null}
curl http://127.0.0.1:8088/api/agents \
  -H 'Authorization: Bearer <your_token>'
```

```python Python theme={null}
headers = {"Authorization": f"Bearer {token}"}
agents = requests.get(
    "http://127.0.0.1:8088/api/agents",
    headers=headers,
).json()
```

### Login request fields

**username** `string` *required*

The account username you created during the setup wizard (or later via user management).

**password** `string` *required*

The account password you set during the setup wizard (or later via password reset).

### Login response fields

**access\_token** `string`

A signed JWT token. Include this value as `Bearer <access_token>` in the `Authorization` header.

**role** `string`

The account's role. Either `"admin"` or `"user"`.

**user** `object`

Basic profile information for the authenticated account.

**user fields**

**user.id** `integer`

Unique numeric identifier for the user.

**user.username** `string`

The account's login username.

**user.display\_name** `string`

The human-readable display name shown in the web UI.

## Token expiry

Tokens expire after **24 hours** by default. Control this with the `OCTOP_ACCESS_TOKEN_TTL` environment variable (value in seconds). When a token expires, re-call `POST /api/auth/login` to obtain a fresh one.

> [!NOTE]
>
> Rotating the JWT secret via `octop admin rotate-jwt-secret` immediately invalidates **all** outstanding tokens. Every user must re-login after a rotation.

## Get current user info

Retrieve the profile of the currently authenticated user:

```bash theme={null}
curl http://127.0.0.1:8088/api/auth/me \
  -H 'Authorization: Bearer <token>'
```

The response includes `id`, `username`, `role`, `display_name`, `locale`, and other profile fields.

## Change password

Update your own password without admin involvement:

```bash theme={null}
curl -X POST http://127.0.0.1:8088/api/auth/change-password \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{"old_password": "octop", "new_password": "mysecurepass1"}'
```

A successful response returns `204 No Content`.

New passwords must be at least **8** characters, include a letter and a digit, differ from the current password, and must not be on a small denylist of common strings (for example `password123` or `admin123`).

## OpenID Connect

An administrator enables OIDC under **Management → Users → Single sign-on**. After at least one user exists, the login page can show **Continue with \{name}**.

| Method | Path | Who can call it | What it does |
| - | - | - | - |
| `GET` | `/auth/oidc/status` | anyone | Whether SSO is on, and the button label |
| `POST` | `/auth/oidc/start` | anyone | Start the identity-provider login |
| `GET` | `/auth/oidc/callback` | anyone | Return from the identity provider |
| `POST` | `/auth/oidc/exchange` | anyone | Finish login and return the same JWT as password login |
| `GET` | `/auth/oidc/config` | admin | Read SSO settings (secret is hidden) |
| `PUT` | `/auth/oidc/config` | admin | Save SSO settings |
| `POST` | `/auth/oidc/config/test` | admin | Test that the provider is reachable |

New SSO users get a regular user account. Grant settings access afterwards if they need it.

## Redeem an invite

Anyone with an invite link can call these routes. Administrators create invites from **Management → Users** or `POST /api/users/invites`. See [Users & Admin](https://octop.mintlify.site/api/users-admin.md).

| Method | Path | What it does |
| - | - | - |
| `POST` | `/auth/invite/validate` | Check that a code is still valid |
| `POST` | `/auth/invite/redeem` | Create the user and return a JWT |

## Log out

Invalidate the current token server-side:

```bash theme={null}
curl -X POST http://127.0.0.1:8088/api/auth/logout \
  -H 'Authorization: Bearer <token>'
```

A successful response returns `204 No Content`.

## Error reference

| HTTP Status | Error Code | Cause | Resolution |
| - | - | - | - |
| `401 Unauthorized` | `AUTH_FAILED` | Invalid credentials supplied at login | Check username and password |
| `401 Unauthorized` | `TOKEN_EXPIRED` | JWT has passed its TTL | Re-login to obtain a fresh token |
| `403 Forbidden` | `FORBIDDEN` | Authenticated but insufficient role (e.g., non-admin accessing an admin endpoint) | Log in with an account that has the required role |
| `403 Forbidden` | `USER_DISABLED` | The account has been disabled by an admin | Contact your Octop administrator |
| `423 Locked` | `LOGIN_LOCKED` | Too many failed login attempts; account is locked | Wait out the lockout period, or ask an admin to call `POST /api/users/{id}/unlock-login` |

> [!TIP]
>
> Set `OCTOP_ENABLE_API_DOCS=1` (or `"enable_api_docs": true` in `config.json`) and visit `http://127.0.0.1:8088/api/docs` to explore every endpoint interactively with the built-in Scalar interface — no extra tooling required.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.