API: auth
POST /api/v1/auth/agent-token
Section titled “POST /api/v1/auth/agent-token”Mint Agent Token
mint (or rotate) a scoped AGENT token + its contract grants.
Superuser-only. Creates (or reuses) the agent identity and REPLACES its grant pool
with body.grants (default-deny — a contract not listed is inaccessible). Changing
the pool or capabilities later is a grant edit, no re-mint needed. publish is granted only when listed
explicitly: withhold on prod contracts by default).
Auth: Authorization: Bearer <token> required
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Optional. |
Request body: application/json — schema AgentTokenRequest
| Field | Type | Required | Description |
|---|---|---|---|
email | string | no | |
expires_days | integer | no | |
full_name | string | null | no | |
grants | array of AgentGrantSpec | yes | |
revoke_prior | boolean | no |
Example:
{ "email": "agent@entherium.dev", "expires_days": 90, "full_name": "Partner agent", "grants": [ { "capabilities": [ "submit", "launch", "cancel", "edit_config" ], "salescontract": 40 } ], "revoke_prior": true}Responses:
| Code | Meaning | Body |
|---|---|---|
200 | Successful Response | ServiceTokenResponse |
401 | Missing or invalid authentication credentials | ErrorResponse |
409 | The e-mail belongs to a non-agent user; refusing to convert | ErrorResponse |
422 | Validation Error | HTTPValidationError |
Example response (200):
{ "access_token": "eyJhbGciOiJIUzI1NiJ9.<payload>.<signature>", "api_scope": "agent", "email": "agent@entherium.dev", "expires_in": 7776000, "token_type": "bearer", "user_guid": 5}POST /api/v1/auth/login
Section titled “POST /api/v1/auth/login”Login
OAuth2 password flow. username field is the user’s email.
Auth: no token required
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Optional. |
Request body: application/x-www-form-urlencoded — schema Body_login_api_v1_auth_login_post
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string | null | no | |
client_secret | string | null | no | |
grant_type | string | null | no | |
password | string | yes | |
scope | string | no | |
username | string | yes |
Responses:
| Code | Meaning | Body |
|---|---|---|
200 | Successful Response | TokenPair |
422 | Validation Error | HTTPValidationError |
GET /api/v1/auth/me
Section titled “GET /api/v1/auth/me”Me
Auth: Authorization: Bearer <token> required
Responses:
| Code | Meaning | Body |
|---|---|---|
200 | Successful Response | MeResponse |
401 | Missing or invalid authentication credentials | ErrorResponse |
Example response (200):
{ "email": "agent@entherium.dev", "full_name": "Partner agent", "guid": 5, "is_active": true, "is_superuser": false, "is_team": false, "last_login": "2026-09-03T08:12:41Z"}POST /api/v1/auth/refresh
Section titled “POST /api/v1/auth/refresh”Refresh
Exchange a refresh token for a new access token.
Auth: no token required
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Optional. |
Request body: application/json — schema RefreshRequest
| Field | Type | Required | Description |
|---|---|---|---|
refresh_token | string | yes |
Example:
{ "refresh_token": "<refresh token from /api/v1/auth/login>"}Responses:
| Code | Meaning | Body |
|---|---|---|
200 | Successful Response | AccessOnly |
422 | Validation Error | HTTPValidationError |
POST /api/v1/auth/service-token
Section titled “POST /api/v1/auth/service-token”Mint Service Token
Mint (or rotate) a long-lived READ-ONLY access token for an external agent.
Superuser-only. The endpoint can only create/serve users with read-only agent scope — it is structurally unable to hand out full-access tokens. Re-minting reactivates a previously revoked user.
Auth: Authorization: Bearer <token> required
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Optional. |
Request body: application/json — schema ServiceTokenRequest
| Field | Type | Required | Description |
|---|---|---|---|
email | string | no | |
expires_days | integer | no | |
full_name | string | null | no | |
revoke_prior | boolean | no |
Responses:
| Code | Meaning | Body |
|---|---|---|
200 | Successful Response | ServiceTokenResponse |
401 | Missing or invalid authentication credentials | ErrorResponse |
409 | The e-mail belongs to an existing non-read-only user; refusing to convert | ErrorResponse |
422 | Validation Error | HTTPValidationError |
Example response (200):
{ "access_token": "eyJhbGciOiJIUzI1NiJ9.<payload>.<signature>", "api_scope": "agent", "email": "agent@entherium.dev", "expires_in": 7776000, "token_type": "bearer", "user_guid": 5}DELETE /api/v1/auth/service-token/{guid}
Section titled “DELETE /api/v1/auth/service-token/{guid}”Revoke Service Token
Revoke a read-only service user: deactivate + kill all minted tokens.
Effective immediately — auth re-reads the user row on every request. Only read-only agent identities are addressable here (404 otherwise), so a typo’d guid can never lock out a human/admin account.
Auth: Authorization: Bearer <token> required
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
guid | path | yes | integer | |
Idempotency-Key | header | no | string | Optional. |
Responses:
| Code | Meaning | Body |
|---|---|---|
204 | Successful Response | — |
401 | Missing or invalid authentication credentials | ErrorResponse |
422 | Validation Error | HTTPValidationError |