Admin API: Audit
Operations on audit in the Odudu admin API, one section each. Every request carries a bearer token; the index says which audience it needs and how a refusal is shaped.
GET /admin/tenants/{tenant}/audit
Requires the "view-audit" capability.
Every read here runs under a five second statement timeout. Two filters whose rows are each common but that few rows share (an action and an actor, say) make Postgres read all of the cheaper one, so past the bound the read is refused with 400 of type about:blank#audit-query-too-broad: narrow it with from and to, which lead the index, or drop a filter. from and to are instants from 1970 to 9999, refused with 400 otherwise. Newest first, by an opaque cursor bound to the filters it was issued under.
Path parameters
| Name | Type | Required | Details |
|---|---|---|---|
tenant | string | yes | The tenant being administered, addressed by name. |
Query parameters
| Name | Type | Required | Details |
|---|---|---|---|
cursor | string | no | The next value of the previous page, to continue after it. |
limit | integer | no | How many items to return. A value over 200 is treated as 200; the default is 50. Constraints: at least 1. |
event_type | string | no | Only events of this type. Constraints: one of admin_mutation, admin_access, authentication, session, token, credential. |
actor_subject_id | string | no | Only events done by this subject. Constraints: a UUID. |
resource_type | string | no | Only events on this kind of resource, such as client. Constraints: at least 1 character, at most 256 characters. |
resource_id | string | no | Only events on this resource; needs resource_type. Constraints: at least 1 character, at most 256 characters. |
action | string | no | Only events with this action, such as client.create. Constraints: at least 1 character, at most 256 characters. |
outcome | string | no | Only events with this outcome. Constraints: one of allowed, refused, failed. |
from | string | no | Only events at or after this instant. Constraints: an ISO 8601 date and time. |
to | string | no | Only events before this instant. Constraints: an ISO 8601 date and time. |
Responses
200 OK
Body: application/json
| Field | Type | Required | Details |
|---|---|---|---|
items | array of object | yes | The entries of this answer. |
items[] | object | yes | |
items[].id | string | yes | The event’s identifier. |
items[].occurred_at | string | yes | When it happened. |
items[].event_type | string | yes | The kind of event: admin_mutation, admin_access, authentication, session, token or credential. |
items[].action | string | yes | What happened, such as client.create or login.password. |
items[].outcome | string | yes | allowed, refused or failed. Constraints: one of allowed, refused, failed. |
items[].actor_tenant_id | string or null | yes | The tenant of whoever did it, or null. |
items[].actor_subject_id | string or null | yes | The subject who did it, or null. |
items[].actor_client_id | string or null | yes | The client it was done through, or null. |
items[].actor_name | string or null | yes | The actor’s username, or null. |
items[].actor_origin | string or null | yes | Where the actor comes from: this tenant, the system tenant, or other-tenant. Constraints: one of tenant, system, other-tenant. |
items[].resource_type | string or null | yes | The kind of thing acted on, or null. |
items[].resource_id | string or null | yes | The thing acted on, or null. |
items[].request_id | string or null | yes | The x-request-id of the request, to correlate with logs. |
items[].ip | string or null | yes | The address the server saw the request come from. |
items[].detail | object | yes | Extra facts about the event. Never a secret, a token or a password. Constraints: other fields accepted. |
next | string | no | An opaque cursor for the next page; absent on the last page. |
{
"items": [
{
"id": "0192f5c4-1d4e-7a3b-9c11-5a2f0e6b7c01",
"occurred_at": "2026-10-19T09:30:00.000Z",
"event_type": "admin_mutation",
"action": "client.create",
"outcome": "allowed",
"actor_tenant_id": "0192f5c4-0000-7000-8000-000000000001",
"actor_subject_id": "0192f5c4-0000-7000-8000-000000000002",
"actor_client_id": "0192f5c4-0000-7000-8000-000000000003",
"actor_name": "ada",
"actor_origin": "tenant",
"resource_type": "client",
"resource_id": "0192f5c4-0000-7000-8000-000000000004",
"request_id": "0192f5c4-0000-7000-8000-000000000005",
"ip": "203.0.113.7",
"detail": {}
}
]
}
401 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
403 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
GET /admin/tenants/{tenant}/audit/count
Requires the "view-audit" capability.
Every read here runs under a five second statement timeout. Two filters whose rows are each common but that few rows share (an action and an actor, say) make Postgres read all of the cheaper one, so past the bound the read is refused with 400 of type about:blank#audit-query-too-broad: narrow it with from and to, which lead the index, or drop a filter. from and to are instants from 1970 to 9999, refused with 400 otherwise.
Path parameters
| Name | Type | Required | Details |
|---|---|---|---|
tenant | string | yes | The tenant being administered, addressed by name. |
Query parameters
| Name | Type | Required | Details |
|---|---|---|---|
event_type | string | no | Only events of this type. Constraints: one of admin_mutation, admin_access, authentication, session, token, credential. |
actor_subject_id | string | no | Only events done by this subject. Constraints: a UUID. |
resource_type | string | no | Only events on this kind of resource, such as client. Constraints: at least 1 character, at most 256 characters. |
resource_id | string | no | Only events on this resource; needs resource_type. Constraints: at least 1 character, at most 256 characters. |
action | string | no | Only events with this action, such as client.create. Constraints: at least 1 character, at most 256 characters. |
outcome | string | no | Only events with this outcome. Constraints: one of allowed, refused, failed. |
from | string | no | Only events at or after this instant. Constraints: an ISO 8601 date and time. |
to | string | no | Only events before this instant. Constraints: an ISO 8601 date and time. |
Responses
200 OK
Body: application/json
| Field | Type | Required | Details |
|---|---|---|---|
count | integer | yes | How many items match, up to a cap. |
capped | boolean | yes | True when more match than count says, because counting stops at the cap. |
401 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
403 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
GET /admin/tenants/{tenant}/audit/export
Requires the "view-audit" capability.
Every read here runs under a five second statement timeout. Two filters whose rows are each common but that few rows share (an action and an actor, say) make Postgres read all of the cheaper one, so past the bound the read is refused with 400 of type about:blank#audit-query-too-broad: narrow it with from and to, which lead the index, or drop a filter. from and to are instants from 1970 to 9999, refused with 400 otherwise. Every row the same filters list, newest first, one JSON object per line, built in full before it is sent rather than streamed. Refused whole with 413 past 10,000 rows rather than cut short. Audited as audit.export.
Path parameters
| Name | Type | Required | Details |
|---|---|---|---|
tenant | string | yes | The tenant being administered, addressed by name. |
Query parameters
| Name | Type | Required | Details |
|---|---|---|---|
event_type | string | no | Only events of this type. Constraints: one of admin_mutation, admin_access, authentication, session, token, credential. |
actor_subject_id | string | no | Only events done by this subject. Constraints: a UUID. |
resource_type | string | no | Only events on this kind of resource, such as client. Constraints: at least 1 character, at most 256 characters. |
resource_id | string | no | Only events on this resource; needs resource_type. Constraints: at least 1 character, at most 256 characters. |
action | string | no | Only events with this action, such as client.create. Constraints: at least 1 character, at most 256 characters. |
outcome | string | no | Only events with this outcome. Constraints: one of allowed, refused, failed. |
from | string | no | Only events at or after this instant. Constraints: an ISO 8601 date and time. |
to | string | no | Only events before this instant. Constraints: an ISO 8601 date and time. |
Responses
200 OK
Body: application/x-ndjson
| Field | Type | Required | Details |
|---|---|---|---|
id | string | yes | The event’s identifier. |
occurred_at | string | yes | When it happened. |
event_type | string | yes | The kind of event: admin_mutation, admin_access, authentication, session, token or credential. |
action | string | yes | What happened, such as client.create or login.password. |
outcome | string | yes | allowed, refused or failed. Constraints: one of allowed, refused, failed. |
actor_tenant_id | string or null | yes | The tenant of whoever did it, or null. |
actor_subject_id | string or null | yes | The subject who did it, or null. |
actor_client_id | string or null | yes | The client it was done through, or null. |
actor_name | string or null | yes | The actor’s username, or null. |
actor_origin | string or null | yes | Where the actor comes from: this tenant, the system tenant, or other-tenant. Constraints: one of tenant, system, other-tenant. |
resource_type | string or null | yes | The kind of thing acted on, or null. |
resource_id | string or null | yes | The thing acted on, or null. |
request_id | string or null | yes | The x-request-id of the request, to correlate with logs. |
ip | string or null | yes | The address the server saw the request come from. |
detail | object | yes | Extra facts about the event. Never a secret, a token or a password. Constraints: other fields accepted. |
401 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
403 RFC 9457 problem details
Body: application/problem+json, an RFC 9457 problem document described under problem details.
Documentation coverage: 60 of 60 fields described (100%).