Audit logs
Query the immutable audit trail, and (on premium tiers) export a tamper-evident signed copy for archival or SIEM ingestion.
::: tip Auth
GET /v1/audit-logs— any platform admin.GET /v1/admin/audit-export— platform Admin + theAuditExportentitlement (premium tier). :::
GET /v1/audit-logs
Query the audit log, newest-first, with offset pagination and optional filters.
Request
GET /v1/audit-logs?user_id=&action=&from=&to=&page=&page_size=
| Query param | Type | Notes |
|---|---|---|
user_id | UUID | Filter to events whose actor is this user. |
action | string | Exact-match action filter (e.g. auth.login). |
from | RFC3339 | Lower time bound (inclusive). |
to | RFC3339 | Upper time bound (inclusive). |
page | int | 1-indexed. Defaults to 1. |
page_size | int | Defaults to 25, clamped to [1, 100]. |
Response
200 OK
{
"items": [
{
"id": 91823,
"event_id": "b1e2…",
"timestamp": "2026-06-01T12:00:00Z",
"organization_id": "f47a…",
"actor_id": "a3f1…",
"actor_type": "user",
"action": "auth.login",
"resource_type": "session",
"resource_id": "c9d8…",
"ip_address": "203.0.113.7",
"user_agent": "Mozilla/5.0 …",
"request_id": "7f3a…",
"metadata": { "method": "password" },
"outcome": "success"
}
],
"total": 1,
"page": 1,
"page_size": 25
}
| Field | Type | Meaning |
|---|---|---|
id | int | Monotonic row id (sort key). |
event_id | UUID | Stable event identifier. |
timestamp | string | RFC3339, UTC. |
organization_id | UUID | Tenant the event is scoped to. |
actor_id | UUID|null | The acting user, if any. |
actor_type | string | user, system, api_key, etc. |
action | string | Dotted event name (e.g. auth.login, mfa.reset). |
resource_type / resource_id | string | The affected resource. |
ip_address / user_agent | string|null | Request origin. |
request_id | UUID|null | Correlates with request logs. |
metadata | object | Event-specific structured payload. |
outcome | string | success / failure / etc. |
GET /v1/admin/audit-export
Stream the audit log as newline-delimited JSON (NDJSON) with a detached HMAC-SHA256 signature, so the export is tamper-evident.
Request
GET /v1/admin/audit-export?from=&to=
| Query param | Type | Notes |
|---|---|---|
from | RFC3339 | Lower time bound (inclusive). No lower bound when absent. |
to | RFC3339 | Upper time bound (inclusive). No upper bound when absent. |
Response
200 OK
Content-Type: application/x-ndjson- One JSON object per line (each an audit row), followed by a final trailer line carrying the signature and row count:
{"id":91823,"action":"auth.login", ...}
{"id":91824,"action":"auth.logout", ...}
{"_signature":"sha256=4f3c…","_count":2}
- Header
X-IdentSphere-Signature: sha256=<hex>carries the same signature.
The signature is HMAC-SHA256 over the data region only — every line
except the trailer (a signature can't sign itself). To verify: concatenate all
lines except the final _signature line, recompute the HMAC with your signing
key, and compare. The key is IDENTSPHERE_AUDIT_EXPORT_KEY (a deterministic
fallback is used when unset — set it in production).
Error responses
| Status | Code | When |
|---|---|---|
| 401 | authentication_required | No valid auth credential. |
| 402 | payment_required | audit-export on a tier without the AuditExport entitlement. Checked before the admin role. |
| 403 | forbidden | Caller is not a platform admin (or lacks Admin for export). |
| 400 | invalid_input | Malformed from/to timestamp. |