Skip to main content
Version: 0.0.1

Health, setup, and authentication API

All examples use a local or test-only address. Read the API overview before using a session-authenticated mutation.

Route table

MethodPathSession / permissionSuccessOther implemented outcomes
GET/api/healthPublic200 status object
GET/api/setup/statusPublic200 initialized boolean500 database_error
POST/api/setup/initializePublic; CSRF-exempt201 user, normally with session + CSRF cookies400 invalid_input, 403 invalid_setup_token, 409 already_initialized, 429
POST/api/auth/loginPublic; CSRF-exempt200 user with session + CSRF cookies401 invalid_credentials, 429 rate_limited
POST/api/auth/logoutNo handler authentication; CSRF when CSRF cookie exists204
GET/api/auth/meSession cookie200 user401
PATCH/api/auth/me/preferencesSession cookie + CSRF200 user400 invalid_input, 401 unauthorized, 500 database_error
GET/api/auth/me/themeSession cookie200 theme preference401, 500 database_error
PATCH/api/auth/me/themeSession cookie + CSRF200 theme preference400 invalid_input, 401
GET/api/eventsSession cookie200 SSE stream401 unauthorized

User response shape

Setup, login, current-user, and locale preference writes serialize a user as:

{
"id": 1,
"email": "admin@example.test",
"role": "admin",
"created_at": "2026-08-17T00:00:00Z",
"disabled": false,
"preferred_locale": null
}

preferred_locale is a string or null. It is not a locale list and the accepted values are validated by the server.

Health and first setup

GET /api/health is a narrow liveness response and does not assert database, upstream, certificate, or authorization health.

GET /api/setup/status reports whether any user exists. To create the first administrator, send exactly email, password, and setup_token to POST /api/setup/initialize. The email is trimmed and lowercased; the password must be at least 12 characters. On a successful 201, the response is the user object. The server attempts to create a session and set both cookies, but the administrator remains created even if that session creation fails; log in afterward in that rare case.

curl --fail-with-body -k \
-H 'Content-Type: application/json' \
--data '{"email":"admin@example.test","password":"test-password-at-least-12","setup_token":"local-test-setup-token"}' \
https://127.0.0.1:8081/api/setup/initialize

Do not repeat setup as a login mechanism. After initialization it returns 409 with already_initialized. Invalid tokens return 403; malformed email or a short password return 400; rapid attempts can return 429.

Login, logout, and current user

POST /api/auth/login accepts:

{"email":"admin@example.test","password":"test-password-at-least-12"}

On 200, it returns the user object and sets bearust_session plus bearust_csrf. A failed credential check returns the safe 401 invalid_credentials envelope; rate limiting returns 429 rate_limited.

POST /api/auth/logout revokes the presented session if one is present and always responds 204, including without one. It is CSRF-protected when the request carries a current CSRF cookie. GET /api/auth/me returns 401 when the cookie is absent, expired, revoked, or belongs to a disabled user.

Preferences and theme

PATCH /api/auth/me/preferences requires an object containing preferred_locale. Supply a locale string to set it or null to clear it; omitting the field, unknown fields, or an invalid locale returns 400 invalid_input.

{"preferred_locale":"en"}

GET /api/auth/me/theme returns exactly:

{"preferred_theme":"system"}

preferred_theme may also be "light", "dark", or null. Patch the same single field; invalid JSON, unknown fields, or an unsupported value return 400 invalid_input.

Events stream

GET /api/events uses text/event-stream. The initial event is ready with {} data. Subsequent notifications include an event name and JSON data; when the subscriber lags it receives reconnect with {"reason":"lagged"}. The server sends a heartbeat every 15 seconds and rechecks the session on that interval. Reconnect by fetching current resource state; event IDs cannot replay missed events.

curl -k -N -b "$cookie_jar" https://127.0.0.1:8081/api/events

Source pointers

Handlers and the SSE lifecycle are in bearust/src/control_plane/mod.rs; cookie attributes, credential failure, and logout are in bearust/src/control_plane/auth.rs; locale/theme client shapes are in bearust/frontend/src/api.ts and tests/control_plane_locale.rs.