switching clears the token & responses
No token
51

Reading the tenant audit log

An admin reviews tenant security events; filterable + cursor-paginated.

  1. GET /v1/audit — events for the tenant (filter by event / userId / from / to)
GET/v1/auditadminRead tenant audit log

Scoped to the caller's tenant. Includes operator ACT-AS actions performed inside the tenant, attributed to the operator via actOperatorId / actReason — the cross-profile hop is scenario 37. The Enhancement 4 event codes listed in scenario 38 are visible here too: device_trust_failed and login_challenge_failed are the ones a tenant admin will care about when a member reports trouble signing in. Those events are written BEFORE any tenant is resolved — a device challenge is issued while the user is still proving who they are — so their tenant_id is NULL, and a read filtering on tenant_id alone would hide exactly the signal the admin needs from the only person positioned to act on it. The read therefore ALSO returns identity-plane events (NULL tenant_id) for users who are members of this tenant. Nothing scoped to another tenant can appear: any tenant-scoped event carries a non-NULL tenant_id and is excluded unless it is this one. What an admin additionally sees is their own member's authentication events, which are identity-plane facts by design — device trust deliberately spans every tenant a member belongs to (scenario 48).

Query parameters
ℹ︎Field guide — what each value means & where it comes from6 fields

No request body — all inputs are optional query filters. Admin-only and tenant-scoped; still requires the tester's Authorization (access token) and gateway context, which the tester and gateway supply.

eventquerystringoptionalyou choose
You type the exact audit event name to filter by (trimmed, 1-64 chars). Matches a single event such as login_succeeded. Leave empty to return all event types.
userIdqueryUUIDoptionalfrom a response
UUID of the user whose audit events you want. Obtain it from a prior list/get response (e.g. a user list's id field) and paste it here to scope results to that user.
fromqueryISO-8601optionalyou choose
You pick the start of the time window (ISO-8601 date, between 2000-01-01 and 2100-01-01). Only events at or after this time are returned.
toqueryISO-8601optionalyou choose
You pick the end of the time window (ISO-8601, same bounds). Must be greater than or equal to from, otherwise a 422 validation_error is returned. Only events at or before this time are returned.
limitqueryintegeroptionalyou choose
You choose how many records per page (integer 1-100, default 20). Controls page size for cursor pagination.
cursorquerystringoptionalfrom a response
Opaque pagination cursor (<=512 chars). Copy it from the previous response's meta.page.nextCursor to fetch the next page; omit for the first page.
Bearer token
GET https://api.kerja.team/v1/audit?event=login_succeeded&limit=20
↩︎Response guide — what comes back & what each value means16 fields

200 OK with the standard { data, meta } envelope. data is an ARRAY of audit-log event objects (cursor-paginated); meta.page carries the limit and the opaque nextCursor. Response is no-store; no Set-Cookie. SCOPE — an event belongs to this log if it is stamped with the caller's tenant OR is an IDENTITY-PLANE event (tenant_id NULL) about somebody who is a member of it. The second half exists because authentication events happen BEFORE any tenant is resolved: a device challenge is issued while the user is still proving who they are, so device_challenge_issued / device_trust_failed / login_challenge_failed / registration_resumed / login_mode_changed carry no tenant. Filtering on tenant_id alone hid device_trust_failed — a correct password followed by repeated device-challenge failures, the fingerprint of credential stuffing landing on a real account — from the only person positioned to act on it. Nothing from another tenant can leak: anything tenant-scoped carries a non-NULL tenant_id and is excluded unless it is this one.

dataarrayalways
Array of security audit-log event records for the caller's tenant, newest-first; may be empty if no events match the filters.
data[].idstringalways
Opaque identifier of this audit event row.
data[].eventstringalways
The exact event name that was recorded (e.g. login_succeeded); pass back as the ?event filter to narrow subsequent queries.
data[].userIdUUIDalways
ID of the user the event concerns; feed into the ?userId filter to scope the log to one user.
data[].sessionIdstringalways
Identifier of the session associated with the event, when applicable.
data[].outcomeenumalways
Whether the audited action succeeded or failed.
  • successThe audited action completed successfully.
  • failureThe audited action was attempted but did not succeed.
data[].reasonstringalways
Human/machine reason or failure code for the event; null when there is no associated reason (e.g. a plain success).
data[].ipstringalways
Source IP address recorded for the event.
data[].traceIdstringalways
Distributed-trace correlation id for the request that produced this event; use to cross-reference logs/traces.
data[].actOperatorIdUUIDalways
When the action was performed by an operator acting inside the tenant (act-as), the operator's id; null for ordinary tenant-user actions.
data[].actReasonstringalways
Reason the operator supplied for the act-as session; null when the event was not an act-as action.
data[].occurredAtISO-8601always
UTC timestamp of when the event occurred; use for time-ordering and as the basis for the ?from/?to date filters.
metaobjectalways
Envelope metadata wrapper for the paged result.
meta.pageobjectalways
Pagination block for this audit page.
meta.page.limitintegeralways
The page size applied for this query (1-100, default 20); echoes the ?limit param.
meta.page.nextCursorstringalways
Opaque keyset cursor for the next page, or null when this is the last page; pass back as ?cursor to fetch the following page.