Create an audit export
POST /v1/audit-exports · permission audit-exports:write
Queues a job that writes the matching audit records into a signed package you can verify without trusting KeenAuth. The job is returned with 202 Accepted; follow it with Get an audit export and fetch the file with Download an audit export.
Only API keys (secret or restricted) can create exports; the job records the key as requested_by. The environment comes from the key.
Request
Idempotency-Key is required (16 to 64 characters, A-Z a-z 0-9 _ -). The same key with the same body returns the first job with Idempotent-Replayed: true; the same key with a different body fails with 422 idempotency_key_reuse. The SDKs and the CLI set the header for you.
The filters are the same as in List audit events; an omitted field does not filter. Differences:
| Field | Type | Description |
|---|---|---|
stream |
string | admin (default) or application. |
from |
RFC 3339 | Inclusive lower bound. Defaults to the start of the retention window. There is no 92-day limit; a package holds at most 50 million lines (placeholders included). |
to |
RFC 3339 | Exclusive upper bound. Defaults to now; cannot be in the future. |
action, category, actor_type, actor_id, target_type, target_id, org_id, outcome, request_id, correlation_id, agent_only |
As in the list filters. The list's client filter is not available here; a client field fails with 400 unknown_field. |
|
include_ip |
boolean | Adds the full IP address and user agent to records younger than 13 months. Also requires audit-events:read_ip. Default false. |
{
"stream": "admin",
"from": "2026-07-01T00:00:00Z",
"to": "2026-10-01T00:00:00Z",
"action": "user."
}
At most 3 jobs run at the same time per environment (1 in development and staging environments).
Response
202 Accepted and the job with status queued. filter shows the applied filter with the defaults of from and to filled in. recorded_before is the snapshot bound: only records stored before it enter the package.
{
"id": "aex_01j9xk3m7q8r2s4t6v8w0y2z4e",
"status": "queued",
"filter": {
"stream": "admin",
"from": "2026-07-01T00:00:00Z",
"to": "2026-10-01T00:00:00Z",
"action": "user.",
"category": null,
"actor_type": null,
"actor_id": null,
"target_type": null,
"target_id": null,
"org_id": null,
"outcome": null,
"request_id": null,
"correlation_id": null,
"agent_only": false
},
"include_ip": false,
"record_count": null,
"file": null,
"manifest_sha256": null,
"failure_reason": null,
"created_at": "2026-10-19T09:00:00Z",
"started_at": null,
"completed_at": null,
"expires_at": null,
"recorded_before": "2026-10-19T09:00:00Z",
"requested_by": {"type": "api_key", "id": "key_01j9xk3m7q8r2s4t6v8w0y2z4d"}
}
Errors
Every error is an application/problem+json body with a stable code.
| HTTP | code |
When |
|---|---|---|
| 400 | malformed_request |
Idempotency-Key is missing or malformed, or the body is not valid JSON. |
| 400 | unknown_field |
The body has a field that is not listed above. |
| 400 | invalid_filter |
The audit service rejected the filter, for example to in the future. |
| 400 | range_outside_retention |
from or to is outside the audit retention window of your plan. |
| 422 | validation_failed |
A field is invalid (wrong type, bad timestamp, to not after from, unknown enum value, malformed id, empty string). |
| 422 | idempotency_key_reuse |
The Idempotency-Key was used with a different body. |
| 401 | unauthenticated |
The API key is missing, invalid or revoked. |
| 403 | insufficient_permissions |
The key lacks audit-exports:write, uses include_ip without audit-events:read_ip (required_permissions lists both), or the caller is not an API key. |
| 429 | rate_limited |
Too many jobs are running in this environment, or the rate limit was exceeded; honor Retry-After. |
| 503 | service_unavailable |
A dependency is temporarily unavailable; retry later. |
Example
curl https://api.eu.keenauth.com/v1/audit-exports \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"from": "2026-07-01T00:00:00Z", "to": "2026-10-01T00:00:00Z", "action": "user."}'
keenauth audit-exports create --from 2026-07-01T00:00:00Z --to 2026-10-01T00:00:00Z --action user.
Personal data
This endpoint carries personal data: audit events. Personal data in the KeenAuth APIs describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.