
# Creare un job di eliminazione utenti in blocco

`POST /v1/jobs/user-deletions` · permessi `users:delete` e `jobs:write`

Elimina fino a 10.000 utenti in un unico job asincrono. Ogni utente segue la stessa eliminazione di [`DELETE /v1/users/{user_id}`](/docs/api/management/users/delete): l'utente diventa `pending_deletion` e l'eliminazione definitiva viene eseguita in seguito; il record di eliminazione indica che proviene da un job in blocco. L'eliminazione non può essere annullata, quindi l'endpoint funziona in due passaggi:

1. Invia la richiesta con `"dry_run": true`. Non viene scritto nulla; la risposta contiene `matched_count`, il numero di utenti che la richiesta eliminerebbe.
2. Invia la stessa selezione con `"confirm_count"` impostato su quel numero. Se nel frattempo il numero di utenti corrispondenti è cambiato, la richiesta fallisce con `409 confirmation_mismatch` e non viene creato alcun job; esegui di nuovo la simulazione.

Seleziona gli utenti in uno dei due modi: `user_ids` (gli ID ripetuti contano una volta; i risultati mantengono l'ordine della prima comparsa) oppure `organization_id` (i membri attivi e sospesi dell'organizzazione nel momento in cui viene creato il job). Gli ID che non corrispondono a un utente restano nel job e vengono riportati come `not_found`.

In un ambiente può essere in esecuzione un solo job di eliminazione utenti in blocco alla volta; mentre ne è in corso uno, un nuovo job viene rifiutato con `429 rate_limited` e `Retry-After`. Il job viene scritto nel log di audit di gestione alla creazione e al completamento; ogni utente eliminato ha inoltre una propria voce di audit di eliminazione. Segui il job con [Ottenere un job di eliminazione utenti in blocco](/docs/api/management/jobs/get-user-deletion) e leggi l'esito per utente con [Elencare i risultati di eliminazione utenti in blocco](/docs/api/management/jobs/list-user-deletion-results).

## Richiesta

**Header**: `Idempotency-Key` (obbligatorio, 16–64 caratteri `A-Z a-z 0-9 _ -`). Ripetere la richiesta con la stessa chiave e lo stesso body restituisce il primo job; la stessa chiave con un body diverso fallisce con `422 idempotency_key_reuse`. Il body può arrivare fino a 512 KiB.

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `user_ids` | array di stringhe | uno dei due | ID utente con prefisso `usr_`, da 1 a 10.000. |
| `organization_id` | stringa | uno dei due | ID organizzazione con prefisso `org_`; al massimo 10.000 membri. |
| `dry_run` | booleano | no | `true`: conta solo gli utenti; non viene scritto nulla. Predefinito `false`. |
| `confirm_count` | intero | sì, salvo `dry_run` | Il `matched_count` della simulazione (0–10.000). |

## Risposta

Simulazione: `200 OK` con `{"dry_run": true, "matched_count": n}`.

Job creato: `202 Accepted` con il conteggio e il job.

```json
{
  "dry_run": false,
  "matched_count": 2,
  "job": {
    "id": "job_01h455vb4pex5vsknk084sn02q",
    "status": "running",
    "filter": "user_ids",
    "total": 3,
    "succeeded": 0,
    "not_found": 0,
    "failed": 0,
    "pending": 3,
    "created_at": "2026-01-15T09:30:00Z"
  }
}
```

## Errori

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

| HTTP | `code` | Quando |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | L'header `Idempotency-Key` manca o non è valido, oppure il body non è JSON valido o contiene un campo sconosciuto. |
| 401 | `unauthenticated` | La chiave API manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La chiave non ha `users:delete` o `jobs:write`. |
| 409 | `confirmation_mismatch` | `confirm_count` non è il numero attuale di utenti corrispondenti. |
| 409 | `idempotency_in_progress` | Una richiesta con la stessa `Idempotency-Key` è ancora in elaborazione. |
| 413 | `payload_too_large` | Il body supera 512 KiB. |
| 422 | `validation_failed` | Entrambi o nessuno tra `user_ids` e `organization_id`, un ID malformato, più di 10.000 utenti (`too_many`, `too_many_users`), un'organizzazione senza membri (`no_users`) oppure un `confirm_count` mancante (`required`). |
| 422 | `idempotency_key_reuse` | La `Idempotency-Key` è stata usata con un body diverso. |
| 429 | `rate_limited` | È in esecuzione un altro job di eliminazione utenti in blocco, oppure è stato superato il limite di frequenza; rispetta `Retry-After`. |
| 503 | `service_unavailable` | Una dipendenza non è temporaneamente disponibile; riprova più tardi. |

## Esempio

```bash
curl -X POST https://api.eu.keenauth.com/v1/jobs/user-deletions \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"organization_id": "org_01h455vb4pex5vsknk084sn02q", "dry_run": true}'
```

CLI: `keenauth jobs user-deletions create --organization-id org_01h455vb4pex5vsknk084sn02q --dry-run --yes`, poi `keenauth jobs user-deletions create --organization-id org_01h455vb4pex5vsknk084sn02q --confirm-count 42 --yes`. Gli elenchi lunghi di ID vanno in un file: `--data @users.json`.
