
# Creare una directory

`POST /v1/directories` · autorizzazione `directories:write`

Crea una directory SCIM inattiva per un'organizzazione e il suo primo token SCIM. Fornisci al provider di identità (Okta, Entra ID, Google Workspace…) il `base_url` e il `token`. `token` viene restituito solo in questa risposta, una volta; nessun endpoint lo restituisce in seguito. La risposta riporta `Cache-Control: no-store`, e una risposta riprodotta per lo stesso `Idempotency-Key` omette `token` e riporta `secret_redacted: true`; se l'hai perso, crea un nuovo token con `POST /v1/directories/{directory_id}/tokens`. La creazione viene registrata nell'audit come `directory.created` e `directory.token_created` (il token non entra mai nel log di audit).

`scim_host` deve essere l'host principale dell'ambiente: il suo dominio personalizzato attivo, altrimenti `<slug>.<region>.keenauth.app`. L'URL base SCIM della directory è `https://<scim_host>/scim/v2/<directory>`.

## Richiesta

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `organization_id` | stringa | sì | ID dell'organizzazione (`org_…`); deve esistere in questo ambiente ed essere attiva. |
| `name` | stringa | sì | Da 1 a 64 caratteri, senza caratteri di controllo, senza spazi iniziali o finali. |
| `scim_host` | stringa | sì | L'host principale dell'ambiente (nome DNS in minuscolo); deve instradare verso questo ambiente. |
| `type` | stringa | no | `scim` (predefinito; l'unico tipo in questa release). |
| `token_label` | stringa | no | Etichetta del primo token, da 1 a 100 caratteri; predefinita `Initial token`. |

## Risposta

`201 Created` con la directory, `token_id` e il `token` monouso.

```json
{
  "id": "dir_01j9xm2n4p6q8r0s2t4v6w8y0z",
  "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
  "type": "scim",
  "name": "Okta",
  "state": "inactive",
  "base_url": "https://acme.eu.keenauth.app/scim/v2/dir_01j9xm2n4p6q8r0s2t4v6w8y0z",
  "created_at": "2026-10-19T09:31:00.123456Z",
  "last_request_at": null,
  "provisioning_mode": "user_store",
  "attribute_allowlist": [],
  "unverified_domain_action": "invite",
  "delete_action": "remove_membership",
  "on_delete_memberships": "keep",
  "mass_deprovision_guard": {"enabled": true, "percent": 10, "absolute_min": 25},
  "send_welcome_email": false,
  "token_id": "0192a3b4-c5d6-7e8f-9a0b-1c2d3e4f5a6b",
  "token": "idp_scim_<token>"
}
```

## Errori

| HTTP | code | Quando |
|---|---|---|
| 404 | `not_found` | L'organizzazione non esiste in questo ambiente. |
| 409 | `organization_disabled` | L'organizzazione non è attiva; nessuna directory viene creata. |
| 409 | `organization_pending_deletion` | L'organizzazione è programmata per l'eliminazione; nessuna directory viene creata. |
| 422 | `idempotency_key_reuse` | `Idempotency-Key` è stato usato per una richiesta diversa. |
| 422 | `validation_failed` | Un campo manca o non è valido; `/scim_host` `invalid` quando l'host è malformato o non instrada verso questo ambiente. |
| 401 | `unauthenticated` | La credenziale manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha il permesso richiesto. |
| 429 | `rate_limited` | È stato superato il limite di richieste; riprova dopo il periodo indicato da `Retry-After`. |
| 503 | `service_unavailable` | La sincronizzazione delle directory è temporaneamente non disponibile o non configurata in questo deployment; riprova dopo il periodo indicato da `Retry-After`. |

## Esempio

```bash
curl -i -X POST "https://api.eu.keenauth.com/v1/directories" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","name":"Okta","scim_host":"acme.eu.keenauth.app"}'
```
