Skip to content

Audit log

EstimateIQ keeps an append-only audit trail. Nothing changes in the system without a line in it: every mutating API call, every admin clear/load, and every queue/workflow action is recorded.

What gets logged

  • API mutations — a middleware wraps every POST / PUT / PATCH / DELETE under /api/* and records the call after it runs. The method + path are parsed into a readable action and the affected entity id (e.g. POST /api/estimates/est_X/submit → action estimate.submit, target est_X).
  • Admin operationsadmin.clear and admin.load are logged explicitly when data is loaded (see Data loading), with the loaded row counts in the summary.
  • Background actions — queue ingest and workflow steps record their own entries.

Recording is best-effort: it can never break the request it describes. Reads are never logged, and /api/audit itself is excluded so viewing the trail doesn’t pollute it.

Entry shape

Each row (Drizzle table audit_log):

FieldMeaning
tsISO timestamp.
actorWho — the x-actor request header, or operator / admin / system.
actionnoun.verb, e.g. estimate.submit, carrier.update, followup.complete, admin.load.
method · pathThe HTTP method and request path (for API-driven entries).
targetThe affected entity id (estimate / carrier / …), when present.
summaryHuman-readable line.
statusHTTP status the call returned.
sourceapi · admin · queue · workflow · webhook.

Reading the trail

GET /api/audit?limit=300

Returns entries newest first (default 300). See the API reference.

The Audit log page (Operations → Audit log) renders the same data server-side (zero-flash, newest first) with source pills and a link from each target straight to the affected estimate.