Skip to main content

Login — Obtain Access Token

Authenticate with your API credentials to receive a signed JWT token. Include this token in every subsequent request to protected endpoints.

Endpoint

POST /api/v1/auth/token
This endpoint accepts form-data, not JSON. The Content-Type must be application/x-www-form-urlencoded.

Request

Form Fields

username
string
required
API username. Configured via the API_USERNAME environment variable.
password
string
required
Plain-text password. Validated against the bcrypt hash stored in API_PASSWORD_HASH.

Response

200 OK — Token Issued

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}
access_token
string
HS256-signed JWT token. Valid for JWT_ACCESS_TOKEN_EXPIRE_MINUTES minutes (default: 60 minutes).
token_type
string
Always "bearer". Indicates the scheme to use in the Authorization header.

401 Unauthorized — Invalid Credentials

{
  "detail": "Incorrect username or password."
}
On a 401, verify that API_USERNAME and API_PASSWORD_HASH in your .env are correct.

Using the Token

Include the token in the Authorization header of every request to a protected endpoint:
Authorization: Bearer <access_token>

Code Examples

# 1. Obtain the token
TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=your_password" \
  | jq -r '.access_token')

# 2. Use the token in a protected request
curl http://localhost:8000/api/v1/clients/ \
  -H "Authorization: Bearer $TOKEN"

Token Lifecycle

         POST /api/v1/auth/token
         ┌─────────────────────┐
         │  username + password │
         └──────────┬──────────┘


         ┌─────────────────────┐
         │  Validate credentials│
         │  (bcrypt hash check) │
         └──────────┬──────────┘
                    │ Signed JWT (HS256)

         ┌─────────────────────┐
         │  access_token       │  ← valid for 60 min (configurable)
         └──────────┬──────────┘

                    ▼ (each protected request)
         Authorization: Bearer <token>


         ┌─────────────────────┐
         │  get_current_user   │  ← FastAPI dependency
         │  (validates JWT)    │
         └─────────────────────┘

Token Expiry

When a token expires, all protected endpoints return:
{
  "detail": "Could not validate credentials."
}
With the response header:
WWW-Authenticate: Bearer
Simply request a new token by calling this endpoint again.