Panel de aplicaciones externas
Cómo se crea, se configura y se elimina una aplicación externa: estado, claves, permisos, avisos, usuarios, facturación y métricas, con los endpoints del panel.
Actualizado el . 38 min de lectura
Incluido en todos los planes. Ver precios
Desde la pantalla Aplicaciones externas das de alta y gobiernas cada aplicación (propia o de terceros) que usa la API externa de UTILIA OS con una clave de API o un cliente OAuth: creas la aplicación, gestionas sus credenciales, le concedes permisos, configuras sus avisos a tu servidor, consultas sus usuarios externos y vigilas cómo usa la API.
Todo esto se apoya en la API de administración de integraciones
(/api/integrations/apps/...), que se llama con la sesión de un usuario
(Authorization: Bearer <token>) y se protege con los permisos
EXTERNAL_APPS_*. No la confundas con la API externa
(/api/external/v1/...), que es la que usa la propia aplicación con su
cabecera X-Api-Key y que documentan el resto de páginas de esta
sección.
Poner en marcha una aplicación externa
Aplicaciones externas
Crear la aplicación
La clave de API y la clave de firma de los avisos se muestran una sola vez.Configuración › Ajustes
Solo los que vaya a usar. Los protegidos los concede un Super Administrador.Configuración · Opcional
Dirección HTTPS y eventos suscritos, solo si tu servidor necesita enterarse al momento.Pruebas · Opcional
Diagnóstico, prueba de lectura, avisos de ejemplo y facturas sin emitir.
Dónde está
La lista de aplicaciones está en Ajustes, Creadas por tu empresa, para cualquier organización, sea cual sea su perfil de trabajo.
Hace falta el aplicativo Integraciones en el plan y el permiso «Ver aplicaciones externas». Cada tarjeta enseña la salud de la aplicación en una línea y abre su ficha.
La ficha de una aplicación
La ficha agrupa sus pantallas en seis pestañas. Las que tienen varias
pantallas enseñan debajo una segunda fila, más discreta, con cada una;
en el teléfono, las dos filas se desplazan de lado a lado. Las
direcciones no cambian: un enlace guardado a /integrations/:id/webhooks
sigue abriendo Avisos a tu servidor, ahora dentro de
Configuración.
- Seis pestañas. La que tiene más de una pantalla abre debajo una segunda fila con ellas.
- Estado: el veredicto de la integración en una línea, con el enlace a Pruebas.
- Información y clave de API: persona responsable, prefijo de la clave, cupo por hora y último uso.
| Pestaña | Pantallas | Qué contiene |
|---|---|---|
| Resumen | Resumen | Cifras de uso (o de facturación, si la aplicación factura), el bloque Estado, la Información con la persona responsable, la Clave de API, los eventos de los que avisa y los últimos tickets. |
| Pruebas | Pruebas | Si la integración funciona y por qué no: estado, diagnóstico con quién lo arregla, recorrido, pruebas que se lanzan sin la clave, llamadas en directo y qué puede llamar. |
| Actividad | Métricas y Errores | Tráfico, latencia y errores de la API, y los errores que ha enviado la aplicación (ver Pestaña de errores). |
| Dinero | Facturación, Facturas, Cobros, Suscripciones y Autorizaciones de cobro | El interruptor de facturación, el tope por factura, el envío por correo, la cuenta de cobro y la fila de capacidades; y lo que ha facturado, cobrado y autorizado la aplicación. |
| Usuarios | Usuarios | Usuarios finales de la aplicación y su ficha de cliente en el CRM. |
| Configuración | Ajustes, Avisos a tu servidor e Inicio de sesión | Ajustes, con sus pestañas General, Permisos (los permisos de la API), Chat, Widget y Avanzado (dominios autorizados, cuota de almacenamiento y tamaño máximo de cada archivo); la dirección, los eventos, la clave de firma y el historial de los avisos; y el cliente OAuth, para que tus usuarios entren con su cuenta de UTILIA OS. |
En Dinero, Facturación está siempre; las otras cuatro pantallas solo aparecen si la aplicación factura de verdad. Si el plan de tu organización no incluye el aplicativo o la capacidad de una pantalla, no desaparece: se muestra con un candado que dice qué falta. A quien no tiene permiso para ver ese dato no se le ofrece la pantalla, y una pestaña sin ninguna pantalla visible no sale. Pruebas, la segunda pestaña, está siempre a la vista: es lo que se usa antes de que la aplicación funcione y lo primero que se abre cuando deja de funcionar.
El estado de la aplicación
El bloque Estado del Resumen es una sola línea: el veredicto de
la integración en una palabra (Funciona, Funciona en parte,
Revisar, No funciona, Sin uso, Desactivada o Sin
comprobar), la frase del servidor con el porqué y un enlace a
Pruebas, que lo cuenta entero con la acción de cada cosa. Es el mismo diagnóstico que pinta Pruebas, que lee la
aplicación con su clave en GET /external/v1/diagnostics y que resume
el MCP, así que las pantallas no se contradicen. Si la comprobación no
llega, la línea lo dice con Reintentar: nunca lo presenta como un
fallo de la integración.
La pestaña Pruebas
Dice si la integración funciona y, si no, por qué y quién lo arregla, sin emitir nada real. Todo sale del diagnóstico del servidor: la pestaña no calcula nada por su cuenta. Las pruebas las ejecuta el servidor en nombre de la aplicación, con su plan y sus permisos de la API, así que el panel nunca te pide la clave ni la guarda. Cómo se prueba una integración paso a paso está en Probar tu integración, y cada hallazgo, en Hallazgos del diagnóstico.
- Pruebas es la segunda pestaña de la ficha, justo después de Resumen.
- Instrucciones para tu asistente de IA: el texto para el asistente de quien programa, sin la clave.
- El estado: el veredicto en una palabra, desde cuándo, una sola acción y el pulso de las últimas 24 horas.
- Diagnóstico: un área por fila, lo que falla arriba, con quién lo arregla y su acción en la misma fila.
- Recorrido: los primeros pasos de la integración, marcados solos con lo que observa el servidor.
- En directo: las llamadas de la aplicación según llegan, sin recargar la página.
El estado y el pulso
Arriba, el veredicto en una palabra, la frase del servidor con el
porqué, desde cuándo y, si hace falta, una sola acción: un enlace que
lleva al sitio exacto y te devuelve a esta pestaña, o un diálogo en el
sitio (nombrar a la persona responsable, renovar la clave). Si no puedes
hacerla, en su lugar va la frase de quién puede. Al lado, el pulso de las
últimas 24 horas: una barra por hora, con lo rechazado en color. Mientras
la aplicación no ha llamado nunca, en el sitio del pulso aparece Haz tu
primera llamada, con el fragmento mínimo para hacerla con la clave en
UTILIA_API_KEY.
Diagnóstico y recorrido
Diagnóstico es una lista con un área por fila: aplicación, persona responsable, clave de API, permisos de la API, facturación (si la aplicación factura), avisos a tu servidor (si los tiene) y llamadas. Lo que falla sube; cada fila dice quién lo arregla, sin culpar a nadie, y lleva su acción. Conceder un permiso solo se ofrece a quien puede concederlo; ante llamadas rechazadas por falta de permiso, la acción es Revisar el permiso, porque unas llamadas rechazadas no prueban que la integración lo necesite.
Recorrido lista los primeros pasos según para qué sirve la aplicación y los marca solo, con la fecha de su evidencia: el progreso es el mismo para todo el equipo y en cualquier aparato. Cada paso pendiente dice cómo se hace y enlaza a la guía. Probar aquí solo aparece en el paso del receptor de avisos, el único que una prueba del panel puede marcar: la factura de prueba y la prueba activa no pasan por la clave de la aplicación.
Lanzar una prueba
Un selector con las pruebas que tienen sentido para esta aplicación y para ti, y debajo, el panel de la elegida:
- Comprobar ahora: una lectura mínima con cada permiso de lectura, como lo haría la aplicación, sin escribir nada ni devolver datos. Si la aplicación factura, valida además una factura de ejemplo sin emitirla; ese bloque solo lo ve quien puede ver facturas. Hasta 6 por minuto y persona, sin gastar el cupo de la clave.
- Comprobar una petición: pegas el método, la ruta y el cuerpo que manda tu programa y el servidor dice, sin ejecutarla, si pasaría y por qué no, con los campos que se descartarían resaltados. La ruta se autocompleta con lo que la aplicación puede llamar. El cuerpo no se guarda.
- Aviso de prueba: envía a la dirección guardada una muestra del evento que elijas, firmada igual que los avisos reales y marcada como prueba (
livemode: falseymeta.test: true). - Receptor de avisos: tres avisos de prueba que tu servidor tiene que aceptar, el bueno, y rechazar, el de firma falsa y el caducado. El resultado queda guardado para el diagnóstico y el recorrido.
- Factura sin emitir: el editor de una factura de ejemplo con Probar aquí, que la valida sin reservar número, y el PDF de muestra sin validez fiscal. Si el correo saldría al contacto de facturación del cliente del CRM, solo lo ve entero quien puede ver todos los clientes; si no, enmascarado. El borrador se guarda en esa pestaña del navegador mientras dura la sesión, sin datos personales.
La prueba abierta queda en la dirección de la página, así que un enlace pegado en el chat abre la misma prueba, y al volver de arreglar algo aterrizas en ella. Con teclado, el atajo (Cmd + Intro en Mac, Ctrl + Intro en Windows y Linux) lanza la prueba abierta desde cualquier campo de su panel.
En directo y qué puede llamar
En directo enseña las últimas 50 llamadas de la aplicación según
llegan, sin sondear: método, ruta, estado, tiempo, si usó la clave
anterior y, si falla, qué significa. Filtra entre Todas y
Rechazadas, y Pausar deja la lista quieta. Una llamada que el
programa cortó antes de recibir la respuesta sale con el estado 499.
En el ordenador, desde una llamada, Comprobar esta ruta abre
Comprobar una petición ya rellena.
Qué puede llamar agrupa las rutas de la API por recurso, con cuántas puede llamar la aplicación hoy. Al desplegar cada grupo, la ruta que no se puede llamar dice por qué: el permiso que falta, con Conceder si puedes concederlo; un aplicativo o una función que el plan no incluye, con su candado; o «Próximamente», sin venta. En el ordenador, cada ruta lleva además Comprobar esta ruta. Lo que la aplicación no tiene concedido no es un problema: va al final, plegado.
Quién puede hacer cada cosa
Todo exige el aplicativo Integraciones en el plan, también a un
Super Administrador. Lo que no puedes hacer no aparece: sin permiso
para enviar avisos no ves esas dos pruebas, y una aplicación que no
factura no enseña nada de facturación. Cada pieza llama a su ruta del
panel, bajo /api/integrations/apps/:id:
| Pieza | Ruta | Permiso |
|---|---|---|
| Estado, diagnóstico y recorrido | GET /diagnosis | EXTERNAL_APPS_VIEW |
| En directo y llamadas rechazadas | GET /diagnosis/calls, con view=recent (una a una, hasta 100) o view=rejected (agrupadas, por defecto) y window 24h o 7d | EXTERNAL_APPS_VIEW |
| Instrucciones para tu asistente de IA | GET /diagnosis/brief | EXTERNAL_APPS_VIEW |
| Comprobar una petición | POST /diagnosis/check-request, 30 por minuto | EXTERNAL_APPS_VIEW |
| Comprobar ahora | POST /diagnosis/run, 6 por minuto y persona | EXTERNAL_APPS_VIEW; la factura de ejemplo, además INVOICES_VIEW y Finanzas |
| Factura sin emitir | POST /diagnosis/invoice-validate (20 por minuto) y /diagnosis/invoice-validate/pdf (10 por minuto) | EXTERNAL_APPS_VIEW e INVOICES_VIEW, con Finanzas en el plan |
| Aviso de prueba | POST /webhook/test, con event | EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE |
| Receptor de avisos | POST /diagnosis/webhook-receiver-check | EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE |
Los dos avisos de prueba exigen además el aplicativo del evento y
comparten con la clave de la aplicación un cupo de 5 por minuto. Una
aplicación de otra organización, o eliminada, responde
404 APP_NOT_FOUND, igual que una que no existe.
En directo no sondea: escucha GET /diagnosis/stream, un canal en
tiempo real que solo avisa de que hay llamadas nuevas o de que cambió la
salud, sin datos, y el panel vuelve a pedir lo que necesita. Se abre con
un pase de corta duración (POST /auth/sse-token) en ?token=, admite 5
conexiones a la vez por persona y el servidor lo cierra a los 15
minutos; el panel vuelve a conectarse solo, pasando otra vez por tu
sesión, tu permiso y el plan. Además, cada 5 minutos comprueba que
sigues teniendo EXTERNAL_APPS_VIEW, que la organización sigue teniendo
Integraciones y que la aplicación existe; si algo falla, lo cierra.
En el teléfono y en el escritorio
- Teléfono, en la aplicación móvil o en el navegador: las pruebas son una lista y cada una se abre en una hoja inferior. Lo que necesita un editor, Comprobar una petición y Factura sin emitir, no se programa en el teléfono: se ofrece Enviar al ordenador, que abre la hoja de compartir del sistema con el enlace a esa misma prueba. Instrucciones para tu asistente de IA también se comparte en lugar de copiarse, y el detalle de una llamada de En directo se abre en una hoja inferior.
- Aplicación de escritorio: mientras En directo escucha y la ventana está en segundo plano, una notificación del sistema te avisa de la primera llamada de la aplicación y de cada fallo nuevo, otra ruta u otro código en esa sesión. Respeta tu ajuste de notificaciones de escritorio y se apaga con Pausar. El PDF de muestra se descarga con su aviso nativo y Mostrar en la carpeta.
Cuando una aplicación deja de funcionar (su salud pasa a No funciona), el aviso que recibes en la aplicación y por correo lleva a esta pestaña. Cada persona decide por dónde le llega en Mi perfil, Avisos, fila Integraciones, bloque Salud de las aplicaciones, aviso Una aplicación deja de funcionar. Qué hace cambiar la salud está en Salud de la aplicación.
La pantalla de Facturación
Aquí se decide qué puede hacer la aplicación con el dinero.
- Activar la facturación: permite a la aplicación emitir facturas y cobrar. Solo puede encenderla un Super Administrador, y al guardar se le pide un motivo de al menos veinte caracteres que queda en el registro de auditoría. Apagarla no exige nada. La pantalla y su interruptor piden Integraciones y Finanzas, no la pasarela: una organización sin Stripe activa aquí la facturación igual, emite, envía y anota el cobro por transferencia. La pasarela solo gobierna los cobros con tarjeta.
- Tope por factura: importe máximo que la aplicación puede facturar de una vez. Por encima, la API responde con un error de límite.
- Enviar las facturas por correo al emitirlas: cuando está activo, UTILIA OS
manda cada factura al usuario con la plantilla y el PDF de la organización.
Es lo que decide cuando la llamada no dice nada:
sendEmailmanda sobre él en los dos sentidos (truela envía aunque esté apagado yfalsela retiene aunque esté encendido). El justificante de cobro y los avisos de vencimiento y recordatorio dependen solo de este interruptor. - Cuenta de cobro: los cobros se procesan con la cuenta Stripe de tu organización; no hay cuenta por aplicación. La pantalla muestra su estado y enlaza a Finanzas › Ajustes › Pagos con tarjeta (Stripe).
- Fila de capacidades: factura puntual, cobro con tarjeta, suscripción y autorización de cobro, cada una con su estado real. Cuando algo no se puede, distingue las dos razones, porque se arreglan en sitios distintos: no incluida en tu plan y permiso no concedido a la aplicación.
Autenticación y permisos
Todos los endpoints de la API de administración están bajo /api/integrations/apps y exigen una sesión válida (Bearer JWT), el aplicativo Integraciones en el plan y el permiso correspondiente. Los de facturación exigen además Finanzas, y los de cobros con tarjeta, también Pagos con tarjeta (Stripe).
- EXTERNAL_APPS_VIEWpermisoobligatorio
- Ver el listado, el detalle, las estadísticas, los usuarios, las métricas, las entregas de avisos, la facturación, el catálogo de permisos de la API y el diagnóstico, y lanzar las pruebas de solo lectura de la pestaña Pruebas.
- EXTERNAL_APPS_CREATEpermisoobligatorio
- Crear una aplicación externa nueva.
- EXTERNAL_APPS_EDITpermisoobligatorio
- Editar la aplicación, renovar sus claves de API y de firma, cambiar sus permisos, configurar y probar avisos, gestionar OAuth y facturación, activarla o desactivarla.
- EXTERNAL_APPS_DELETEpermisoobligatorio
- Eliminar una aplicación externa (se puede restaurar), ver las eliminadas y restaurarlas, y eliminarla definitivamente.
Con EXTERNAL_APPS_EDIT cambias la mayoría de los permisos de la API,
pero los 17 protegidos (datos personales críticos, como las notas
internas de un contacto o el NIF de los usuarios; críticos financieros,
como cobrar, programar cobros, devolver dinero o emitir rectificativas;
y la gestión de agentes de IA del chat)
exigen además ser Super Administrador y un motivo de al menos veinte caracteres, que queda en
el registro de auditoría. El catálogo llega marcado según el plan:
solo se pueden conceder los permisos que cubre tu plan, y conceder uno
fuera de plan responde 400 SCOPE_OUT_OF_PLAN. Lo ya concedido no se
borra al bajar de plan; simplemente deja de funcionar.
Listado de aplicaciones
La página principal lista las aplicaciones externas de tu organización.
/api/integrations/appsLista las aplicaciones externas. Por defecto, las activas que no están eliminadas; con includeInactive=true, también las desactivadas, y con deleted=only, solo las eliminadas. Permiso: EXTERNAL_APPS_VIEW.
- includeInactivequery (boolean)
- Si es 'true', incluye también las aplicaciones desactivadas que no están eliminadas. Por defecto solo se devuelven las activas.
- deletedquery ('exclude' | 'only')
- 'exclude', el valor por defecto, deja fuera las eliminadas. 'only' devuelve solo las eliminadas, la vista «Eliminadas» del panel. Cualquier otro valor responde 400 VALIDATION_ERROR.
Cada elemento trae los recuentos de tickets y de usuarios externos (_count), el proyecto de Gestión de proyectos vinculado (devProject, si lo hay), oauthEnabled, que indica si la aplicación tiene un cliente OAuth activo, y deletedAt, la fecha en que se eliminó o null. En la vista de eliminadas llega también quién la eliminó (deletedBy).
Trae además la salud de cada aplicación, la misma línea que pinta su tarjeta, sin recalcular nada:
health:status(unknown,idle,ok,attention,failingopaused, los estados de la salud de la aplicación),since(desde cuándo está así, onullsi nunca se ha evaluado) ytitle, el nombre corto del estado. Una aplicación desactivada sale comopausedaunque el evaluador aún no haya pasado. En la vista de eliminadas llega anull.credentialAdvisoryCounts: cuántas recomendaciones de seguridad hay abiertas sobre sus credenciales, enrenew(renovar la clave) yupdateSdk(actualizar el SDK). El motivo de cada una solo se ve en la ficha.
Crear una aplicación externa
El alta crea en una sola operación la aplicación, su clave de API y la clave de firma de sus avisos.
En el panel, la pantalla Nueva aplicación externa empieza por ¿Para qué la usarás?, con tres opciones: Tickets y soporte, Facturación y cobros y Datos del CRM. Puedes marcar varias o ninguna, y la respuesta no se guarda en la aplicación: solo decide qué más pregunta el formulario y qué permisos te propone al terminar. Toda aplicación nace sin permisos; con usos marcados, la pantalla final te propone juntos los de todos ellos, y sin ninguno te lleva a la pestaña de permisos para que elijas tú. Los ajustes de tickets (cómo se comunica tu equipo con el usuario, la IA y el Proyecto vinculado, que es opcional) solo aparecen, y solo se envían, si marcas Tickets y soporte; si no, la aplicación nace con sus valores por defecto. Las opciones de un aplicativo que tu plan no incluye salen con un candado.
/api/integrations/appsCrea una aplicación externa con su clave de API y la clave de firma de sus avisos. Permiso: EXTERNAL_APPS_CREATE.
Define la identidad de la aplicación
nameyslugson obligatorios. Elslugsolo admite minúsculas, números y guiones (^[a-z0-9-]+$) y tiene que ser único en tu organización. Si quieres, añadedescription,logoUrlywebsiteUrl.Ajusta la conversación en los dos sentidos y la IA
Campos opcionales con valores por defecto:
allowBidirectional(por defectotrue),showAgentNames(por defectofalse),customAgentName,aiTranscriptionEnabled(por defectotrue) yaiSuggestionsEnabled(por defectotrue).Configura orígenes y límites de archivos
allowedOriginses la lista de orígenes CORS permitidos.maxFileSize(entre 1 KB y 100 MB) ymaxStorageBytes(entre 1 MB y 10 GB) limitan la subida de archivos. CondevProjectIdvinculas la aplicación a un proyecto de Gestión de proyectos.Guarda la clave de API y la clave de firma
La respuesta devuelve
apiKeyPlainTextywebhookSecretPlainText. Es la única vez que viajan en claro: cópialas y guárdalas en un sitio seguro. Después solo se mostrará el prefijo de la clave.
- namestring (máx. 100)obligatorio
- Nombre visible de la aplicación.
- slugstring (máx. 50)obligatorio
- Identificador único en tu organización. Solo minúsculas, números y guiones.
- descriptionstring
- Descripción de la aplicación.
- logoUrlurl
- URL del logotipo.
- websiteUrlurl
- URL del sitio web de la aplicación.
- allowBidirectionalboolean
- Permite la conversación en los dos sentidos. Por defecto true.
- showAgentNamesboolean
- Muestra los nombres reales de las personas de soporte. Por defecto false.
- customAgentNamestring (máx. 100)
- Nombre genérico que se muestra cuando no se enseñan los reales.
- aiTranscriptionEnabledboolean
- Habilita la transcripción por IA. Por defecto true.
- aiSuggestionsEnabledboolean
- Habilita las sugerencias por IA. Por defecto true.
- allowedOriginsstring[]
- Orígenes CORS permitidos. No se admite el comodín '*' suelto.
- devProjectIdstring | null
- Proyecto de Gestión de proyectos al que se vincula la app.
- maxFileSizeint (bytes)
- Tamaño máximo por archivo. Entre 1024 (1 KB) y 104857600 (100 MB).
- maxStorageBytesint (bytes)
- Almacenamiento total máximo. Entre 1048576 (1 MB) y 10737418240 (10 GB).
El servidor rechaza * como valor de allowedOrigins. Se admiten comodines de subdominio (por ejemplo, https://*.cliente.com), pero nunca el comodín suelto, que abriría la aplicación a peticiones desde cualquier origen.
Con dominios autorizados, la clave de la aplicación va en páginas web y
solo admite los permisos que se pueden usar desde un navegador. Toda
aplicación nace sin permisos, así que el alta con dominios pasa; después,
añadir dominios a una aplicación con otros permisos, o concederle uno de
fuera, responde 400 SCOPE_NOT_ALLOWED_WITH_ALLOWED_ORIGINS. Por qué
y cómo separar la integración en dos aplicaciones está en
Claves dentro de una página web.
Detalle y estadísticas
/api/integrations/apps/:idDetalle de la aplicación, con su clave de API (solo prefijo y datos de uso), el proyecto vinculado y el cliente OAuth si existe. Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/statsEstadísticas de la aplicación: tickets totales, abiertos y resueltos, usuarios externos, desglose por categoría y prioridad, actividad reciente y resumen de errores. Permiso: EXTERNAL_APPS_VIEW.
Ninguna lectura devuelve credenciales. De la clave de API llegan el keyPrefix, el rateLimit, el usageCount, la fecha de último uso y si está activa, nunca su huella. De la clave de firma de los avisos llega solo webhookSecretConfigured, un booleano que dice si hay clave puesta: ni el valor en claro ni su versión cifrada viajan en el listado ni en el detalle. Para volver a tener una credencial completa hay que renovarla.
El detalle trae además la persona responsable de la aplicación y, si UTILIA OS recomienda renovar alguna de sus claves, esas recomendaciones (credentialAdvisories). El motivo de cada recomendación solo lo ve quien gestiona esa clave.
Configuración de la aplicación
La pantalla Configuración › Ajustes cubre la edición general, la renovación de la clave de API y la activación o desactivación. La clave de firma se renueva en Configuración › Avisos a tu servidor.
/api/integrations/apps/:idActualiza la aplicación. Acepta los mismos campos que el alta, todos opcionales. Permiso: EXTERNAL_APPS_EDIT.
/api/integrations/apps/:id/regenerate-api-keyRenueva la clave de API y devuelve la nueva en claro una sola vez (apiKeyPlainText). Con graceDays, la anterior sigue valiendo esos días. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_APPS_MANAGE.
/api/integrations/apps/:id/api-key/retire-previousLa clave de API anterior deja de valer en el acto y se cierran las conexiones abiertas con ella. Sin transición en curso, 409 NO_TRANSITION_IN_PROGRESS. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_APPS_MANAGE.
/api/integrations/apps/:id/regenerate-webhook-secretRenueva la clave de firma de los avisos y devuelve la nueva en claro una sola vez (webhookSecret). Con graceDays, cada aviso lleva también la firma de la anterior esos días. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE.
/api/integrations/apps/:id/webhook-secret/cutoverMi servidor ya usa la nueva: desde ahora X-Utilia-Signature va firmada con la clave nueva y la anterior sigue en X-Utilia-Webhook-Signatures hasta el final de la transición. Sin transición, 409 NO_TRANSITION_IN_PROGRESS. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE.
/api/integrations/apps/:id/webhook-secret/retire-previousUTILIA OS deja de firmar con la clave anterior en el acto. Sin transición, 409 NO_TRANSITION_IN_PROGRESS. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE.
El cuerpo de las dos renovaciones admite:
- graceDays0 | 1 | 7 | 30
- Días que la clave actual sigue valiendo junto a la nueva: 1, 7 o 30, las opciones de la ficha. Con 0, el valor por defecto, deja de valer en el acto. Tiene que ser un número JSON.
- twoFactorCodestring
- Código de la aplicación de autenticación o de recuperación, si la persona tiene la verificación en dos pasos.
- twoFactorApprovalIdstring
- Alternativa al código: la confirmación aprobada desde el móvil para esta aplicación, este tipo de clave y estos mismos graceDays.
Las renovaciones no se encadenan: durante una transición, graceDays mayor que 0 responde 409 ROTATION_IN_PROGRESS, y graceDays: 0 hace que la actual y la anterior dejen de valer en el acto. La respuesta trae credentialKind, graceDays, previousValidUntil (hasta cuándo vale la anterior, o null) y rotatedAt, además de la clave nueva. Mientras la clave de API anterior sigue valiendo, las respuestas a las peticiones que la usan llevan la cabecera X-Utilia-Api-Key-Expires con esa fecha.
/api/integrations/apps/:id/activeDeja la aplicación activa o desactivada según el campo active del cuerpo (true o false). Repetir la misma petición no cambia nada. Desactivada, su clave responde 403 APP_DISABLED. Permiso: EXTERNAL_APPS_EDIT.
/api/integrations/apps/:id/toggle-activeLa forma antigua: cambia al estado contrario del que tenga. Se conserva por compatibilidad; dos peticiones seguidas la dejan como estaba, así que usa PATCH :id/active. Permiso: EXTERNAL_APPS_EDIT.
Desactivar no es eliminar: la aplicación sigue en la lista y se vuelve a activar con el mismo interruptor. Para quitarla de en medio, mira Eliminar una aplicación.
Renovar una clave, con o sin transición
Al renovar la clave de API o la clave de firma eliges cuántos días sigue valiendo la anterior: 1, 7 o 30. Con «Deja de valer en el acto» (graceDays: 0, el valor por defecto en la API), la aplicación recibirá 401 (clave de API) o fallará al comprobar la firma (avisos) hasta que ponga la nueva. Desde la ficha, la opción recomendada es 7 días.
Renovar una clave desde la ficha
La clave de API se renueva en Configuración › Ajustes de la ficha y la clave de firma, en Configuración › Avisos a tu servidor. El diálogo es el mismo para las dos:
Elige cuánto sigue valiendo la actual
1 día, 7 días (recomendado), 30 días o Deja de valer en el acto. Debajo ves hasta qué día y hora valen las dos.
Confirma que eres tú
Si tienes la verificación en dos pasos, con el código de tu aplicación de autenticación o uno de recuperación. Confirmarlo desde el móvil todavía no está en la aplicación de iPhone de la App Store.
Copia la clave nueva
Solo se muestra esta vez. El diálogo no se cierra hasta que pulsas Ya la he guardado.
Durante el periodo de transición no se puede volver a renovar la misma clave: primero hay que retirar la anterior.
- Clave de API: la tarjeta enseña los primeros caracteres de la anterior, hasta cuándo vale y su último uso. Si no se ha usado desde que la renovaste, o hace más de 24 horas, te dice que ya puedes retirarla; si se usó hace menos de una hora, que algún servidor tuyo todavía la usa. Retirar la anterior la deja sin valor en el acto, antes de su fecha.
- Clave de firma: mientras tu servidor sigue con la anterior, la tarjeta ofrece Probar la clave nueva, Mi servidor ya usa la nueva y Retirar la anterior. La prueba envía primero un aviso con una firma falsa y después otro firmado solo con la clave nueva, y dice qué contestó tu servidor a cada uno. El plegable Qué lleva cada aviso y cómo comprobarlo explica las dos cabeceras de firma; el detalle está en Firma HMAC de los avisos.
Quienes gestionan esa clave reciben un aviso cuando otra persona la renueva o retira la anterior antes de su fecha, con la consecuencia para su integración (Avisos de seguridad). Las claves de una aplicación también aparecen en Ajustes › Claves de API, pero allí solo se ven: se gestionan desde la ficha de la aplicación.
Persona responsable
Lo que la aplicación crea o cambia por la API queda a nombre de su persona responsable, que tiene que estar activa: si deja de estarlo y nadie la sustituye, todas las peticiones de la aplicación se rechazan con 403 APP_RESPONSIBLE_INACTIVE.
Lo que la aplicación puede hacer lo deciden sus permisos de la API, no los permisos de esa persona. Los de la persona solo cuentan al emitir rectificativas, al gestionar suscripciones y cobros programados (si le falta el permiso, 403 APP_RESPONSIBLE_PERMISSION_DENIED) y en las escrituras del chat. Por eso, con el permiso de la API, una aplicación lee y escribe los clientes, contactos y leads de toda la organización aunque su responsable solo vea los suyos. El detalle está en La persona responsable.
/api/integrations/apps/:id/responsible-candidatesPersonas que se pueden nombrar. A un Super Administrador le lista las personas activas de su organización (mode: any); al resto, solo a sí mismo (mode: self). Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_APPS_MANAGE.
/api/integrations/apps/:id/responsibleNombra la persona responsable. Solo un Super Administrador nombra a otra persona (si no, 403 RESPONSIBLE_SELF_ONLY); la persona tiene que estar activa en la organización (si no, 409 RESPONSIBLE_NOT_ELIGIBLE). Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_APPS_MANAGE.
En la ficha, el bloque Información del Resumen enseña quién es la persona responsable. Un Super Administrador elige a cualquiera con Elegir responsable; el resto solo puede Nombrarme responsable, y la ficha lo explica: «Solo un Super Administrador puede nombrar responsable a otra persona». La persona nombrada, la anterior y quienes gestionan la aplicación reciben un aviso.
Recomendaciones de renovar una clave
Si UTILIA OS recomienda renovar una clave de la aplicación, la ficha lo muestra en una banda con el plazo recomendado y el botón para renovarla. Quien gestiona esa clave puede descartar la recomendación con un motivo:
/api/integrations/apps/:id/credential-advisories/:advisoryId/dismissDescarta la recomendación con un motivo de 20 a 500 caracteres, que queda en el registro de actividad y se envía a las demás personas que gestionan esa clave. No se puede deshacer. Las de actualizar el SDK no se descartan (409 CREDENTIAL_ADVISORY_NOT_DISMISSIBLE).
Permisos de la API
Los permisos de la API (scopes) deciden qué puede leer y hacer la aplicación con la API externa. La pestaña Permisos de Configuración › Ajustes se pinta con el catálogo que sirve el servidor, así que los textos, los distintivos y la exigencia de Super Administrador siempre coinciden con lo que el servidor aplica.
/api/integrations/apps/scopes/catalogCatálogo de permisos de la API, con los que no cubre el plan marcados como outOfPlan, y con etiqueta, descripción, tipo y marcas de protección. Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/scopesSustituye la lista completa de permisos de la aplicación. El servidor calcula qué cambia y lo deja en el registro de auditoría. Permiso: EXTERNAL_APPS_EDIT.
Cada entrada del catálogo incluye:
- valuestringobligatorio
- Nombre técnico del permiso (por ejemplo, 'crm:contacts:read').
- labelstringobligatorio
- Etiqueta corta para la interfaz.
- descriptionstringobligatorio
- Explicación del permiso.
- category'basic' | 'write' | 'sensitive' | 'rgpd-critical' | 'financial-critical'obligatorio
- Tipo del permiso.
- rgpdSensitivebooleanobligatorio
- Si da acceso a datos personales en sentido amplio.
- rgpdCriticalbooleanobligatorio
- Si es un dato personal crítico.
- requiresSuperAdminbooleanobligatorio
- Si concederlo exige ser Super Administrador y dar un motivo.
- requiredModules / requiredCapabilitiesstring[]obligatorio
- Aplicativos y capacidades del plan que necesita para funcionar.
- outOfPlanboolean
- Si tu plan no lo cubre.
- publishableAllowedbooleanobligatorio
- Si lo puede tener una aplicación cuya clave va en páginas web. Ver Claves dentro de una página web, en Límites de uso y CORS.
- conditionalRequirementsobjeto[]obligatorio
- Lo que pide el plan para una ruta o una opción concreta del permiso, con satisfied si tu organización ya lo tiene. Vacío si no hay.
Sobre la actualización (PATCH .../scopes):
scopeslleva la lista completa que debe quedar, no solo los cambios. El servidor calculaaddedyremoved.reason(texto, hasta 500 caracteres) es obligatorio, con al menos 20, cuando se añade un permiso protegido.expectedUpdatedAt(ISO 8601) activa el bloqueo optimista: si la aplicación cambió después, la respuesta es409.- Retirar un permiso revoca los tokens OAuth activos que lo incluían. La clave de firma no se rota.
Respuestas de error específicas de este endpoint:
- 400 INVALID_SCOPEerror
- La lista scopes contiene un valor que no está en el catálogo.
- 403 SUPER_ADMIN_REQUIRED_FOR_RGPD_SCOPEerror
- Hace falta ser Super Administrador para añadir un permiso protegido.
- 400 SCOPE_OUT_OF_PLANerror
- El plan de tu organización no cubre ese permiso.
- 400 SCOPE_NOT_ALLOWED_WITH_ALLOWED_ORIGINSerror
- La clave de la aplicación está publicada en páginas web y el permiso no se puede usar con ella. notAllowedScopes dice cuáles.
- 403 RESPONSIBLE_SELF_ONLYerror
- Ampliar los permisos solo lo puede hacer la persona responsable de la aplicación o un Super Administrador. Quitarlos, cualquiera con EXTERNAL_APPS_EDIT.
- 404 EXTERNAL_APP_NOT_FOUNDerror
- La aplicación no existe en tu organización.
- 409 EXTERNAL_APP_SCOPES_CONFLICTerror
- Bloqueo optimista: expectedUpdatedAt no coincide. También 409 EXTERNAL_APP_REVOKED si la aplicación está desactivada.
- 422 REASON_REQUIRED_FOR_RGPD_SCOPEerror
- Falta el motivo (mínimo 20 caracteres) al añadir un permiso protegido.
El catálogo completo por áreas y sus reglas están en Permisos de la API.
Avisos a tu servidor
Cada aplicación puede recibir avisos (webhooks) cuando pasa algo en UTILIA OS. Desde el panel configuras la dirección de destino y los eventos, pruebas la entrega y consultas el historial.
/api/integrations/apps/:id/webhookConfigura los avisos: dirección de destino, activación y eventos suscritos. Permiso: EXTERNAL_APPS_EDIT.
- webhookUrlurl | null
- Dirección HTTPS de destino. null para borrarla.
- webhookEnabledbooleanobligatorio
- Activa o desactiva la entrega de avisos.
- webhookEventsstring[]obligatorio
- Eventos a los que se suscribe la aplicación. Solo recibe los que declare aquí.
/api/integrations/apps/:id/webhook/testEnvía un aviso de prueba a la dirección configurada, después de comprobar que no apunta a una red privada. Con secret igual a current, prueba la clave nueva; con event, envía una muestra de ese evento. Permiso: EXTERNAL_APPS_EDIT o INTEGRATIONS_WEBHOOKS_MANAGE.
El cuerpo es opcional y decide qué prueba se hace:
- Sin cuerpo, o con
{"event": "WEBHOOK_TEST"}: Probar la conexión, un aviso de prueba firmado igual que los de verdad. {"secret": "current"}: Probar la clave nueva. Primero un aviso con una firma falsa, que tu servidor debería rechazar, y después otro firmado solo con la clave vigente. La respuesta trae el resultado de los dos y un veredicto (verdict): si tu servidor acepta el de la firma falsa, el mensaje lo dice, porque significa que no está comprobando la firma.{"event": "INVOICE_CREATED"}(o cualquier otro evento del catálogo que el plan de tu organización permita suscribir): una muestra de ese evento, firmada igual que los avisos reales, conlivemode: false,meta.test: truee identificadores inventados que llevantest. Las de los eventos de facturación, de métodos de pago (PAYMENT_METHOD_ADDEDyPAYMENT_METHOD_REMOVED) y de salud (APP_HEALTH_CHANGED) tienen la forma exacta de los reales. La respuesta añade el evento, si la aplicación está suscrita a él (subscribed), si la muestra es exacta o genérica (sampleShape), el cuerpo enviado (payload) y el principio de la respuesta de tu servidor (responseSnippet). Es lo que usa la pestaña Pruebas.
Si llegan secret y event, manda secret. Ninguna prueba queda en el historial de entregas ni se reintenta, y cada una espera la respuesta de tu servidor como mucho 10 segundos (la entrega real espera 30).
La prueba responde 400 WEBHOOK_NO_URL si la aplicación no tiene dirección configurada, 400 WEBHOOK_URL_INVALID si la dirección es una IP privada o se resuelve a una red privada (protección frente a SSRF y DNS rebinding), 400 VALIDATION_ERROR si event no está en el catálogo, 403 MODULE_NOT_ENABLED si el plan no incluye el aplicativo del evento y, al probar la clave nueva, 409 WEBHOOK_SECRET_NOT_CONFIGURED si no hay clave. Con los avisos desactivados no sale nada: el resultado lo dice con success: false (al probar la clave nueva, con un 409). Si tu servidor responde con un código de error, cuenta como intento válido y el código se devuelve en el resultado.
Historial de entregas
/api/integrations/apps/:id/webhook-deliveriesHistorial paginado de entregas de avisos, con filtro por estado y por evento. Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/webhook-deliveries/:deliveryIdDetalle de una entrega, con el contenido enviado y la respuesta de tu servidor. Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/webhook-deliveries/:deliveryId/retryReintenta una entrega a mano. Responde 204 No Content. Permiso: EXTERNAL_APPS_EDIT.
Filtros admitidos en el listado:
- statusWebhookDeliveryStatus
- Filtra por estado de la entrega.
- eventstring
- Filtra por nombre de evento.
- pageint (≥1)
- Página. Por defecto 1.
- limitint (1-100)
- Tamaño de página. Por defecto 20.
El detalle de cada entrega trae event, status, statusCode, errorMessage, attemptCount, payload (el JSON enviado), responseBody, lastAttemptAt, nextRetryAt y completedAt.
Hay eventos de tickets, usuarios, archivos, errores, presupuestos, facturas, métodos de pago, autorizaciones de cobro, suscripciones, cobros, contactos, leads, clientes y chat. Cada uno tiene su descripción, su versión de contenido y su forma de envío (a todas las aplicaciones suscritas o solo a la implicada). El catálogo completo está en Avisos a tu servidor.
Usuarios externos
Lista los usuarios finales que la aplicación ha identificado.
/api/integrations/apps/:id/usersLista paginada de usuarios externos de la aplicación. Permiso: EXTERNAL_APPS_VIEW.
- pagequery (int)
- Página. Por defecto 1.
- limitquery (int)
- Tamaño de página. Por defecto 20.
Para unir un usuario de la aplicación con una ficha de cliente que ya
existía en el CRM (por ejemplo, creada por tu equipo), el panel usa
POST /api/integrations/apps/:id/users/:userId/link-client. Exige los
permisos EXTERNAL_APPS_EDIT y CLIENTS_VIEW, el CRM en el plan y
acceso a esa ficha; es la única forma de enlazar con una ficha nativa,
que la API externa nunca toca (ver Usuarios externos).
Métricas de la API
La sección Métricas resume cómo usa la aplicación la API externa. Todas las métricas admiten period con los valores 24h, 7d, 30d o 90d (por defecto, 24h).
/api/integrations/apps/:id/metricsResumen: total de peticiones, tiempo de respuesta medio, tasa de error, veces que se alcanzó el límite y variación frente al periodo anterior.
/api/integrations/apps/:id/metrics/requestsPeticiones a lo largo del periodo.
/api/integrations/apps/:id/metrics/latencyLatencia a lo largo del periodo: p50, p95, p99 y media.
/api/integrations/apps/:id/metrics/errorsErrores por código de estado HTTP y tipo de error.
/api/integrations/apps/:id/metrics/endpointsEndpoints más usados, con latencia media y tasa de error.
/api/integrations/apps/:id/metrics/webhooksEntregas de avisos correctas y fallidas, con desglose por evento.
El resumen (/metrics) devuelve:
- totalRequestsnumberobligatorio
- Total de peticiones en el periodo.
- avgResponseTimeMsnumberobligatorio
- Tiempo de respuesta medio en milisegundos.
- errorRatenumberobligatorio
- Tasa de error en porcentaje.
- rateLimitHitsnumberobligatorio
- Veces que se alcanzó el límite de peticiones.
- trendsobjectobligatorio
- Variación de requests, responseTime, errorRate y rateLimitHits frente al periodo anterior.
- periodstringobligatorio
- Periodo consultado.
OAuth
Además de la clave de API, una aplicación puede tener un cliente OAuth 2.0 para actuar en nombre de una persona que la autoriza.
/api/integrations/apps/:id/enable-oauthActiva OAuth para la aplicación. Exige al menos una redirect_uri. Permiso: EXTERNAL_APPS_EDIT.
/api/integrations/apps/:id/oauthActualiza la configuración OAuth de la aplicación. Permiso: EXTERNAL_APPS_EDIT.
/api/integrations/apps/:id/oauthDatos del cliente OAuth de la aplicación. Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/disable-oauthDesactiva OAuth en la aplicación. Permiso: EXTERNAL_APPS_EDIT.
Parámetros principales al habilitar OAuth:
- redirect_urisurl[]obligatorio
- Direcciones de redirección autorizadas del cliente OAuth.
- allowed_scopesstring
- Scopes que puede pedir el cliente OAuth.
- token_endpoint_auth_method'none' | 'client_secret_basic' | 'client_secret_post'
- Método de autenticación en el endpoint de token.
- tos_uriurl
- Dirección de las condiciones del servicio.
- policy_uriurl
- Dirección de la política de privacidad.
- contact_emailemail
- Correo de contacto del cliente OAuth.
Las marcas is_first_party (aplicación propia, que se salta la pantalla
de consentimiento) y verified (insignia de aplicación verificada en esa
pantalla) solo puede ponerlas UTILIA OS. Si las envías a true, la
respuesta es 403; a false se ignoran y no cambian nada.
El flujo de autorización, el intercambio de tokens y la pantalla de consentimiento están en Iniciar sesión con UTILIA.
Facturación de la aplicación
Si la aplicación emite facturas o cobra por la API, el panel permite consultarlo y configurarlo. Estos endpoints exigen además Finanzas en el plan, y los de cobros, también Pagos con tarjeta (Stripe).
/api/integrations/apps/:id/invoicesFacturas emitidas por la aplicación (origen EXTERNAL_APP), con filtros por usuario externo, estado y fechas. Permisos: EXTERNAL_APPS_VIEW e INVOICES_VIEW.
/api/integrations/apps/:id/invoices/statsTotales de las facturas emitidas por la aplicación. Permisos: EXTERNAL_APPS_VIEW e INVOICES_VIEW.
/api/integrations/apps/:id/invoices/:invoiceId/issuance-reviewDa por revisada una factura de la aplicación cuya emisión se interrumpió antes de terminar su cierre fiscal (issuanceDeliveryStatus: review_required). Es el botón «Dar por revisada» de la ficha de la factura. Permisos: EXTERNAL_APPS_EDIT e INVOICES_ISSUE.
La revisión solo se acepta si la factura tiene número y su PDF original
(y su código QR, si lo lleva) está generado y verificado; si no, o si la
emisión sigue en curso, responde 409 INVOICE_STATE_INVALID. No reemite
ni envía nada: deja la emisión en complete, queda en el registro de
auditoría con quien la hizo y responde {"status": "complete"}, también
si ya estaba completa. Desde ese momento la aplicación puede rectificar o
anular la factura. Ver Estado de la emisión.
/api/integrations/apps/:id/paymentsCobros (PaymentIntents) procesados por la aplicación sobre sus facturas. Permisos: EXTERNAL_APPS_VIEW y PAYMENTS_VIEW.
/api/integrations/apps/:id/payments/statsTotales de los cobros procesados por la aplicación. Permisos: EXTERNAL_APPS_VIEW y PAYMENTS_VIEW.
/api/integrations/apps/:id/billing-configConfiguración de facturación de la aplicación, con sus series por defecto (defaultStandardSeriesId y defaultSimplifiedSeriesId) y las series activas reservadas a ella (availableSeries). Permiso: EXTERNAL_APPS_VIEW.
/api/integrations/apps/:id/billing-configActiva o desactiva la facturación por API, fija el tope por factura en céntimos, decide si se envían por correo al emitirlas y fija las series por defecto de la aplicación. Activarla exige ser Super Administrador y un motivo. Permiso: EXTERNAL_APPS_EDIT.
Series por defecto de la aplicación
Una aplicación puede numerar sus facturas en una serie propia (por
ejemplo, APP-202600001), separada de la de las facturas del equipo. La
serie se crea en Ajustes › Organización, necesitas entrar con tu cuenta,
pestaña Facturas, bloque Series de facturación, con el permiso
«Editar organización», eligiendo la aplicación a la que se reserva.
Después, en la pantalla Facturación de la aplicación (o con
PATCH :id/billing-config), se fija la serie por defecto:
- defaultStandardSeriesIdstring | null
- Serie de las facturas ordinarias que la aplicación emite sin seriesCode: una serie de ordinarias, activa y reservada a esta aplicación. null vuelve a la serie general de siempre.
- defaultSimplifiedSeriesIdstring | null
- Serie de las simplificadas que la aplicación emite sin seriesCode: una serie de simplificadas, activa y reservada a esta aplicación. null vuelve a la de siempre (T-).
- availableSeriesarray
- Solo en la lectura (GET): las series activas reservadas a la aplicación, con id, code, prefix, documentType y description. Son las únicas que se pueden fijar por defecto.
Una serie que no es de la organización, de otra aplicación o del equipo
responde 400 INVOICE_SERIES_NOT_AVAILABLE; una de otro tipo,
400 INVOICE_SERIES_TYPE_MISMATCH, y una desactivada,
409 INVOICE_SERIES_INACTIVE. El cambio queda en el registro de
auditoría con el antes y el después. Fijar la serie no exige ser Super
Administrador: no amplía lo que la aplicación puede hacer, solo dónde se
numera. Mientras sea la serie por defecto de una aplicación, la serie no
se puede desactivar (409 INVOICE_SERIES_IN_USE): primero hay que
cambiar la de la aplicación. La aplicación ve sus series con
GET /external/v1/invoices/series,
pero la clave de API no puede crearlas ni cambiarlas.
El recorrido completo, de la primera factura al cobro recurrente, está en Facturar y cobrar desde tu aplicación.
Eliminar una aplicación
Hay dos formas de quitar una aplicación, las dos con el permiso «Eliminar aplicaciones externas» (EXTERNAL_APPS_DELETE) y las dos al final del menú de su ficha, en rojo y separadas del resto:
Dos formas de eliminar
Se puede deshacer
Eliminar
No se puede deshacer
Eliminar definitivamente
Estados de una aplicación externa
Activa
Su clave funciona y recibe avisos.Se llega desde Activa cuando: DELETE :id
Eliminada
No funciona ni sale en la lista; se conserva todo.Se llega desde Eliminada cuando: POST :id/permanent-delete
Eliminada definitivamente
Estado final
Ya no existe; lo que obliga la ley se queda.
Se llega desde Activa cuando: PATCH :id/active
Desactivada
Sigue en la lista; su clave responde 403 APP_DISABLED.
Otras transiciones
- Desactivada pasa a Activa: PATCH :id/active la vuelve a activar.
- Desactivada pasa a Eliminada: DELETE :id también elimina una desactivada.
- Eliminada pasa a Desactivada: POST :id/restore la devuelve, siempre desactivada.
- Activa pasa a Eliminada definitivamente: POST :id/permanent-delete no exige eliminarla antes.
Eliminar
/api/integrations/apps/:idElimina la aplicación sin borrar nada: deja de funcionar, sale de la lista y se puede restaurar. Responde la aplicación con deletedAt. Permiso: EXTERNAL_APPS_DELETE.
Al eliminarla, en el acto:
- su clave de API deja de valer y la API externa responde
401 API_KEY_INVALID, y se cierran las conexiones abiertas con ella; - deja de recibir avisos nuevos en tu servidor;
- se apagan su inicio de sesión con OAuth y su ficha del catálogo de aplicaciones, si la tenía;
- su identificador (
slug) queda reservado, porque sus tickets lo llevan en el código: dar de alta o renombrar otra aplicación con él responde409 EXTERNAL_APP_SLUG_HELD_BY_DELETED.
No se puede eliminar mientras cobra: con suscripciones activas o en pausa o con cobros programados pendientes, la respuesta es 409 EXTERNAL_APP_HAS_ACTIVE_BILLING, con details.activeSubscriptions y details.pendingScheduledCharges. Primero hay que dar de baja esas suscripciones y cancelar esos cobros. Una aplicación de otra organización o que ya estaba eliminada responde 404.
Ver las eliminadas y restaurar
En el listado del panel, la pestaña Eliminadas (solo para quien puede eliminar) enseña cada aplicación eliminada con la fecha y dos botones, Restaurar y Eliminar definitivamente. Por la API es GET /api/integrations/apps?deleted=only.
/api/integrations/apps/:id/restoreRestaura una aplicación eliminada. Vuelve desactivada (isActive: false, deletedAt: null). 404 si no está eliminada o no es de tu organización. Permiso: EXTERNAL_APPS_DELETE.
Al restaurarla vuelven su clave de API y su ficha del catálogo, pero la aplicación queda desactivada: hasta que alguien la active (PATCH :id/active con {"active": true}), su clave responde 403 APP_DISABLED. El inicio de sesión con OAuth no se enciende solo, para que no vuelvan a valer los tokens que había antes de eliminarla: si la aplicación lo usaba, vuelve a activarlo en Configuración › Inicio de sesión.
Eliminar definitivamente
Antes de borrar, el panel te enseña qué se borra, qué se conserva y qué lo impide:
/api/integrations/apps/:id/permanent-deletion-previewQué impide eliminarla definitivamente (blockers), qué se borra (willDelete) y qué se conserva (willKeep), con canDelete. Vale para una aplicación activa, desactivada o eliminada. Permiso: EXTERNAL_APPS_DELETE.
/api/integrations/apps/:id/permanent-deleteBorra la aplicación para siempre. Exige confirmName con el nombre exacto. Responde deleted: true y appId. Permiso: EXTERNAL_APPS_DELETE.
- confirmNamestring (1 a 200)obligatorio
- El nombre de la aplicación, escrito tal cual para confirmar. Se compara sin los espacios del principio y del final; si no coincide, 400 CONFIRMATION_MISMATCH.
Se borra: la aplicación, sus usuarios (y sus accesos a facturas y tarjetas cuando no tienen ficha de cliente), los mensajes que publicó en el chat (las respuestas de las personas se quedan), sus accesos a canales, el historial de avisos enviados, sus métricas de uso, su cliente OAuth con sus tokens y su clave de API.
Se conserva, sin el vínculo con la aplicación: las facturas y las rectificativas, las suscripciones, las autorizaciones de cobro, los tickets, las fichas del CRM que creó, los archivos que subió y sus series de facturación, que quedan desactivadas con su código y su numeración.
Si algo lo impide, la respuesta es 409 EXTERNAL_APP_PERMANENT_DELETE_BLOCKED y details.blockers trae cada motivo con su code, su message y, si se sabe, su count:
| code | Qué lo impide y cómo se resuelve |
|---|---|
ACTIVE_SUBSCRIPTIONS | Suscripciones activas o en pausa de la aplicación, o que facturan con una de sus series. Dalas de baja. |
PENDING_SCHEDULED_CHARGES | Cobros programados pendientes de sus facturas o suscripciones. Cancélalos. |
CATALOG_INSTALLS_IN_OTHER_ORGS | Está o ha estado en el catálogo de aplicaciones y otras organizaciones pueden tenerla instalada. Si solo quieres que deje de funcionar, elimínala sin más. |
PAYMENT_METHODS_IN_USE_WITHOUT_CLIENT | Tarjetas de usuarios de la aplicación sin ficha de cliente que usa una autorización o un cobro programado. Vincula a esos usuarios con su ficha de cliente. |
Eliminar definitivamente no tiene vuelta atrás
No pide la verificación en dos pasos: la confirmación es escribir el nombre. Antes de hacerlo, revisa la previsualización, y si solo quieres que la aplicación deje de funcionar, elimínala sin más: se conserva todo y se restaura cuando quieras.
Por MCP
La herramienta integrations hace lo mismo con apps_delete, apps_restore y apps_delete_permanently, con el permiso EXTERNAL_APPS_DELETE y el scope integrations:apps:manage. Las tres piden confirm: true, y el borrado definitivo, además, confirmName. Las eliminadas se listan con apps_list y deletedOnly: true. Detalle en la referencia MCP.
Errores frecuentes
- 401error
- Falta la sesión o no es válida (Bearer JWT).
- 403error
- Falta el permiso EXTERNAL_APPS_*, hace falta ser Super Administrador para un permiso protegido o el plan no incluye el aplicativo.
- 400 CONFIRMATION_MISMATCHerror
- Al eliminarla definitivamente, confirmName no es el nombre exacto de la aplicación.
- 404error
- La aplicación no existe en tu organización o, para casi todo salvo restaurarla y eliminarla definitivamente, está eliminada.
- 409error
- Slug repetido al crear o reservado por una aplicación eliminada, conflicto de bloqueo optimista en los permisos, aplicación desactivada, o algo que impide eliminarla (EXTERNAL_APP_HAS_ACTIVE_BILLING) o eliminarla definitivamente (EXTERNAL_APP_PERMANENT_DELETE_BLOCKED).
Todo cambio sensible (permisos, credenciales, facturación) queda en el registro de auditoría. Las métricas y el historial de entregas son el primer sitio donde mirar ante latencia, errores o avisos que no llegan.
Siguiente paso
Ponlo en práctica
Lo encontrarás en Creadas por tu empresa. Para abrirlo, entra con tu cuenta de UTILIA OS.