Export your team's audit log to NDJSON, CSV, or JSON for compliance, archival, and downstream analysis.
What's in the audit log
Every action that changes account state — invites, role changes, key rotations, website settings, billing changes, and more — is recorded with:
- id — unique log entry id
- action — what happened (e.g.
team.invite_member,website.update_settings) - resource_type + resource_id — what was acted on
- actor_id — which team member performed the action
- metadata — additional context (source, hashed IP, etc.)
- created_at — UTC timestamp
IP addresses inside metadata are stored as one-way hashes with a daily-rotating salt, so you keep forensic value without exposing raw IPs.
You can also browse the same trail in the dashboard under Settings → Security → Audit log.
Plan availability
Audit Export is available on the Pro plan and above. (Free plans don't include API key creation, so the endpoint isn't reachable on Free.)
Authentication
The endpoint is part of the External API and is called with an API key:
Authorization: Bearer YOUR_API_KEY
Create an API key from the dashboard: Settings → Security → API Keys → New key. A full-access key works against every CLI endpoint.
If your account is part of multiple teams, target a specific team with the X-Zenovay-Team-Id header on every request.
Export the audit log
curl -L "https://api.zenovay.com/v1/cli/mutate/audit/export?format=ndjson" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o zenovay-audit.ndjson
Supported formats
format | Content-Type | Best for |
|---|---|---|
ndjson (default) | application/x-ndjson | Streaming into log-analysis pipelines (line-delimited JSON) |
csv | text/csv | Opening in Excel, Google Sheets, or BI tools |
json | application/json | Single JSON array for programmatic processing |
The response is sent with Content-Disposition: attachment; filename="zenovay-audit.<format>" so most HTTP clients save it to disk.
The export returns your team's available audit history (audit logs are retained for 24 months). A single export returns up to 10,000 of the most recent entries; for larger archives, run regular exports on a schedule and append them in cold storage. For lighter, interactive lookups, use /v1/cli/mutate/audit/logs (below).
Tail recent entries (paginated)
For interactive querying use /v1/cli/mutate/audit/logs:
curl "https://api.zenovay.com/v1/cli/mutate/audit/logs?since=7d&limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"
Query parameters
| Parameter | Default | Notes |
|---|---|---|
since | 7d | Time window: 1h, 7d, 4w, 12m |
action | – | Filter by exact action string |
actor | – | Filter by user id |
limit | 50 | Max 200 per request |
The response includes pagination.next_cursor when more entries exist beyond the requested limit. To reach older entries, raise limit (up to 200) or narrow the since window. For a complete archive, use the export endpoint above, which returns up to 10,000 of the most recent entries in one call.
Best practices
- Schedule regular exports. A weekly cron job that stores the NDJSON in cold storage (S3 Glacier, R2, etc.) is a low-cost way to keep an immutable trail.
- Rotate your API key periodically and after any team-member offboarding.
- Treat exports as sensitive. Entries are not secrets, but they describe operational activity — keep them out of public buckets and shared drives.
- Combine with webhooks to react to specific actions in real time and use the export as a periodic full reconciliation.
Errors you might see
| Status | Meaning |
|---|---|
401 unauthorized | Missing or invalid API key, or the key isn't bound to a team |
402 upgrade_required | Your plan doesn't include Audit Export — upgrade to Pro or higher |
400 invalid_format | format must be one of ndjson, csv, json |
Every response also includes the x-request-id header. Keep it in your support tickets so we can trace the call end-to-end.