apiAll notable changes to the api container are documented in this file.
The format is based on Keep a Changelog, and the container adheres to Semantic Versioning.
The api and ui containers are versioned independently. The HTTP wire
contract (endpoints, token kinds, RBAC roles, response envelope) is the
boundary between them — bumping the major here implies a breaking
change to that contract that consumers must adapt to.
Tags use the api-v<MAJOR>.<MINOR>.<PATCH> form so they don't collide
with the UI's tags in this monorepo.
POST /api/v1/report writes a report.received entry attributed to the reporter, and GET /api/v1/blocklist writes a blocklist.requested entry (including 304s) attributed to the consumer.app_settings key/value table plus GET/PATCH /api/v1/admin/app-settings (admin-only) exposing the two audit toggles (audit_report_received_enabled, audit_blocklist_request_enabled) so the high-volume rows can be silenced at runtime without a container restart.audit_enabled boolean on reporters and consumers (default true) editable via the admin PATCH endpoints. Audit emits only when both the global toggle and the entity-level flag are true (AND, not OR).DELETE /api/v1/admin/tokens/{id}/purge — hard-deletes a previously revoked, non-service token row. Returns 409 on still-active tokens.report.received, blocklist.requested, app_settings.updated, token.deleted./api/v1/admin/stats/dashboard replaces the single-series bans_by_day_7d (manual-block creations per day) with blocked_ips_by_day_7d, a per-category time series of distinct IPs reported per UTC day. Shape is {days: string[], series: [{category, counts}]}. Categories with zero activity in the window still appear as flat-zero series so the legend stays stable./api/v1/admin/audit-log now accepts subject_kind + subject_id query parameters (must be supplied together; otherwise 400). When set, the row matches if the (kind, id) pair matches either the audit row's target or its actor — so per-entity detail pages can list both admin actions on the entity and events the entity emitted (report.received, blocklist.requested).First stable release. Implements every milestone of SPEC.md from the
api side (M1–M7, M11–M14) plus shared concerns from M12.
:8081 with healthcheck.DB_DRIVER. WAL + tuned PRAGMAs on SQLite, transactional writes throughout.SPEC.md §4: reporters, consumers, api_tokens, categories, reports, ip_scores, job_locks, job_runs, ip_enrichment, manual_blocks, allowlist, policies, policy_category_thresholds, users, oidc_role_mappings, audit_log.reporter, consumer, admin, service) with SHA-256 hashing, irdb_<kind>_<32 base32> formatting, and a RbacMiddleware driving role enforcement on every admin endpoint.X-Acting-User-Id impersonation header — only honoured in combination with a service token; ignored on every other kind.POST /api/v1/report (token-bucket rate limiter, 60 req/s/token by default); GET /api/v1/blocklist (text + JSON, ETag, 30 s per-consumer cache).purge.upsert-oidc, upsert-local, users/{id} — service-token-only, used by the UI BFF to translate browser identities into stable user records and roles.recompute-scores, cleanup-audit, cleanup-expired-manual-blocks, enrich-pending, refresh-geoip, tick, status. Loopback / RFC1918 only via InternalNetworkMiddleware; bearer-gated by INTERNAL_JOB_TOKEN. Single-shot lock acquisition via job_locks with crash-tolerant expiry and job_runs history per execution./api/v1/openapi.yaml with viewer at /api/docs; canonical reference for request/response schemas.bin/console: db:migrate, db:rollback, db:seed, auth:bootstrap-service-token, auth:create-token, jobs:run, jobs:status, scores:rebuild.