
# Crea un'esportazione di audit

`POST /v1/audit-exports` · autorizzazione `audit-exports:write`

Accoda un job che scrive i record di audit corrispondenti in un pacchetto firmato che puoi verificare senza fidarti di KeenAuth. Il job viene restituito con `202 Accepted`; seguilo con [Ottieni un'esportazione di audit](get.md) e scarica il file con [Scarica un'esportazione di audit](download.md).

Solo le chiavi API (segrete o con restrizioni) possono creare esportazioni; il job registra la chiave come `requested_by`. L'ambiente viene ricavato dalla chiave.

## Richiesta

`Idempotency-Key` è obbligatoria (da 16 a 64 caratteri, `A-Z a-z 0-9 _ -`). La stessa chiave con lo stesso corpo restituisce il primo job con `Idempotent-Replayed: true`; la stessa chiave con un corpo diverso fallisce con `422 idempotency_key_reuse`. Gli SDK e la CLI impostano l'intestazione per te.

I filtri sono gli stessi di [Elenca gli eventi di audit](../audit-events/list.md); un campo omesso non filtra. Differenze:

| Campo | Tipo | Descrizione |
|---|---|---|
| `stream` | string | `admin` (predefinito) oppure `application`. |
| `from` | RFC 3339 | Limite inferiore incluso. Il valore predefinito è l'inizio della finestra di conservazione. Non c'è un limite di 92 giorni; un pacchetto contiene al massimo 50 milioni di righe (segnaposto inclusi). |
| `to` | RFC 3339 | Limite superiore escluso. Il valore predefinito è l'ora attuale; non può essere nel futuro. |
| `action`, `category`, `actor_type`, `actor_id`, `target_type`, `target_id`, `org_id`, `outcome`, `request_id`, `correlation_id`, `agent_only` | | Come nei filtri dell'elenco. Il filtro `client` dell'elenco non è disponibile qui; un campo `client` fallisce con `400 unknown_field`. |
| `include_ip` | boolean | Aggiunge indirizzo IP completo e agente utente ai record più recenti di 13 mesi. Richiede anche `audit-events:read_ip`. Predefinito `false`. |

```json
{
  "stream": "admin",
  "from": "2026-07-01T00:00:00Z",
  "to": "2026-10-01T00:00:00Z",
  "action": "user."
}
```

Al massimo 3 job girano contemporaneamente per ambiente (1 negli ambienti di sviluppo e staging).

## Risposta

`202 Accepted` e il job con `status` `queued`. `filter` mostra il filtro applicato con i valori predefiniti di `from` e `to` compilati. `recorded_before` è il limite dello snapshot: entrano nel pacchetto solo i record memorizzati prima di questo valore.

```json
{
  "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"}
}
```

## Errori

Ogni errore è un corpo `application/problem+json` con un `code` stabile.

| HTTP | `code` | Quando |
|---|---|---|
| 400 | `malformed_request` | `Idempotency-Key` manca o è malformata, oppure il corpo non è JSON valido. |
| 400 | `unknown_field` | Il corpo contiene un campo non elencato sopra. |
| 400 | `invalid_filter` | Il servizio di audit ha rifiutato il filtro, per esempio `to` nel futuro. |
| 400 | `range_outside_retention` | `from` o `to` sono fuori dalla finestra di conservazione dell'audit del tuo piano. |
| 422 | `validation_failed` | Un campo non è valido (tipo errato, timestamp non valido, `to` non successivo a `from`, valore enum sconosciuto, id malformato, stringa vuota). |
| 422 | `idempotency_key_reuse` | `Idempotency-Key` è stata usata con un corpo diverso. |
| 401 | `unauthenticated` | La chiave API manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La chiave non ha `audit-exports:write`, usa `include_ip` senza `audit-events:read_ip` (`required_permissions` elenca entrambe), oppure il chiamante non è una chiave API. |
| 429 | `rate_limited` | Troppi job sono in esecuzione in questo ambiente, oppure è stato superato il limite di frequenza; rispetta `Retry-After`. |
| 503 | `service_unavailable` | Una dipendenza è temporaneamente non disponibile; riprova più tardi. |

## Esempio

```bash
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."}'
```

```bash
keenauth audit-exports create --from 2026-07-01T00:00:00Z --to 2026-10-01T00:00:00Z --action user.
```

## Dati personali

Questo endpoint contiene dati personali: eventi di audit. [I dati personali nelle API di KeenAuth](/docs/policies/personal-data) descrive cosa viene memorizzato, per quanto tempo viene conservato e come viene cancellato. Non inviare categorie particolari di dati personali (salute, dati biometrici, religione, opinioni politiche, orientamento sessuale) in nessun campo.
