List audit events

GET /v1/audit-events · permission audit-events:read

Lists the environment's audit records with cursor pagination, newest first. The admin stream holds changes made through the management API, the dashboard and the platform; the application stream holds events your application wrote. Every record is part of a hash chain per environment and stream, so the history can be verified independently with an export (POST /v1/audit-exports).

The environment always comes from the API key; there is no environment parameter.

Request

Parameter In Required Description
limit query no Page size, 1 to 100. Default 20.
after query no Opaque cursor from list_metadata.after (older records). Exclusive with before.
before query no Opaque cursor from list_metadata.before (newer records). Exclusive with after.
stream query no admin (default) or application.
from query no RFC 3339 time; records at or after it. Defaults to the later of the start of the retention window and to minus 92 days.
to query no RFC 3339 time; records before it. Defaults to now. The range from from to to is at most 92 days.
action query no Action prefix such as user. or connection.updated.
category query no authentication, session, token, administration, provisioning, federation, authorization, data_access, security, key_management, configuration or application.
actor_type query no Actor type such as api_key, dashboard_user, m2m_client, agent or system.
actor_id query no Exact actor id as recorded (key_…, usr_…, system:<service>).
target_type query no Target type such as user, organization or audit_export.
target_id query no Exact target id. With target_type, both must match the same target.
org_id query no Records about one organization (org_…).
outcome query no success, failure, denied or error.
request_id query no Idp-Request-Id of a request (UUID).
correlation_id query no Idp-Correlation-Id of a workflow (UUID).
agent_only query no true returns only agent actions: actor_type agent or a non-empty act_chain.
client query no The kind of client that made the call: mcp (the management MCP server, metadata.client = mcp/<version>) or cli (the KeenAuth CLI, cli/<version>). The client declares this value itself; it is not proof of who acted, the record's actor is. List only: an export has no client filter.

Records are always ordered by occurred_at (then id), newest first; there is no order parameter (order=desc is accepted, any other value fails with validation_failed). A cursor is only valid with the filters and the environment it was issued for. No total count is returned.

A search that takes longer than 10 seconds stops with 422 search_too_broad: narrow the filters or the time range, or use an export for large ranges.

Response

200 OK. data holds the records on the page; list_metadata.after points to older records and list_metadata.before to newer ones (null when there are none). Empty fields are null.

ip and user_agent are present only when the key has the audit-events:read_ip permission, and are filled only for records younger than 13 months. Without the permission the fields are left out entirely (no masked value). ip_prefix, ip_country, ip_asn and user_agent_family are always returned. prev_hash, org_prev_hash and record_hash are unpadded base64url SHA-256 values.

{
  "data": [
    {
      "id": "evt_01j9xk3m7q8r2s4t6v8w0y2z4a",
      "stream": "admin",
      "seq": 4182,
      "schema_version": 1,
      "action": "user.blocked",
      "category": "administration",
      "outcome": "success",
      "reason_code": null,
      "occurred_at": "2026-10-01T08:15:42.120Z",
      "received_at": "2026-10-01T08:15:42.131Z",
      "recorded_at": "2026-10-01T08:15:42.140Z",
      "clock_anomaly": false,
      "actor_type": "api_key",
      "actor_id": "key_01j9xk3m7q8r2s4t6v8w0y2z4d",
      "act_chain": null,
      "session_id": null,
      "auth_context": null,
      "elevation_ref": null,
      "org_id": null,
      "targets": [
        {"type": "user", "id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p", "org_id": null, "name": null}
      ],
      "application_id": null,
      "ip_prefix": "203.0.113.0/24",
      "ip_country": "DE",
      "ip_asn": 64500,
      "user_agent_family": "keenauth-go",
      "request_id": "0192a6c1-7d3e-7a10-9b2c-3d4e5f607182",
      "correlation_id": null,
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "producer_service": "directory",
      "policy_ref": "perm:users:write",
      "changes": {"status": {"old": "active", "new": "blocked"}},
      "metadata": null,
      "prev_hash": "n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
      "org_prev_hash": null,
      "record_hash": "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
    }
  ],
  "list_metadata": {
    "before": null,
    "after": "<opaque cursor>"
  }
}

Errors

Every error is an application/problem+json body with a stable code.

HTTP code When
400 invalid_cursor The cursor is malformed or was not issued for this request.
400 invalid_filter The audit service rejected a filter, for example a range longer than 92 days.
400 range_outside_retention from or to is outside the audit retention window of your plan.
422 validation_failed A query parameter is invalid (limit out of range, bad timestamp, to not after from, unknown stream, category or outcome, malformed id, repeated parameter, order other than desc).
422 search_too_broad The search took longer than 10 seconds; narrow it.
401 unauthenticated The API key is missing, invalid or revoked.
403 insufficient_permissions The key lacks audit-events:read.
429 rate_limited The rate limit was exceeded; honor Retry-After.
503 service_unavailable A dependency is temporarily unavailable; retry later.

Example

curl "https://api.eu.keenauth.com/v1/audit-events?action=user.&from=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
keenauth audit-events list --action user. --from 2026-10-01T00:00:00Z

Personal data

This endpoint carries personal data: audit events. Personal data in the KeenAuth APIs describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.