api.md 2.9 KB

HTTP API reference

All /api/* routes require an authenticated session. State-changing methods (non-GET) require an X-CSRF-Token header whose value comes from GET /api/configcsrf_token. Unauthorised API calls return 401; non-admin calls to admin routes return 403.

Auth (auth.py)

Method Path Purpose
GET/POST /login OIDC: redirect to Okta. Static: render/submit the dev form.
GET /authorize OIDC callback; validates token, checks allowed-users, sets session.
GET /logout Clear session.

Quarantine (app.py)

Method Path Returns
GET / The single-page UI.
GET /api/config {folders, deleted_folder, report_release, prefs, csrf_token, config_version, is_admin}
GET /api/messages?folder=&limit=&before= {folder, messages[], page:{raw_count, oldest, has_more}}
GET /api/message/<guid> {headers, text, html, attachments[], raw_headers}
POST /api/actions 202 {job_id, queued} — body {action, folder, messages[], targetfolder?}
GET /api/jobs {jobs[], config_version} — scoped to the caller (admins see all)
GET/PUT/DELETE /api/prefs Per-user preferences (get / set patch / reset)

actionrelease | report_release | delete | move. messages[] items carry {localguid, guid, subject, sender, recipient}. For move, targetfolder must be a configured folder.

Paging /api/messages

The PPS API caps a search at 1000 rows and has no offset paging. The client pages the whole folder backwards by date: fetch a page, then pass the oldest date seen as before for the next page, until page.has_more is false. page.oldest is the oldest date in the raw batch (before hidden/acted messages are filtered), so paging never terminates early.

Admin (admin.py, all @admin_required)

Method Path Returns
GET /admin The admin panel page.
GET /api/admin/config {config: redacted, schema, version} — secrets shown as *_set booleans
PUT /api/admin/config {version, applied[], restart_required[], config} / 400 {errors:[{field,message}]}
POST /api/admin/pps-test {ok, detail} — probes PPS with pending form values, never persists
GET /api/admin/jobs?limit= {jobs[], active} — all users
POST /api/admin/jobs/<id>/retry {job_id, status} — failed → pending
GET /api/admin/logs?source=ops\|app&lines=&q= {source, lines:[{text, level}], truncated}

Users and the denied message are ordinary config keys under [auth], saved through PUT /api/admin/config (one atomic write). source is an enum, never a file path.

Error shape

PPS failures return 502 {error, detail, status, reqid} (reqid = the PPS x-pps-reqid header, for cross-referencing PPS logs). Validation failures return 400 {errors:[…]} or 400 {error}.