Audit log
Every meaningful change to your organization — member invites, API key rotations, app deletions, ownership transfers, sign-in attempts — is written to an append-only audit log. Admin roles can query it from the dashboard or the REST API.
What gets logged
Section titled “What gets logged”| Category | Actions |
|---|---|
| API keys | api_key.created, api_key.revoked |
| Members | member.invited, member.removed, member.role_changed, member.invitation_cancelled, member.ownership_transferred |
| Organization | organization.created, organization.updated, organization.deleted |
| Apps | app.created, app.updated, app.deleted |
| Channels | channel.created, channel.updated, channel.deleted |
| Webhooks | webhook_endpoint.created, webhook_endpoint.deleted |
| Auth | auth.signup, auth.signin, auth.signin_failed, auth.google, auth.google_failed, auth.org_setup, auth.token_refreshed |
| User | user.profile_updated, user.updated_by_admin, user.active_org_switched |
New actions get added as features ship. The full list lives in AuditAction on the backend.
Entry shape
Section titled “Entry shape”{ "id": 4821, "organizationId": 17, "actorId": 42, "action": "api_key.created", "resourceType": "api_key", "resourceId": "ak_live_9f2c...", "metadata": { "name": "prod deploy", "environmentId": 3 }, "ipAddress": "203.0.113.17", "actor": { "id": 42, "first_name": "Sayan", "last_name": "Biswas", "email": "sayan@example.com", "username": "sayan" }, "createdAt": "2026-04-21T18:03:11.742Z"}actorId can be null — some actions (failed sign-ins, system-triggered changes) have no authenticated caller.
Querying
Section titled “Querying”GET /audit-logs?page=1&limit=50Authorization: Bearer <admin_jwt>x-tenant-id: <organization_id>Requires the Admin role in the target organization. Non-admins get a 403.
Filters
Section titled “Filters”| Query param | Type | Notes |
|---|---|---|
page | number | Defaults to 1. |
limit | number | Defaults to 50. |
action | string | Exact match, e.g. api_key.created. |
resourceType | string | Exact match, e.g. api_key, channel. |
actorId | number | Filter by the user who performed the action. |
from | ISO-8601 date | Lower bound on createdAt. |
to | ISO-8601 date | Upper bound on createdAt. |
Response
Section titled “Response”{ "data": [ /* AuditLog entries, newest first */ ], "meta": { "total": 1284, "page": 1, "limit": 50, "totalPages": 26 }}Example: export the last 30 days
Section titled “Example: export the last 30 days”curl "https://api.axonpush.xyz/audit-logs?from=2026-03-22&limit=500" \ -H "Authorization: Bearer $AXONPUSH_ADMIN_JWT" \ -H "x-tenant-id: 17"Paginate with page=2, page=3, … until totalPages is exhausted.
Guarantees
Section titled “Guarantees”- Append-only. There’s no API to edit or delete audit entries.
- Scoped to the caller’s organization. You cannot read entries from orgs you’re not a member of.
- Indexed on
(organizationId, createdAt)so date-bounded queries stay fast as the log grows.
Related
Section titled “Related”- Environments — environment changes show up here as
app.updatedentries - API Keys — every create/revoke is audited
- Organizations — member and ownership changes are audited