Actualizar un usuario
PATCH /v1/users/{user_id} · permiso users:write
Actualiza un usuario con un parche de fusión JSON (Content-Type: application/merge-patch+json). Solo cambian los campos que envíe. Los campos de texto se borran con null o con una cadena vacía; email_verified y phone_verified no se pueden borrar; address se reemplaza por completo; user_metadata y app_metadata se fusionan clave por clave, y un valor null elimina esa clave; enviar user_metadata o app_metadata como null elimina todo su contenido y deja {}. El estado no se puede cambiar aquí; use bloquear y desbloquear. No se puede actualizar un usuario que está pendiente de eliminación. If-Match es opcional: si se envía, debe coincidir con el ETag actual del usuario.
Solicitud
| Parámetro | En | Obligatorio | Descripción |
|---|---|---|---|
user_id |
path | sí | Identificador del usuario, con el prefijo usr_. |
If-Match |
header | no | El ETag de una lectura anterior. |
El cuerpo acepta los mismos campos que Crear un usuario, todos opcionales, más los campos de edad indicados a continuación. Los campos desconocidos se rechazan con unknown_field.
Edad y consentimiento parental
Cuando su propio proceso de verificación de edad o de consentimiento parental termine, registre su resultado en el usuario con estos campos. También se devuelven en cada objeto de usuario; null indica que el usuario no ha sido evaluado.
| Campo | Valores | Notas |
|---|---|---|
age_group |
adult, minor, unknown |
No se puede borrar; envíe unknown cuando no se conozca la edad. |
parental_consent_status |
not_required, pending, granted, denied, revoked |
null lo borra. Cualquier valor distinto de not_required solo se acepta si el age_group del usuario es minor. |
age_assurance_level |
self_declared, birthdate_declared, third_party_verified |
null lo borra. Indica con qué firmeza su proceso estableció la edad. |
Un cambio en age_group o en parental_consent_status emite un evento user.updated. No incluya una fecha de nacimiento ni un número de documento de identidad en estos campos ni en los metadatos para respaldarlos; envíe solo el resultado.
Respuesta
200 OK. El cuerpo es el objeto de usuario. La cabecera ETag contiene la versión del usuario.
Los datos personales se enmascaran cuando la clave no tiene el permiso users:read_pii: email pasa a ser a***@e***.com, phone_number conserva solo sus 2 últimos dígitos (+**********67), name, given_name, family_name, middle_name y nickname pasan a ser iniciales (A. L.), username conserva solo su primer carácter (a***), birthdate pasa a ser ****-**-** y address pasa a ser {"redacted": true}. user_metadata y app_metadata no se enmascaran.
{
"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,
"age_group": "adult",
"parental_consent_status": null,
"age_assurance_level": "self_declared",
"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
}
Errores
Cada error es un cuerpo application/problem+json con un code estable.
| HTTP | code |
Cuándo |
|---|---|---|
| 400 | malformed_request, unknown_field |
El parche no es un objeto JSON, o un campo no está en el esquema; o If-Match tiene un formato incorrecto. |
| 409 | conflict |
El valor ya está en uso, o el usuario está pendiente de eliminación (errors[].code es user_pending_deletion). |
| 412 | precondition_failed |
If-Match no coincide con la versión actual. |
| 415 | unsupported_media_type |
Content-Type no es application/merge-patch+json. |
| 422 | validation_failed |
Un valor no es válido o tiene un tipo incorrecto; errors[].pointer indica el campo. |
| 404 | not_found |
El usuario no existe en este entorno (o el identificador tiene un formato incorrecto). |
| 401 | unauthenticated |
Falta la clave de API, no es válida o ha sido revocada. |
| 403 | insufficient_permissions |
La clave no tiene el permiso users:write. |
| 429 | rate_limited |
Se superó el límite de uso; respete Retry-After. |
| 503 | service_unavailable |
Una dependencia no está disponible temporalmente; reintente más tarde. |
Ejemplo
curl -X PATCH https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/merge-patch+json" \
-d '{"name": "Ada King", "app_metadata": {"tier": "gold"}}'
Registre un consentimiento parental concedido para un menor:
curl -X PATCH https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/merge-patch+json" \
-d '{"age_group": "minor", "parental_consent_status": "granted", "age_assurance_level": "third_party_verified"}'
Datos personales
Este endpoint contiene datos personales: perfil de usuario final. Datos personales en las API de KeenAuth describe qué se almacena, durante cuánto tiempo se conserva y cómo se elimina. No envíe categorías especiales de datos personales (salud, datos biométricos, religión, opiniones políticas, orientación sexual) en ningún campo.