Authentication API
Endpoint reference for authenticating requests and managing sessions. See API Conventions for the shared error format and status codes.
All auth routes are mounted at /api/auth. The setup, login, and refresh endpoints do not require authentication — all other endpoints require Authorization: Bearer <token>.
Auth Status
Check whether auth has been set up and if the current request is authenticated:
curl http://localhost:4111/{
"name": "Pandora",
"version": "0.1.0",
"runtime": "node",
"serverless": false,
"auth": { "setup": true, "authenticated": false }
}Use auth.setup to decide whether to show a setup or login flow.
Endpoints
Setup
POST /api/auth/setup
Content-Type: application/json
{ "password": "my-secure-password" }Sets the initial password. Returns 201 with a token pair on success, 409 if already configured. Password must be at least 8 characters.
Login
POST /api/auth/login
Content-Type: application/json
{ "password": "my-secure-password" }Returns a token pair on success, 401 on wrong password, 403 if setup hasn’t been completed.
Refresh
POST /api/auth/refresh
Content-Type: application/json
{ "refreshToken": "..." }Rotates the refresh token and issues a new access token. The old refresh token is invalidated. Returns 401 if the token is expired, invalid, or reused.
Logout
POST /api/auth/logout
Authorization: Bearer <token>Revokes the current session.
Change Password
POST /api/auth/change-password
Authorization: Bearer <token>
Content-Type: application/json
{ "currentPassword": "old", "newPassword": "new" }Invalidates all sessions and refresh tokens, then returns a new token pair.
Sessions
GET /api/auth/sessions — list active sessions
DELETE /api/auth/sessions/:id — revoke a specific session
DELETE /api/auth/sessions — revoke all sessionsAll session endpoints require Authorization: Bearer <token>.
Revoking a specific session returns { "success": true, "loggedOut": false } — loggedOut is true when you revoke your own session. Returns 404 with session_not_found if the session ID doesn’t exist.
Response Formats
Token Pair
All successful auth responses (setup, login, refresh, change-password) return the same shape:
{
"token": "...",
"refreshToken": "...",
"expiresAt": "2025-01-01T00:15:00.000Z",
"refreshExpiresAt": "2025-01-08T00:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
token | string | Access token — send as Authorization: Bearer <token> |
refreshToken | string | Refresh token — use to obtain a new access token when the current one expires |
expiresAt | string | Access token expiry (15 minutes from issue) |
refreshExpiresAt | string | Refresh token expiry (7 days from issue) |
Session List
{
"sessions": [
{
"id": "abc123...",
"createdAt": "2025-01-01T00:00:00.000Z",
"expiresAt": "2025-01-01T00:15:00.000Z",
"userAgent": "Mozilla/5.0...",
"ip": "192.168.1.1",
"current": true
}
]
}Errors
Auth errors return a JSON body with an error field containing a machine-readable code:
| Code | Status | Meaning |
|---|---|---|
setup_required | 403 | No password has been configured yet |
already_setup | 409 | Password has already been configured |
invalid_credentials | 401 | Wrong password |
unauthorized | 401 | Missing or invalid access token |
refresh_token_required | 400 | Refresh token not provided |
Rate Limits
Auth endpoints are rate-limited per IP address:
| Endpoint | Limit | Window |
|---|---|---|
/api/auth/setup | 3 requests | 1 minute |
/api/auth/login | 5 requests | 1 minute |
/api/auth/refresh | 10 requests | 1 minute |
/api/auth/change-password | 3 requests | 1 minute |
Rate-limited responses include X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers.
SDK Types
These types are available from @pandorakit/sdk/api:
import type { AuthTokenPair, Session } from '@pandorakit/sdk/api'See SDK Client for the typed client that wraps these endpoints.