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.