Audit log
Every API call, on the record — who called what, with which credential, and what came back.
wapi records every authenticated API call: the method and path, the credential that made it, the status returned, and when. It is account-scoped and read with a Personal Access Token.
curl "https://api.wapi.crafter.run/api/audit-logs?page=1&limit=50" -H "Authorization: Bearer $PAT"
curl https://api.wapi.crafter.run/api/audit-logs/1234 -H "Authorization: Bearer $PAT"The list is paginated in the { items, pagination } shape described in
Groups & contacts. The single-record endpoint
returns the full detail, including the request body where one was recorded.
What a record looks like
{
"success": true,
"data": {
"items": [
{ "id": 8412, "method": "POST", "path": "/api/send-message",
"status": 200, "credential": "session:3", "ip": "203.0.113.9",
"created_at": "2026-09-05T21:14:02.331Z" }
],
"pagination": { "page": 1, "limit": 50, "total": 1284, "totalPages": 26 }
}
}credential names the kind and the identity — session:3 for a session key, pat:12 for a
Personal Access Token — never the credential itself. There is nothing in this table that could be
replayed as a credential if it leaked, which is deliberate.
status is the response wapi returned, so a run of 403s from one credential is a program
holding the wrong kind of token, and a run of 503s is a session that was not connected.
Filtering
curl "https://api.wapi.crafter.run/api/audit-logs?page=1&limit=50&status=422" -H "Authorization: Bearer $PAT"Filter by status to find failures, or by session to scope it to one number. The dashboard's
Audit view is the same data with the filters as chips.
What it is for
Three things, in practice:
- Proving something happened. A message somebody swears was never sent has a row, with a status and a timestamp.
- Finding which credential did it. Every row names the token or session key used, so a surprising call can be traced to the machine holding that credential.
- Watching a token you are about to revoke. Before revoking, look at what has been using it.
The dashboard renders the same data under Audit, with filters by session and status.
What goes wrong
| Symptom | Cause |
|---|---|
403 | You sent a session key. This is account-scoped, so it needs a PAT |
| Empty list on a busy account | page is past totalPages; check pagination.total |
| A call you made is absent | Unauthenticated requests are not recorded — a 401 never reached the log |
What it does not store
Not a copy of every message. Message content lives in message logs, and only when log_messages
is on for the session — see Managing sessions. The audit log is about
calls, not conversations.
Operations covered