Audit log
Driftstack writes an immutable audit entry for every meaningful account mutation — API key mints, session lifecycle, profile changes, team membership events, MFA changes, billing, more. This page covers what's captured, how to query it, and how long entries are kept.
Endpoint
GET /v1/account/audit-log
Authorization: Bearer ds_live_…
The endpoint is reachable with any authenticated key — there
is no per-scope gate on read. Each caller sees only their own
account's entries (or the team owner's entries when the call
passes X-Driftstack-Account; see Team RBAC
below). For a CSV / JSON dump of the whole window, use
GET /v1/account/audit-log/export?format=csv (10,000-row
ceiling, signalled by x-driftstack-export-truncated
on the response).
Response envelope
{
"data": [
{
"id": "b1a2c3d4-…-uuid",
"account_id": "acc_…",
"actor_type": "customer",
"actor_account_id": "acc_…",
"actor_key_id": "key_…",
"action": "api_key.minted",
"target_resource_id": "api_key_key_…",
"payload": { "name": "ci-bot", "scopes": ["read"] },
"ip_address": "203.0.113.42",
"user_agent": "DriftstackCLI/2.3.1",
"timestamp": "2026-05-11T13:42:00.000Z"
}
],
"next_cursor": null
}
Entry ids are raw UUIDs (no aud_ prefix). The
response envelope uses data and
next_cursor — there is no items field.
Actions captured
A non-exhaustive list of the actions you'll see (the canonical set is enforced server-side):
- Account:
account.email_verified,account.login,account.logout,account.password_changed,account.mfa_enrolled,account.mfa_disabled,account.recovery_code_used - API keys:
api_key.minted,api_key.revoked,api_key.rotated - Sessions:
session.created,session.destroyed - Profiles:
profile.created,profile.deleted,profile.exported,profile.imported - Webhooks:
webhook_endpoint.created,webhook_endpoint.deleted,webhook_delivery.replayed - Billing:
subscription.tier_changed - Team RBAC:
team.member_invited,team.invite_accepted,team.member_removed - Staff actions (visible to you):
admin.refund_recorded,admin.support_note
Actor types
The actor_type field is one of:
customer— action performed by an authenticated API key or web session. Theactor_account_id+actor_key_idfields identify which account / key performed it.system— automated action by Driftstack infrastructure (e.g. scheduled-job triggered revocation, expired-card subscription downgrade).actor_account_id/actor_key_idare null.staff— Driftstack staff performed the action via internal admin tools. Used for refund recording, support-note insertion, and exceptional manual interventions. We notify the affected account by email when this happens for any action that modifies state.
Filters
All filters compose; combine freely with pagination cursors.
action— single action string. Returns entries whereaction === filter.actor_type—customer,system, orstaff.target_resource_id— filter to a specific resource id (e.g.?target_resource_id=api_key_key_xyzto see every action on that key).from,to— ISO-8601 timestamps, inclusive.?from=2026-05-01T00:00:00Z&to=2026-05-31T23:59:59Z.
GET /v1/account/audit-log?action=api_key.minted&from=2026-05-01Z&to=2026-05-31Z
Authorization: Bearer ds_live_… Pagination
Standard cursor pagination — see /docs/pagination.
Sort order is timestamp DESC with id DESC
tiebreaker, so newest entries appear first.
Team RBAC: whose audit log do I see?
When a team member calls
GET /v1/account/audit-log with the
X-Driftstack-Account: acc_<owner-uuid>
header, the server returns the owner's audit
log — both member and admin team
roles are read-allowed on this surface (
effectiveAccountId behaviour). Without the
header, callers see their own account's entries.
The same effective-account header gate applies to
/v1/account/audit-log/export.
Retention
| Tier | Audit-log retention |
|---|---|
| Free | 30 days |
| Solo / API Starter | 90 days |
| Team / API Builder | 1 year |
| Agency / API Scale | 3 years |
| Enterprise | Custom (default 7 years for compliance) |
Past the retention window, entries are pruned by a nightly
sweep. For longer retention, export via the API regularly and
store copies on your side — most enterprise customers ship a
daily cron that calls the endpoint with
from=yesterday&to=today and forwards the
response into their SIEM.
Immutability
Audit entries are append-only. There's no
delete or update endpoint; even staff cannot mutate existing
entries. If a correction is needed (e.g. a misattributed
action), staff append an admin.support_note
pointing at the original entry rather than editing it.
Webhook subscriptions for audit events
The audit log itself does not emit a per-entry
webhook event — that would create a feedback loop (writing a
webhook delivery would itself generate an audit entry).
Subscribe to the underlying resource webhooks instead
(api_key.revoked, session.completed,
etc.) — see /docs/webhooks.
Support
Compliance / audit-export questions: [email protected]. Technical questions about the endpoint: [email protected].