Audit
The organization's append-only log of what happened and who did it, and the request timeline it tells.
Events are never changed or deleted. List audit events
pages by cursor: pass next_cursor back as cursor with the same filters
until a page has no next_cursor.
List audit eventsHosted edition
Returns one page of the organization's audit log, newest first by default. Every filter is optional and they combine.
Paging is by cursor. When more events follow, the response carries next_cursor. Pass it back as cursor with the same sort, order and filters to get the next page. The last page has no next_cursor. total_count is how many events match the filters across every page.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
sort | query · enum | What to sort by. Events with the same value are ordered newest first. One of occurred, event_type, actor |
order | query · enum |
One of asc, desc |
cursor | query · string | The |
q | query · string | Free text. Matches the event type, the actor's name and id, the subject id, the event id, and the event's data. Case does not matter. |
event_type | query · array<string> | Only events of these types. Repeat the parameter to pass several. |
actor_type | query · enum | Only events by this kind of actor. One of human, agent, system, api_key |
actor_id | query · string | Only events by one actor. A membership id also matches events recorded under its user id, and the other way round. An agent is given by its slug. |
subject_type | query · string | Only events about this kind of thing, such as a request or a membership. |
subject_id | query · string | Only events about one subject. Requires |
outcome | query · enum | Only events whose action ended this way. Resolved from the event's data, so you do not need to know its shape. One of approved, denied, expired, cancelled, human, blocked |
from_at | query · date-time | Only events at or after this time. |
to_at | query · date-time | Only events before this time. |
limit | query · integer | How many events to return. Defaults to 100. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | One page of events |
400 | ErrorResponse | A filter is malformed, or |
401 | ErrorResponse | You are not signed in |
403 | ErrorResponse | You cannot read the audit log |
Response body200
The events on this page.
Present when another page follows.
How many events match the filters, across every page.
Example
curl -X GET "$WITHHUMAN_URL/api/v1/audit" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"events": [
{
"sequence": 1,
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"event_type": "string",
"actor_type": "string",
"actor_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"actor_display_name": "string",
"subject_type": "string",
"subject_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"data": {},
"occurred_at": "2026-09-08T12:02:11Z"
}
],
"next_cursor": "string",
"total_count": 1
}Retrieve an audit eventHosted edition
One entry of the organization's audit log by id, the record behind a deep link. An id from another organization is reported as not found.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The audit event's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | AuditEvent | The event |
400 | ErrorResponse | The id is not a UUID |
401 | ErrorResponse | You are not signed in |
403 | ErrorResponse | You cannot read the audit log |
404 | ErrorResponse | No such event in this organization |
Response body200
The event's position in the organization's log. Later events have higher numbers.
What happened, as a dotted key such as membership.suspended.
Who did it: human, agent, system, or api_key.
The person, agent, or key that acted. Absent for system.
The actor's name at the time.
What kind of thing the event is about, such as a request or a membership.
The thing the event is about.
Details specific to the event type, as JSON.
When it happened.
Example
curl -X GET "$WITHHUMAN_URL/api/v1/audit/{id}" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"sequence": 1,
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"event_type": "string",
"actor_type": "string",
"actor_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"actor_display_name": "string",
"subject_type": "string",
"subject_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"data": {},
"occurred_at": "2026-09-08T12:02:11Z"
}List the event types this organization has recordedHosted edition
The vocabulary for the audit log's event filter, sorted. Unlike a fixed list it can never name a type that does not occur.
Request
No parameters or body.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | Distinct event types |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/audit/event_types" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"event_types": [
"string"
]
}