
# Rechercher des utilisateurs

`POST /v1/users:search` · autorisation `users:read`

Recherche des utilisateurs à l'aide de filtres contenant des données personnelles. Ces filtres sont acceptés uniquement dans le corps de la requête, jamais dans la chaîne de requête, car les chaînes de requête finissent dans les journaux des proxys et des clients. Les filtres se combinent avec AND et au moins un filtre d'identité est requis. Les correspondances sont exactes ; la recherche par préfixe et la recherche par sous-chaîne ne sont pas proposées. Une recherche qui correspond à trop d'utilisateurs échoue avec `search_too_broad` ; affinez les filtres.

## Requête

Les paramètres de pagination vont dans la chaîne de requête ; ils ne contiennent aucune donnée personnelle.

| Paramètre | Dans | Obligatoire | Description |
|---|---|---|---|
| `limit` | query | non | Taille de page, de 1 à 100. Valeur par défaut : 20. |
| `after` | query | non | Curseur opaque issu de `list_metadata.after`. Exclusif avec `before`. |
| `before` | query | non | Curseur opaque issu de `list_metadata.before`. Exclusif avec `after`. |
| `order` | query | non | `asc` ou `desc` selon la date de création. Valeur par défaut : `desc`. |

Champs du corps :

| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| `email` | string | non | Adresse e-mail exacte. |
| `phone` | string | non | Numéro de téléphone exact au format E.164. |
| `username` | string | non | Nom d'utilisateur exact. |
| `email_domain` | string | non | Domaine e-mail exact. |
| `app_metadata`, `user_metadata` | object | non | Jusqu'à 3 clés de premier niveau ; chaque clé doit correspondre à une valeur scalaire. |
| `status` | string | non | `active`, `blocked` ou `pending_deletion`. |

Un curseur n'est valide qu'avec le même ensemble de filtres et le même ordre que ceux pour lesquels il a été émis.

## Réponse

`200 OK`. `data` contient les utilisateurs de la page ; `list_metadata.before` et `list_metadata.after` sont les curseurs de la page précédente et de la page suivante (`null` lorsqu'il n'y en a pas). Aucun nombre total n'est renvoyé.

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. Une clé sans `users:read_pii` peut tout de même rechercher avec des filtres exacts sur des données personnelles ; les résultats sont masqués.

```json
{
  "data": [ {
    "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
  } ],
  "list_metadata": { "before": null, "after": "<opaque cursor>" }
}
```

## Erreurs

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

| HTTP | `code` | Quand |
|---|---|---|
| 400 | `unknown_field`, `invalid_cursor` | Le corps contient un champ non pris en charge (par exemple un filtre par préfixe), ou le curseur ne correspond pas à la requête. |
| 415 | `unsupported_media_type` | `Content-Type` n'est pas `application/json`. |
| 422 | `validation_failed`, `search_too_broad` | Un filtre est invalide, aucun filtre d'identité n'a été fourni, ou la recherche correspond à trop d'utilisateurs. |
| 401 | `unauthenticated` | La clé API est absente, invalide ou révoquée. |
| 403 | `insufficient_permissions` | La clé ne dispose pas de l'autorisation `users:read`. |
| 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:search?limit=20" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "ada@example.com"}'
```

## Données personnelles

Cet endpoint 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é, la durée de conservation et la manière dont elles sont supprimées. N'envoyez aucune catégorie particulière de données personnelles (santé, données biométriques, religion, opinions politiques, orientation sexuelle) dans aucun champ.
