API de Usuarios
La API de Usuarios proporciona gestión completa del ciclo de vida de las cuentas de usuario dentro de un tenant: crear, leer, actualizar, deshabilitar y eliminar usuarios; asignar roles; importar y exportar usuarios en masa; y gestionar números de teléfono y la configuración de autenticación en dos pasos para cuentas individuales.
Todos los endpoints de esta sección requieren la cabecera x-tenant y, salvo que se indique lo contrario, requieren el permiso manage:users.
Gestión de Usuarios
/api/usersRequires: manage:usersLista todos los usuarios del tenant. Admite paginación y filtrado por rol, estado de cuenta y consulta de búsqueda. Devuelve objetos de usuario con información resumida (no incluye el estado de 2FA ni detalles de sesión — usa el endpoint de usuario individual para eso).
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
page | integer | Número de página (predeterminado: 1) |
limit | integer | Elementos por página (predeterminado: 20, máx: 100) |
search | string | Búsqueda de texto completo en email, username, firstName, lastName |
role | string | Filtrar por nombre de rol |
status | active | disabled | locked | Filtrar por estado de cuenta |
Respuesta exitosa
{
"ok": true,
"data": {
"data": [
{
"id": "usr_abc123",
"email": "[email protected]",
"username": "alice",
"firstName": "Alice",
"lastName": "Smith",
"enabled": true,
"emailVerified": true,
"createdAt": "2025-01-15T10:30:00Z",
"roles": ["editor", "viewer"]
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 87,
"totalPages": 5
}
}
}/api/usersRequires: manage:usersCrea una nueva cuenta de usuario en el tenant. El usuario se crea tanto en la base de datos de
Auris como en el realm de Keycloak subyacente. Si se omite password, la cuenta se crea sin
contraseña (el usuario deberá establecer una mediante un magic link o el flujo de restablecimiento
de contraseña).
Cuerpo de la solicitud
{
"email": "[email protected]",
"username": "bob",
"firstName": "Bob",
"lastName": "Jones",
"password": "initialPassword123",
"roles": ["viewer"],
"enabled": true
}Todos los campos excepto email son opcionales.
Respuesta exitosa
{
"ok": true,
"data": {
"id": "usr_def456",
"email": "[email protected]",
"username": "bob",
"firstName": "Bob",
"lastName": "Jones",
"enabled": true,
"emailVerified": false,
"createdAt": "2025-02-18T09:00:00Z",
"roles": ["viewer"]
}
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
EMAIL_TAKEN | 409 | Ya existe un usuario con este email en el tenant |
USERNAME_TAKEN | 409 | El nombre de usuario ya está en uso |
VALIDATION_ERROR | 400 | El cuerpo de la solicitud no superó la validación del esquema |
/api/users/[id]Requires: manage:usersRecupera un usuario individual por su ID. Devuelve los detalles completos del usuario incluyendo membresías de roles, estado de 2FA, número de teléfono, membresías de grupos e información del último inicio de sesión.
Respuesta exitosa
{
"ok": true,
"data": {
"id": "usr_abc123",
"email": "[email protected]",
"username": "alice",
"firstName": "Alice",
"lastName": "Smith",
"enabled": true,
"emailVerified": true,
"phoneNumber": "+39 02 1234567",
"phoneNumberVerified": true,
"createdAt": "2025-01-15T10:30:00Z",
"lastLoginAt": "2025-02-17T14:22:00Z",
"roles": ["editor", "viewer"],
"twoFactor": {
"totpEnabled": true,
"smsEnabled": false,
"webauthnEnabled": false
}
}
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
NOT_FOUND | 404 | El usuario no existe en este tenant |
/api/users/[id]Requires: manage:usersActualiza los campos del perfil de un usuario. Todos los campos son opcionales — solo se actualizan
los campos proporcionados. Para deshabilitar un usuario sin eliminarlo, establece enabled: false.
Cuerpo de la solicitud
{
"firstName": "Alicia",
"lastName": "Smith-Jones",
"enabled": false
}Respuesta exitosa
{
"ok": true,
"data": {
"id": "usr_abc123",
"email": "[email protected]",
"firstName": "Alicia",
"lastName": "Smith-Jones",
"enabled": false
}
}/api/users/[id]Requires: manage:usersElimina un usuario de forma lógica (soft-delete). La cuenta del usuario se deshabilita y se marca como eliminada en la base de datos de Auris, y su cuenta de Keycloak es eliminada. Las sesiones activas se invalidan inmediatamente.
La eliminación lógica es irreversible a través de la API. El registro del usuario se conserva en la base de datos para mantener la coherencia del registro de auditoría, pero no puede recuperarse ni usarse para iniciar sesión. Usa enabled: false mediante PUT /api/users/[id] si quieres deshabilitar temporalmente sin eliminar.
Respuesta exitosa
{
"ok": true,
"data": { "deleted": true }
}Asignación de Roles
/api/users/[id]/rolesRequires: manage:usersLista todos los roles asignados actualmente a un usuario.
Respuesta exitosa
{
"ok": true,
"data": [
{
"id": "role_123",
"name": "editor",
"description": "Can create and edit content",
"color": "#3b82f6"
}
]
}/api/users/[id]/rolesRequires: manage:usersAsigna un rol a un usuario. El rol debe existir en el tenant. Asignar el mismo rol dos veces es una operación sin efecto (idempotente).
Cuerpo de la solicitud
{
"roleId": "role_123"
}Respuesta exitosa
{
"ok": true,
"data": { "assigned": true }
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
NOT_FOUND | 404 | El rol no existe en este tenant |
SELF_ROLE_CHANGE | 403 | No puedes modificar tus propios roles |
/api/users/[id]/rolesRequires: manage:usersElimina un rol de un usuario. Eliminar un rol que el usuario no tiene es una operación sin efecto (idempotente).
Cuerpo de la solicitud
{
"roleId": "role_123"
}Respuesta exitosa
{
"ok": true,
"data": { "removed": true }
}Importación Masiva
/api/users/importRequires: manage:usersImporta usuarios en masa desde un archivo CSV o JSON. La importación se ejecuta de forma
asíncrona — el endpoint devuelve un ID de trabajo inmediatamente. Consulta
GET /api/users/import/[id] para seguir el progreso.
Formato de solicitud: multipart/form-data
| Campo | Tipo | Descripción |
|---|---|---|
file | binary | Archivo CSV o JSON |
format | csv | json | Formato del archivo |
sendWelcomeEmail | boolean | Enviar correo de bienvenida a los nuevos usuarios (predeterminado: false) |
Formato CSV (la primera fila es la cabecera):
email,firstName,lastName,username,password,roles
[email protected],Alice,Smith,alice,,viewer
[email protected],Bob,Jones,bob,TempPass123,editorFormato JSON:
[
{
"email": "[email protected]",
"firstName": "Alice",
"lastName": "Smith",
"roles": ["viewer"]
}
]Respuesta exitosa (trabajo creado)
{
"ok": true,
"data": {
"jobId": "import_xyz789",
"status": "pending",
"totalRows": 142,
"createdAt": "2025-02-18T10:00:00Z"
}
}/api/users/importRequires: manage:usersLista todos los trabajos de importación del tenant actual, ordenados por hora de creación descendente.
Respuesta exitosa
{
"ok": true,
"data": {
"data": [
{
"id": "import_xyz789",
"fileName": "users-2025-02.csv",
"format": "csv",
"status": "completed",
"totalRows": 142,
"processedRows": 142,
"successCount": 140,
"errorCount": 2,
"createdAt": "2025-02-18T10:00:00Z",
"completedAt": "2025-02-18T10:01:34Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}
}/api/users/import/[id]Requires: manage:usersObtiene el estado actual y los detalles de error de un trabajo de importación.
Respuesta exitosa
{
"ok": true,
"data": {
"id": "import_xyz789",
"status": "completed",
"totalRows": 142,
"processedRows": 142,
"successCount": 140,
"errorCount": 2,
"errors": [
{
"row": 45,
"email": "bad@",
"error": "Invalid email address"
},
{
"row": 98,
"email": "[email protected]",
"error": "Email already exists"
}
]
}
}Estados del trabajo de importación: pending (pendiente), processing (en proceso), completed (completado), failed (fallido), partial (parcial).
Exportación Masiva
/api/users/exportRequires: manage:usersInicia una exportación de usuarios. La exportación se ejecuta de forma asíncrona. Consulta
GET /api/users/export para encontrar el trabajo y luego descárgalo usando
GET /api/users/export/[id]/download cuando el estado sea completed.
Cuerpo de la solicitud
{
"format": "csv"
}format es "csv" o "json".
Respuesta exitosa
{
"ok": true,
"data": {
"id": "export_abc123",
"status": "pending",
"format": "csv",
"createdAt": "2025-02-18T11:00:00Z"
}
}/api/users/exportRequires: manage:usersLista todos los trabajos de exportación.
/api/users/export/[id]/downloadRequires: manage:usersDescarga el archivo de exportación una vez que el estado del trabajo es completed. Devuelve el
archivo binario con una cabecera Content-Disposition apropiada.
Los archivos de exportación se almacenan temporalmente y expiran después de 24 horas. Descárgalos rápidamente tras completarse el trabajo.
Gestión del Número de Teléfono
Estos endpoints permiten a los usuarios autenticados gestionar su propio número de teléfono. No se requiere ningún permiso especial más allá de un access token válido.
/api/user/phone/setRequires: authenticated userEstablece o actualiza el número de teléfono del usuario autenticado. Después de establecerlo,
el número debe verificarse usando POST /api/user/phone/verify. Se envía un OTP por SMS al
número proporcionado.
Cuerpo de la solicitud
{
"phoneNumber": "+39021234567"
}El número de teléfono debe estar en formato E.164 (formato internacional con código de país).
Respuesta exitosa
{
"ok": true,
"data": {
"sent": true,
"phoneNumber": "+39021234567"
}
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
INVALID_PHONE | 400 | El número no está en formato E.164 |
PHONE_TAKEN | 409 | El número ya está asociado a otra cuenta |
SMS_RATE_LIMITED | 429 | Demasiadas solicitudes de SMS (máx. 5 por hora) |
/api/user/phone/verifyRequires: authenticated userVerifica el número de teléfono con el código OTP enviado por SMS. Si tiene éxito, phoneNumberVerified
se establece en true en la cuenta del usuario.
Cuerpo de la solicitud
{
"code": "482910"
}Respuesta exitosa
{
"ok": true,
"data": { "verified": true }
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
INVALID_OTP | 400 | El código es incorrecto |
OTP_EXPIRED | 400 | El código ha expirado (TTL: 10 minutos) |
MAX_ATTEMPTS | 400 | Se superó el número máximo de intentos de verificación |
Autenticación en Dos Factores
/api/user/2fa/sms/enableRequires: authenticated userActiva el OTP por SMS como método 2FA para el usuario autenticado. Requiere un número de teléfono verificado. Se envía un OTP para confirmar que el teléfono puede recibir códigos antes de activarlo.
Cuerpo de la solicitud
{
"code": "123456"
}Proporciona el OTP que fue enviado al número de teléfono verificado del usuario.
Respuesta exitosa
{
"ok": true,
"data": { "smsEnabled": true }
}Códigos de error
| Código | HTTP | Descripción |
|---|---|---|
PHONE_NOT_VERIFIED | 400 | El usuario no tiene un número de teléfono verificado |
INVALID_OTP | 400 | El código de confirmación es incorrecto |
/api/user/2fa/webauthn/enableRequires: authenticated userInicia la ceremonia de registro de passkey WebAuthn para activar WebAuthn como método 2FA. Devuelve
un desafío de registro. El cliente debe completar la ceremonia usando la API WebAuthn del navegador
y enviar la AuthenticatorAttestationResponse a POST /api/user/2fa/webauthn/challenge.
Solicitud: No se requiere cuerpo.
Respuesta exitosa (opciones de registro)
{
"ok": true,
"data": {
"challenge": "base64url-challenge",
"rp": { "name": "Auris", "id": "your-auris-domain.com" },
"user": {
"id": "base64url-user-id",
"name": "[email protected]",
"displayName": "Alice Smith"
},
"pubKeyCredParams": [{ "type": "public-key", "alg": -7 }],
"timeout": 60000,
"attestation": "none"
}
}Usa la librería @simplewebauthn/browser para manejar este desafío en el navegador.
Relacionado
- Gestión de Usuarios — Guía de gestión del ciclo de vida de usuarios
- Importación y Exportación — Migración masiva de usuarios mediante CSV/JSON
- Aprovisionamiento SCIM 2.0 — Aprovisionamiento automático de usuarios
- Usuarios y Roles — Gestiona usuarios desde la Consola
- API de Importación y Exportación de Usuarios — Endpoints de importación y exportación masiva