Usuarios externos
Identifica a los usuarios de tu aplicación, vincúlalos a una ficha de cliente del CRM y consulta el listado con /external/v1/users.
Actualizado el . 7 min de lectura
Incluido en todos los planes. Ver precios
Con /external/v1/users tu aplicación registra en UTILIA OS a sus
usuarios finales y consulta los que ya tiene vinculados. Es el primer
paso para emitir facturas, guardar tarjetas o abrir tickets en nombre de
esos usuarios.
Autenticación
Todas las peticiones llevan la clave de API de la aplicación en la
cabecera X-Api-Key:
X-Api-Key: <api_key_de_la_app>
Plan y permisos
Antes que el permiso de la aplicación se comprueba el plan de tu
organización. Sin el aplicativo Integraciones contratado, la
respuesta es 403 con errorCode: 'MODULE_NOT_ENABLED'.
| Endpoint | Aplicativo del plan | Permiso de la API (scope) |
|---|---|---|
POST /external/v1/users/identify | Integraciones | crm:users:write |
GET /external/v1/users | Integraciones | crm:users:read |
| NIF y dirección de facturación guardados, en las dos rutas | Integraciones | además, crm:users:read:fiscal-data |
crm:users:read:fiscal-data («Ver los datos fiscales de los usuarios») es un permiso de datos personales críticos: para un autónomo, el NIF lo identifica. Solo lo concede un Super Administrador, con un motivo de al menos veinte caracteres. No sustituye a los otros dos: el listado sigue pidiendo crm:users:read y el alta, crm:users:write.
Desde el 21 de octubre de 2026, el NIF solo con su permiso
Hasta ese día, el listado y la respuesta de identify devolvían el NIF (taxId) y la dirección de facturación (billingAddress) guardados con el permiso básico. Ahora solo llegan con crm:users:read:fiscal-data. Si tu integración los leía de ahí, pide a un Super Administrador que conceda el permiso; si no, guárdalos en tu sistema cuando los mandes. Que no lleguen no significa que no estén guardados.
identify exige crm:users:write desde el 5 de septiembre de 2026
Dar de alta o actualizar a un usuario final trata datos personales y
fiscales (correo, NIF y dirección de facturación), así que exige
crm:users:write; la lectura sola (crm:users:read) no basta.
Si tu aplicación ya usaba identify, concédele crm:users:write antes
de nada: no hay periodo de gracia y la llamada responde
403 INSUFFICIENT_SCOPE desde el primer momento.
Sin el permiso adecuado, la respuesta es 403 INSUFFICIENT_SCOPE con el permiso que
falta en requiredScopes. El catálogo completo está en
Permisos de la API.
Endpoints
/api/external/v1/users/identifyDa de alta o actualiza un usuario externo por su externalId. Permiso: crm:users:write.
/api/external/v1/usersLista los usuarios externos vinculados a la aplicación, primero los que han tenido actividad más reciente. Permiso: crm:users:read; el NIF y la dirección de facturación, solo con crm:users:read:fiscal-data.
Cuerpo de identify
- externalIdstringobligatorio
- Identificador estable del usuario en tu sistema (máximo 255 caracteres). Junto con la aplicación, es la clave para crear o actualizar.
- emailstring
- Correo del usuario. Se valida su formato.
- namestring
- Nombre o razón social (máximo 255 caracteres).
- avatarUrlstring
- Dirección de la imagen del usuario. Se valida que sea una URL.
- metadataobject
- Metadatos libres asociados al usuario.
- taxIdstring
- NIF o CIF del usuario final (máximo 50 caracteres). Se copia a su ficha de cliente del CRM y al cliente de la pasarela de pago.
- billingAddressobject
- Dirección de facturación. Si la envías, sustituye a la guardada. Es la que se imprime en el PDF de sus facturas.
- clientIdstring
- Ficha de cliente del CRM a la que vincular el usuario, cuando tu aplicación la creó antes con POST /external/v1/clients o con el propio puente. Sin este campo, UTILIA OS crea o reutiliza la ficha la primera vez que factura, guarda una tarjeta o crea una suscripción para el usuario.
Campos de billingAddress:
- streetstringobligatorio
- Calle y número o indicación de la dirección (máximo 255 caracteres).
- citystringobligatorio
- Ciudad o municipio (máximo 100 caracteres).
- postalCodestringobligatorio
- Código postal (máximo 20 caracteres).
- countrystringobligatorio
- País en texto libre o código ISO (máximo 100 caracteres). Mejor en castellano (por ejemplo, «España») para que coincida con el PDF de la AEAT.
- provincestring
- Provincia o región administrativa (máximo 100 caracteres).
taxId y billingAddress también viajan en el bloque user de la
creación de una factura, y el alta rellena con los datos del receptor
los huecos que el usuario no tenga guardados. Aun así, mándalos aquí en
cuanto los tengas: una factura emitida a un cliente sin identificador
fiscal obliga a rectificarla después. Lo que declare identify manda
siempre sobre lo que se deduzca del receptor, y omitir un campo no borra
el que ya estaba guardado. Si tu aplicación llamaba a identify sin
datos fiscales, no tienes que cambiar nada: los dos campos son opcionales.
Parámetros del listado
- pagenumber
- Página que se pide. Por defecto, 1.
- limitnumber
- Usuarios por página, de 1 a 100. Por defecto, 20.
La respuesta trae users y un bloque pagination con page, limit,
total y totalPages. Cada usuario lleva taxId y billingAddress
solo si la aplicación tiene crm:users:read:fiscal-data; sin él, esos
dos campos no vienen, ni siquiera a null, y ni se leen de la base de
datos.
Qué devuelve identify
identify responde siempre con el usuario dado de alta o actualizado,
con id, appId, externalId, lastSeenAt, createdAt y
updatedAt. Lo demás depende de los permisos de la aplicación y de
dónde está su clave, porque cualquiera que tenga una clave publicada en
una página podría mandar el externalId de otro usuario y leer su ficha:
¿Qué datos devuelve identify?
¿Tiene la aplicación crm:users:read (o crm:users:read:fiscal-data) y una clave que no está publicada en páginas web?
No:
Solo lo que mandas
Los campos que enviaste en esta llamada, con el valor que quedó guardado. Lo que no mandaste no viene.Sí:
¿Tiene además crm:users:read:fiscal-data?
Sí:
La ficha guardada entera
Correo, nombre, imagen, metadatos, ficha de cliente, NIF y dirección de facturación.No:
La ficha guardada, sin lo fiscal
Todo menos el NIF y la dirección de facturación, que solo vienen si los mandaste en esta llamada.
Una clave cuenta como publicada si la aplicación tiene dominios
autorizados o si la clave se ha usado desde un navegador desde su última
renovación (Claves dentro de una página web).
Con la del widget, por tanto, identify solo devuelve el eco de lo que
mandas, y clientId solo si lo mandaste tú.
El usuario externo se convierte en cliente del CRM
Dar de alta a un usuario no crea todavía nada en el CRM. La ficha de cliente nace cuando hace falta, la primera vez que hay dinero de por medio:
De usuario de tu aplicación a cliente del CRM
Usuarios externos
Dar de alta al usuario
identify lo crea o lo actualiza por su externalId.Finanzas
Primera factura, tarjeta o suscripción
Es lo que pone en marcha el puente con el CRM.CRM
Buscar una ficha de la aplicación
Por NIF exacto y después por correo, solo entre las fichas que creó tu aplicación.Si no: crea una ficha nueva.
Desde ese momento el usuario existe para Finanzas y para el CRM como
cualquier otro cliente, y la ficha muestra de qué
aplicación viene. La respuesta de identify devuelve el clientId
cuando ese vínculo ya existe y la aplicación puede leer lo guardado (ver
Qué devuelve identify).
Tu aplicación solo alcanza las fichas que ella creó
El puente de identidad trabaja únicamente sobre fichas de cliente que
haya creado la propia aplicación, con POST /external/v1/clients o con
el propio puente. Una ficha nativa del CRM, dada de alta por tu equipo
desde el panel, nunca se toca desde la API externa.
clientIdenidentifysolo acepta fichas propias. Con cualquier otra, la respuesta es404 CLIENT_NOT_ACCESSIBLE, nunca un 403: decir que existe permitiría descubrir fichas ajenas probando identificadores.- La deduplicación automática busca por NIF exacto y después por correo exacto, pero solo entre las fichas propias. Si la coincidencia cae en una ficha nativa, no se reutiliza ni se modifica: se crea una ficha nueva y la coincidencia queda en el registro de auditoría para que tu equipo la revise.
Enlazar un usuario de la aplicación con una ficha nativa sigue siendo posible, pero lo decide tu equipo desde el panel, con sesión iniciada y permiso sobre esa ficha. Lo explica Panel de aplicaciones externas.
Ejemplos
# Identificar (alta o actualización)
curl -X POST 'https://os.utilia.ai/api/external/v1/users/identify' \
-H 'X-Api-Key: utl_xxx' \
-H 'Content-Type: application/json' \
-d '{
"externalId": "user_01HXYZ",
"email": "cliente@empresa.com",
"name": "Empresa de Canarias SL",
"taxId": "B76543210",
"billingAddress": {
"street": "Avenida de Canarias 12, planta 3",
"city": "Las Palmas de Gran Canaria",
"postalCode": "35001",
"country": "España",
"province": "Las Palmas"
}
}'
# Listar usuarios vinculados
curl -X GET 'https://os.utilia.ai/api/external/v1/users?page=1&limit=20' \
-H 'X-Api-Key: utl_xxx'Errores propios de estos endpoints
403 MODULE_NOT_ENABLED: el plan de tu organización no incluye el aplicativo Integraciones.403 INSUFFICIENT_SCOPE: faltacrm:users:writeal identificar ocrm:users:readal listar. Que faltecrm:users:read:fiscal-datano da error: los datos fiscales guardados, simplemente, no vienen.404 CLIENT_NOT_ACCESSIBLE: elclientIdno es de tu organización, ya está vinculado a un usuario de otra aplicación o es una ficha nativa del CRM que esta aplicación no creó.400 VALIDATION_ERROR: el cuerpo no cumple las restricciones (correo mal formado,externalIdvacío) olimitpasa de 100.
Siguiente paso
Con los usuarios identificados, tu aplicación puede emitir facturas en su nombre con los endpoints de facturas o abrir tickets de soporte con los endpoints de tickets.