
# Créer un utilisateur

`POST /v1/users` · autorisation `users:write`

Crée un utilisateur dans l'environnement de la clé API. L'utilisateur n'appartient qu'à cet environnement ; la même adresse e-mail dans deux environnements correspond à deux utilisateurs distincts. Les valeurs uniques (`email`, `phone_number`, `username`, `external_id`) sont vérifiées par environnement. Envoyez un en-tête `Idempotency-Key` pour rendre les nouvelles tentatives sans risque.

## Requête

Le corps est un objet JSON. Les champs inconnus sont rejetés avec `unknown_field`.

| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| `email` | string | non* | Adresse e-mail principale. |
| `email_verified` | boolean | non | Marque l'adresse e-mail comme vérifiée. Par défaut `false`. |
| `phone_number` | string | non* | Numéro de téléphone principal au format E.164. |
| `phone_verified` | boolean | non | Marque le numéro de téléphone comme vérifié. Par défaut `false`. |
| `phone_country_code` | string | non | Code ISO 3166-1 alpha-2. Déduit de l'indicatif du téléphone lorsqu'il est vide. |
| `username` | string | non* | De 3 à 64 caractères. Unique dans l'environnement. |
| `external_id` | string | non | Votre propre identifiant, de 1 à 255 caractères. Unique dans l'environnement. |
| `name`, `given_name`, `family_name`, `middle_name`, `nickname` | string | non | Noms du profil. |
| `picture`, `website`, `profile_url` | string | non | URL `https://`, jusqu'à 2048 caractères. |
| `locale`, `zoneinfo`, `gender`, `birthdate` | string | non | Attributs du profil. `birthdate` est au format `YYYY-MM-DD`. |
| `address` | object | non | Objet `address` OIDC, jusqu'à 2048 octets. |
| `user_metadata`, `app_metadata` | object | non | Objets JSON libres, jusqu'à 16 KiB, profondeur 5, 100 clés de premier niveau. |

\* Au moins l'un des champs `email`, `phone_number` ou `username` est requis.

## Réponse

`201 Created`. Le corps est l'objet utilisateur. L'en-tête `ETag` contient la version de l'utilisateur.

Les données personnelles sont masquées lorsque la clé ne dispose pas de l'autorisation `users:read_pii` : `email` devient `a***@e***.com`, `phone_number` ne conserve que ses 2 derniers chiffres (`+**********67`), `name`, `given_name`, `family_name`, `middle_name` et `nickname` deviennent des initiales (`A. L.`), `username` ne conserve que son premier caractère (`a***`), `birthdate` devient `****-**-**` et `address` devient `{"redacted": true}`. `user_metadata` et `app_metadata` ne sont pas masqués.

```json
{
  "id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p",
  "kind": "regular",
  "status": "active",
  "external_id": null,
  "username": null,
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "email_verified": true,
  "phone_number": null,
  "phone_verified": false,
  "user_metadata": {},
  "app_metadata": {},
  "created_via": "admin_api",
  "created_at": "2026-01-15T09:30:00Z",
  "updated_at": "2026-01-15T09:30:00Z",
  "last_sign_in_at": null,
  "deletion_requested_at": null,
  "deletion_due_at": null
}
```

## Erreurs

Chaque erreur est un corps `application/problem+json` avec un `code` stable.

| HTTP | `code` | Quand |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | Le corps n'est pas un JSON valide ou contient un champ absent du schéma. |
| 409 | `conflict` | La valeur est déjà utilisée. `errors[]` indique le champ et la raison (`email_taken`, `phone_taken`, `username_taken`, `external_id_taken`). |
| 415 | `unsupported_media_type` | `Content-Type` n'est pas `application/json`. |
| 422 | `validation_failed` | Une valeur est invalide ; `errors[].pointer` indique le champ. |
| 401 | `unauthenticated` | La clé API est absente, invalide ou révoquée. |
| 403 | `insufficient_permissions` | La clé ne dispose pas de l'autorisation `users:write`. |
| 429 | `rate_limited` | La limite de débit a été dépassée ; respectez `Retry-After`. |
| 503 | `service_unavailable` | Une dépendance est temporairement indisponible ; réessayez plus tard. |

## Exemple

```bash
curl -X POST https://api.eu.keenauth.com/v1/users \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"email": "ada@example.com", "email_verified": true, "name": "Ada Lovelace"}'
```

## Données personnelles

Cet point de terminaison traite des données personnelles : profil de l'utilisateur final. [Données personnelles dans les API KeenAuth](/docs/policies/personal-data) décrit ce qui est stocké, pendant combien de temps et comment elles sont supprimées. N'envoyez de catégories particulières de données personnelles (santé, données biométriques, religion, opinions politiques, orientation sexuelle) dans aucun champ.
