Autenticación con clave de acceso
Cómo autentica la API externa a tu aplicación con la cabecera X-Api-Key, qué comprueba en cada petición y qué error devuelve cuando algo falla.
Actualizado el . 7 min de lectura
Incluido en todos los planes. Ver precios
La API externa (https://os.utilia.ai/api/external/v1/...) reconoce a tu aplicación por su clave de API, que envías en la cabecera X-Api-Key en cada petición. No hay sesión, ni cookies, ni token que renovar: la clave basta, y por eso solo debe vivir en tu servidor.
GET /api/external/v1/users HTTP/1.1
Host: os.utilia.ai
X-Api-Key: utl_tu_claveDe dónde sale la clave
Cada aplicación externa tiene una clave propia, que se genera al crearla con Crear la aplicación, desde el botón Nueva aplicación de Ajustes, Creadas por tu empresa. La clave empieza por utl_ y solo se muestra una vez, en la pantalla «Aplicación creada». UTILIA OS guarda únicamente su huella, así que nadie puede volver a enseñártela.
Si la pierdes o sospechas que se ha filtrado, renuévala desde la ficha de la aplicación, en Ajustes. Puedes elegir cuántos días sigue valiendo la anterior (1, 7 o 30) para desplegar la nueva sin cortes, o que deje de valer en el acto, que es lo que toca si se ha filtrado. Mientras la anterior sigue valiendo, las peticiones que la usan funcionan y su respuesta lleva la cabecera X-Utilia-Api-Key-Expires con la fecha en que dejará de valer: si la ves en tus registros, algún servidor tuyo todavía no tiene la nueva. Pueden renovarla quienes tienen el permiso Editar aplicaciones externas o Gestionar aplicaciones externas.
La persona responsable
Cada aplicación tiene una persona responsable, que se ve y se cambia en la ficha. Lo que la aplicación crea o cambia por la API queda a su nombre, y tiene que estar activa: si deja de estarlo y nadie la sustituye, UTILIA OS rechaza todas las peticiones de la aplicación con 403 APP_RESPONSIBLE_INACTIVE.
Lo que la aplicación puede hacer lo deciden, sobre todo, sus permisos de la API (los scopes que le concede la organización), no los permisos de esa persona. Los de la persona solo cuentan en estos casos:
- Rectificativas: emitir una exige además que la persona responsable pueda rectificar esa factura. Si no,
403 APP_RESPONSIBLE_PERMISSION_DENIED. - Suscripciones y cobros programados: se gestionan con el motor de Finanzas en nombre de la persona responsable. Si le han retirado el permiso sobre ellos,
403 APP_RESPONSIBLE_PERMISSION_DENIED. - Escrituras del chat: crear un canal exige que la persona responsable pueda crear canales, y escribir en uno, que quien concedió el canal a la aplicación conserve ese permiso (
403 APP_NOT_AUTHORIZED_IN_CHANNEL).
En el resto (clientes, contactos, leads, comentarios y firmas de presupuesto, facturas, cobros, archivos, usuarios externos y tickets) basta el permiso de la API. Los datos del CRM y de los presupuestos alcanzan a toda la organización; los usuarios externos, las facturas, los cobros, los archivos, los tickets y los errores, solo a los de la propia aplicación.
Qué se comprueba en cada petición
Antes de llegar a la operación, cada petición pasa estos controles, en este orden. El primero que falla corta la petición con su código:
Controles de cada petición a la API externa
Cabecera X-Api-Key
¿Llega la clave en X-Api-Key?
Antes de nada, la clave sola en la dirección se rechaza con 401 API_KEY_IN_URL_NOT_ALLOWED. Solo en eventos en tiempo real vale además un pase de conexión enstreamToken.Si no: 401 API_KEY_REQUIRED, API_KEY_WRONG_HEADER o API_KEY_WRONG_KIND.
¿Es válida y de una aplicación?
Existe, está activa, no ha caducado y pertenece a una aplicación externa. Durante una renovación con transición vale también la anterior.Si no: 401 API_KEY_INVALID o API_KEY_NOT_LINKED.
¿Aplicación y responsable activos?
La aplicación está activa y su persona responsable sigue activa en la organización.Si no: 403 APP_DISABLED o APP_RESPONSIBLE_INACTIVE.
¿Le queda cupo?
Peticiones por hora de la clave; 1.000 en una aplicación nueva.Si no: 429 RATE_LIMIT_EXCEEDED, con Retry-After.
¿El origen está autorizado?
Solo si la petición llega desde una web y la aplicación tiene dominios autorizados.Si no: 403 ORIGIN_NOT_ALLOWED.
¿Se puede usar desde una página?
Desde un navegador, solo los permisos del widget. Ver Claves dentro de una página web.Si no: 403 SCOPE_NOT_ALLOWED_FROM_BROWSER.
Plan de la organización
¿Está en el plan?
El aplicativo y la capacidad de la operación.Si no: 403 MODULE_NOT_ENABLED, CAPABILITY_NOT_ENABLED o FEATURE_COMING_SOON.
Permisos de la aplicación
¿Tiene el permiso?
El permiso de la API que exige la operación, concedido a la aplicación.Si no: 403 INSUFFICIENT_SCOPE, con el permiso en requiredScopes.
Si la organización está suspendida o dada de baja, las consultas siguen funcionando y las escrituras responden 403 TENANT_SUSPENDED o TENANT_CANCELLED. Toda respuesta de error trae además fixedBy (quién lo arregla: tú, la organización o UTILIA OS) y docsUrl, el apartado de la documentación que lo explica. Cada código está en Errores, identificador de petición y reintentos. La organización con la que trabaja la petición sale siempre de la aplicación dueña de la clave, nunca de lo que envíes en el cuerpo.
Para saber qué le pasa a tu clave sin adivinarlo por los errores, GET /api/external/v1/diagnostics devuelve qué puede y qué no puede hacer tu aplicación y por qué. Cómo se usa está en Probar tu integración.
Los límites de uso, los orígenes permitidos y los permisos que admite una clave que va en una página se explican en Límites de uso y CORS.
Eventos en tiempo real: un pase en lugar de la clave
EventSource, la herramienta del navegador para recibir eventos en tiempo real, no permite añadir cabeceras. Para no poner la clave en la dirección, tu servidor pide antes un pase de conexión con la cabecera X-Api-Key (POST /api/external/v1/tickets/stream-token) y la conexión se abre con el pase en el parámetro streamToken:
// El pase lo pide tu servidor; aquí solo viaja el pase, nunca la clave.
const fuente = new EventSource(
`https://os.utilia.ai/api/external/v1/tickets/ai-suggest/${jobId}/stream?streamToken=${pase}`,
);El pase vale cinco minutos y una sola conexión, y va atado a la conexión, al trabajo o al usuario con el que se pidió. Cómo pedirlo y sus errores está en Endpoints de tickets. Los SDK oficiales lo resuelven solos a partir de la 4.2.0: el de JavaScript pide el pase por ti y el de Python manda la clave en la cabecera. Qué versión está publicada lo dice Versiones y compatibilidad.
La clave nunca va en la dirección
Una dirección queda escrita en registros de servidores, servidores intermedios e historiales, así que la API externa no acepta la clave en ella:
- Sola en la dirección, con cualquier nombre de parámetro (
apiKey,api_key,x-api-key...) o como valorutl_…de otro parámetro, la petición se rechaza con401 API_KEY_IN_URL_NOT_ALLOWEDantes de comprobar nada más. - En la dirección y también en la cabecera
X-Api-Key, de momento la petición entra por la cabecera, pero queda constancia y el diagnóstico avisa con el hallazgokey-in-url. Quítala de la dirección cuanto antes y pide que se renueve la clave, porque la que viajó en la dirección puede estar expuesta. - La forma antigua de los eventos en tiempo real, la clave en
apiKeyen peticionesGETconAccept: text/event-stream, se sigue admitiendo de momento. No la uses en integraciones nuevas: usa el pase de conexión.
Las dos tolerancias dejarán de admitirse, y entonces esas peticiones responderán también 401 API_KEY_IN_URL_NOT_ALLOWED.
Qué credencial abre cada puerta
Además del pase de conexión, UTILIA OS reconoce cuatro credenciales, y cada una solo abre su puerta. Cuál te toca según quién llama lo resuelve Elegir credencial.
| Credencial | Cómo viaja | Dónde se crea | Qué abre |
|---|---|---|---|
Clave de aplicación externa (utl_…) | Cabecera X-Api-Key | Al dar de alta la aplicación, en Ajustes › Creadas por tu empresa | La API externa (/api/external/v1/...), con los permisos de la API concedidos a la aplicación |
Clave de API de la organización (utk_…) | Authorization: Bearer | Ajustes › Claves de API, tipo «Acceso a la API» | La API que usa la aplicación (/api/...), con los permisos de su persona responsable recortados por la clave |
Clave para enviar leads (utl_…) | Cabecera X-API-Key | Ajustes › Claves de API, tipo «Enviar leads» | Solo POST /api/v1/leads |
| Token de OAuth | Authorization: Bearer | Lo autoriza una persona desde tu aplicación o tu asistente de IA | Lo que esa persona autorice, por ejemplo las herramientas MCP |
Si las mezclas, la puerta no se abre:
- A la API externa, una clave para enviar leads responde
401 API_KEY_NOT_LINKED; una clave de API de la organización,401 API_KEY_WRONG_KIND, vaya enAuthorizationo enX-Api-Key; y la clave de tu aplicación enAuthorization: Beareren lugar deX-Api-Key,401 API_KEY_WRONG_HEADER. - A la API de la aplicación (
/api/...), la clave de una aplicación externa enAuthorization: Bearerresponde401 API_KEY_WRONG_KIND, y un token de sesión ausente, mal formado o caducado,401 AUTH_TOKEN_INVALID. - La API del panel que gestiona las aplicaciones externas (
/api/integrations/apps/...) se llama con la sesión de una persona y sus permisos. No la abre la clave de una aplicación, y tampoco una clave de API de la organización: lo que tiene que ver con Integraciones queda fuera de cualquier clave (403conAPI_KEY_PERMISSION_NOT_GRANTEDoAPI_KEY_ROUTE_NOT_AVAILABLE).
Cómo se crea, se usa y se recorta la clave de la organización está en Claves de API de la organización; el token de OAuth, en OAuth: visión general.
Siguiente paso
Revisa cuántas peticiones admite tu clave y cómo se controla desde qué webs se puede llamar en Límites de uso y CORS.
Ponlo en práctica
Lo encontrarás en Creadas por tu empresa. Para abrirlo, entra con tu cuenta de UTILIA OS.