Referencia de métodos
Todos los servicios y métodos de los SDK de JavaScript y Python, con su nombre en cada lenguaje, la credencial que los alcanza y las diferencias entre ambos.
Actualizado el . 26 min de lectura
Incluido en todos los planes. Ver precios
Esta página es el índice de todo lo que ofrecen los dos SDK, servicio a servicio, contrastado con el código de la versión 4.6.0, que está sin publicar. Lo que llegó después de la versión que tienes instalada lleva su número de versión: comprueba en Versiones y compatibilidad si ya está publicada. Las guías de cada tema explican cuándo y cómo usar cada método; aquí está el mapa completo para encontrarlo.
Cómo leer esta referencia
- Nombres. Los servicios y métodos son los mismos en los dos lenguajes: JavaScript usa
camelCase(sdk.paymentMethods.setDefault) y Python,snake_case(sdk.payment_methods.set_default). Las tablas muestran los dos. - Asíncrono. En JavaScript todos los métodos devuelven una promesa, salvo los de
sdk.webhooks, que no hacen red. En Python, la claseUtiliaSDKusaawaityUtiliaSDKSyncofrece los mismos métodos sin él. - Entrada. En JavaScript pasas objetos literales; en Python, los modelos de entrada de Pydantic (
CreateTicketInput,IdentifyUserInput…), que se importan deutilia_sdko deutilia_sdk.models.
Qué credencial alcanza cada servicio
| Credencial | Servicios |
|---|---|
Clave de la aplicación externa (X-Api-Key, rutas /external/v1/*) | diagnostics (4.6.0), appInstallations (4.7.0, solo con la clave de la aplicación que publica una ficha), users, tickets, files, ai, aiAnalytics (4.6.0), errors, externalContacts, externalLeads, externalClients, invoices (con scheduledCharges, refunds y rectifications), paymentMethods, payments, subscriptions, paymentAuthorizations, chat, list, get y verify de budgetSignatures (4.2.0) y list y create de budgetComments (4.6.0) |
| Ninguna: no hacen red | webhooks |
| OAuth en nombre de una persona | oauth y todo sdk.mcp.* (el carril MCP no acepta la clave de la aplicación) |
Cinco servicios no son alcanzables hoy desde el SDK, y dos solo en parte
contacts, budgets, budgetTemplates, calendar y organizationSettings llaman a rutas internas del panel, que exigen la sesión de una persona que ha iniciado sesión en UTILIA OS. Ni la clave de la aplicación ni un token OAuth llegan hasta ellas: responden 401. Siguen en el paquete, pero hoy no sirven para integrar. Para contactos y clientes usa externalContacts y externalClients, y para el resto del CRM, las herramientas MCP del CRM (sdk.mcp.crm).
budgetSignatures (desde la 4.2.0) y budgetComments (desde la 4.6.0) funcionan en parte con la clave de la aplicación: sus métodos de la API externa van a /external/v1/budgets/{budgetId}/... y los demás lanzan METHOD_NOT_AVAILABLE_WITH_API_KEY antes de hacer la petición.
Diferencias entre los dos lenguajes
| Qué | JavaScript | Python |
|---|---|---|
| Pedir sugerencias o transcripción en segundo plano | requestSuggestions y requestTranscription devuelven { jobId } | Devuelven el identificador como texto |
| Transcribir | transcribe y streamTranscription devuelven { transcription } | Devuelven el texto |
| Sugerencias en tiempo real | streamSuggestions devuelve { result, abort } | stream_suggestions devuelve el resultado; stream_suggestions_handle, el objeto con abort |
| Cambios de tickets en tiempo real | streamUpdates con funciones de aviso y close(); reconecta solo, con un pase nuevo cada vez | stream_updates es un generador que recorres con async for; si se corta, vuelves a llamarlo |
| Listado de facturas | La lista viene en data | La lista viene en invoices |
| PDF de una factura | Blob | bytes |
| Conflictos de calendario abiertos | calendar.listOpenConflicts | No existe |
| Ventana emergente de OAuth | oauth.loginWithPopup | No existe |
| Comprobaciones del error | Métodos: error.isRetryable() | Propiedades: error.is_retryable |
| Capturar un error atrapado | errors.capture(error) devuelve una promesa | errors.capture_exception(), sin argumentos dentro de un except, devuelve un concurrent.futures.Future |
| Intervalo de envío de la cola | flushIntervalMs, en milisegundos | flush_interval, en segundos |
| Alias en desuso | sdk.mandates | sdk.mandates, sdk.scheduled_charges y sdk.oauth_service |
| Orden de diagnóstico | npx @utilia-os/sdk-js doctor | utilia-doctor |
| Espera máxima ante un 429 | maxRetryAfterMs, en milisegundos | max_retry_after, en segundos |
Comprobar tu integración
diagnostics
Desde la 4.6.0. Con la clave de tu aplicación y sin ningún permiso de la API: describe la propia credencial y lo que puede hacer. Nada de este servicio escribe datos de negocio; solo los dos envíos de avisos de prueba salen hacia tu servidor. Qué devuelve cada ruta está en Rutas del diagnóstico, y cómo leer cada hallazgo, en Hallazgos del diagnóstico.
| JavaScript | Python | Ruta | Qué hace |
|---|---|---|---|
me | me | GET /external/v1/me | Aplicación, organización, clave en uso, cupo por hora y scopes. |
get | get | GET /external/v1/diagnostics | Diagnóstico completo: veredicto, hallazgos con quién los arregla, qué puedes llamar y siguiente paso. |
calls | calls | GET /external/v1/diagnostics/calls | Llamadas rechazadas agrupadas, en la ventana 24h o 7d. |
checkRequest | check_request | POST /external/v1/diagnostics/check-request | Comprueba una petición sin ejecutarla: ruta, scope, plan, cuerpo y campos que se descartarían. |
run | run | POST /external/v1/diagnostics/run | Prueba activa de solo lectura de cada scope de lectura y, si facturas, de una factura de ejemplo. |
sendWebhookSample | send_webhook_sample | POST /external/v1/diagnostics/webhook-sample | Envía una muestra firmada de un evento a tu dirección de avisos. Espera hasta 40 s. |
checkWebhookReceiver | check_webhook_receiver | POST /external/v1/diagnostics/webhook-receiver-check | Comprueba que tu receptor acepta la firma buena y rechaza la falsa y la caducada. Espera hasta 100 s. |
openApi | open_api | GET /external/v1/diagnostics/openapi.json | Contrato OpenAPI con solo lo que tu clave puede llamar hoy. |
En JavaScript, checkRequest recibe { method, path, query?, body? } y calls, { window }; en Python, check_request(method, path, query=..., body=...) y calls(window="24h"). La orden doctor hace lo mismo desde la consola y sale con 0, 1 o 2: ver Integrar con un asistente de IA.
Con la clave de una aplicación con dominios autorizados, publicada en sus páginas web, me() y get() responden recortados y con credential.publishable a true, y calls, run, sendWebhookSample y checkWebhookReceiver (send_webhook_sample y check_webhook_receiver en Python) lanzan UtiliaSDKError con errorCode DIAGNOSTICS_NOT_AVAILABLE_FOR_PUBLISHABLE_KEY (constante con el mismo nombre en los dos SDK): esas pruebas se lanzan desde la pestaña Pruebas del panel. Ver Claves publicadas en una web.
Instalaciones del catálogo
appInstallations
Desde la 4.7.0, sin publicar todavía. Con la clave de la aplicación que publica una ficha en el catálogo de aplicaciones, nunca con la de una instalación. Cómo se canjea el código y qué guardar está en La instalación y el canje del código.
| JavaScript | Python | Ruta | Qué hace |
|---|---|---|---|
exchange | exchange | POST /external/v1/app-installations/exchange | Canjea el código de una instalación por su clave de API y su clave de firma, una sola vez. Solo desde un servidor. |
list | list | GET /external/v1/app-installations | Las instalaciones de tu ficha, de la más reciente a la más antigua, con su estado y, si es de pago, su suscripción. Desde la 4.8.0 filtra por subscriptionStatus (subscription_status en Python). |
get | get | GET /external/v1/app-installations/:id | Una instalación de tu ficha, con su suscripción si es de pago. |
En Python, el servicio es app_installations. La función isAccessAllowed(instalacion) (is_access_allowed en Python, 4.8.0) dice si la empresa puede usar tu aplicación: la instalación no está suspendida ni desinstalada y su suscripción lo permite. La suscripción y sus avisos están en Referencia de las instalaciones.
Usuarios, soporte e IA
users
Usuarios de tu aplicación. Guía: Usuarios externos.
| JavaScript | Python | Qué hace |
|---|---|---|
identify | identify | Crea o actualiza un usuario externo. |
list | list | Lista los usuarios de la aplicación, por páginas. |
tickets
Tickets de soporte de los usuarios de tu aplicación. Guía: Tickets de soporte. No lo confundas con sdk.mcp.tickets, que trabaja con los tickets de soporte interno de tu organización por MCP.
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Abre un ticket. |
list | list | Lista los tickets de un usuario. |
get | get | Detalle de un ticket con sus mensajes. |
getUnreadCount | get_unread_count | Mensajes sin leer del usuario. |
addMessage | add_message | Añade un mensaje. |
close | close | Cierra un ticket. |
reopen | reopen | Reabre un ticket cerrado. |
streamUpdates | stream_updates | Cambios en tiempo real. |
createStreamToken | create_stream_token | Pase de un solo uso para abrir por tu cuenta una conexión en tiempo real, sin la clave en la dirección (4.2.0). |
files
Archivos adjuntos. Guía: Archivos adjuntos.
| JavaScript | Python | Qué hace |
|---|---|---|
upload | upload | Sube un archivo. |
getUrl | get_url | Enlace temporal de descarga. |
getQuota | get_quota | Espacio usado y límites. |
ai
Sugerencias y transcripción. Guías: Sugerencias con IA y Transcripción de audio. En Python existe además stream_suggestions_handle.
| JavaScript | Python | Qué hace |
|---|---|---|
requestSuggestions | request_suggestions | Encola una petición de sugerencias. |
getSuggestionsStatus | get_suggestions_status | Estado de esa petición. |
getSuggestions | get_suggestions | Pide sugerencias y espera el resultado consultando. |
streamSuggestions | stream_suggestions | Sugerencias en tiempo real. |
requestTranscription | request_transcription | Encola una transcripción. |
getTranscriptionStatus | get_transcription_status | Estado de esa transcripción. |
transcribe | transcribe | Transcribe un audio corto en una llamada. |
streamTranscription | stream_transcription | Transcripción en tiempo real. |
trackAiAction | track_ai_action | Registra qué hizo la persona con la propuesta. |
reportError | report_error | Avisa de un fallo del cliente por la telemetría ligera, en un solo intento. Nunca lanza. |
errors
Errores de tu aplicación. Guía: Capturar los errores de tu aplicación. Todo menos report, list y stats llega en la 4.6.0.
| JavaScript | Python | Qué hace |
|---|---|---|
install | install | Captura sola lo que nadie trata y configura la cola. Nunca lanza. |
capture | capture_exception | Envía un error atrapado, en cola y en lote. Nunca lanza. |
captureMessage | capture_message | Envía un aviso sin pila. Nunca lanza. |
flush | flush | Envía ya lo pendiente y espera como mucho el tiempo indicado. |
report | report | Envía un error en una petición; lanza si falla. |
reportBatch | report_batch | Envía de 1 a 25 errores en un solo intento. |
list | list | Lista los errores enviados, con filtros. |
stats | stats | Cifras: total, pendientes, silenciados y los más frecuentes. |
get | get | Detalle de un error por su hash. |
resolve | resolve | Lo marca como resuelto. |
reopen | reopen | Lo reabre. |
silence | silence | Lo silencia de 1 a 672 horas. |
unsilence | unsilence | Le quita el silencio. |
En el SDK asíncrono de Python, install, capture_exception y capture_message no se esperan con await; el resto, sí.
aiAnalytics
Desde la 4.6.0, sdk.aiAnalytics (sdk.ai_analytics en Python): el uso de IA de tu propia aplicación, con el scope analytics:ai:read. Las dos admiten startDate y endDate en ISO 8601 (start_date y end_date). Referencia de la API: Analítica de IA.
| JavaScript | Python | Qué hace |
|---|---|---|
getOverview | get_overview | Resumen del periodo: solicitudes, tasa de éxito, coste, tokens y qué pasó con las sugerencias (GET /external/v1/ai-analytics/overview). |
getTrends | get_trends | Serie diaria del periodo (GET /external/v1/ai-analytics/trends). |
CRM por la API externa
externalContacts
Contactos para herramientas de envío de correo (Instantly, Smartlead, Apollo, Mailerlite y similares), con sincronización de cambios y registro de bajas y reactivaciones con prueba documental. En Python, sdk.external_contacts.
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Listado paginado con filtros de campaña. |
get | get | Detalle de un contacto. |
search | search | Búsqueda libre. |
byEmail | by_email | Búsqueda exacta por correo. |
sync | sync | Sincronización de cambios con cursor. |
unsubscribe | unsubscribe | Registra la baja del contacto. |
resubscribe | resubscribe | Reactiva el contacto con prueba documental. |
externalLeads
Leads para aplicaciones de prospección y sincronización con el CRM. convert es la operación más delicada: exige el scope crm:leads:convert y un motivo (reason) de al menos 20 caracteres. Después de convertir, el siguiente paso es trabajar la oportunidad en el CRM. En Python, sdk.external_leads.
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Listado paginado (por defecto, solo leads activos). |
get | get | Detalle del lead. |
search | search | Búsqueda libre. |
byEmail | by_email | Búsqueda exacta por correo. |
sync | sync | Sincronización de cambios con cursor. |
create | create | Crea un lead. |
update | update | Actualiza un lead. |
updateScore | update_score | Actualiza su puntuación. |
qualify | qualify | Lo pasa a QUALIFIED. |
disqualify | disqualify | Lo pasa a LOST. |
convert | convert | Lo convierte en contacto y, si quieres, en oportunidad. |
externalClients
Clientes para aplicaciones de facturación y sincronización. No expone IBAN ni datos financieros; el NIF solo aparece en el detalle y con el scope crm:clients:read:fiscal-data, y vincular a una matriz exige crm:clients:write:hierarchy. En Python, sdk.external_clients.
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Listado paginado (por defecto, solo ACTIVE). |
get | get | Detalle del cliente. |
search | search | Búsqueda libre. |
byTaxId | by_tax_id | Búsqueda exacta por NIF o CIF. |
bySlug | by_slug | Búsqueda exacta por identificador corto. |
sync | sync | Sincronización de cambios con cursor. |
listContacts | list_contacts | Contactos vinculados al cliente. |
create | create | Crea un cliente. |
update | update | Actualiza un cliente; con parentClientId lo vincula a una matriz o, con null, lo desvincula. |
getGroup | get_group | Grupo de empresas: papel (PARENT, SUBSIDIARY o STANDALONE), matriz y filiales. |
deactivate | deactivate | Lo pasa a INACTIVE (la única forma de retirarlo). |
reactivate | reactivate | Reactiva un cliente inactivo. |
Facturar y cobrar
invoices
Guía: Facturas.
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Emite una factura. |
validate | validate | Comprueba la factura con el mismo cuerpo que create, sin numerar ni guardar nada (4.5.0). |
validatePdf | validate_pdf | PDF de muestra sin validez fiscal, con el número «PRUEBA» (4.5.0). |
list | list | Facturas de un usuario. |
get | get | Detalle con sus líneas. |
downloadPdf | download_pdf | PDF de la factura. |
getStats | get_stats | Totales del usuario. |
listSeries | list_series | Series en las que tu aplicación puede numerar (4.4.0). |
getEuVatRates | get_eu_vat_rates | Tipos de IVA vigentes de la Unión para la ventanilla única (4.4.0, Próximamente). |
send | send | La envía por correo con su PDF. |
charge | charge | La cobra sin el usuario delante. |
markPaid | mark_paid | Registra un pago fuera de la pasarela. |
getPublicLink | get_public_link | Vigencia del enlace público. |
regeneratePublicLink | regenerate_public_link | Emite un enlace público nuevo. |
cancel | cancel | La anula. |
invoices.scheduledCharges (invoices.scheduled_charges): cobros programados.
| JavaScript | Python | Qué hace |
|---|---|---|
schedule | schedule | Programa el cobro de una factura. |
list | list | Cobros programados de una factura. |
cancel | cancel | Cancela un cobro programado. |
retryNow | retry_now | Adelanta el reintento de un cobro fallido. |
invoices.refunds: devoluciones.
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Devuelve lo cobrado, entero o en parte. |
invoices.rectifications: rectificativas desde tu aplicación (4.3.0).
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Emite la rectificativa de una devolución hecha en tu pasarela o de un contracargo que deja la venta sin efecto. El código legal lo decide UTILIA OS y va siempre a la serie de rectificativas. |
list | list | Rectificativas de una factura y lo que queda por rectificar. |
validate | validate | Comprueba la rectificativa con el mismo cuerpo que create, sin emitirla ni registrar la devolución (4.5.0). |
updateLegalMetadata (update_legal_metadata) sigue retirado: lanza siempre un error. Para devolver dinero cobrado con la pasarela de UTILIA OS y rectificar a la vez, usa refunds.create con createRectifyingInvoice.
paymentMethods
Guía: Métodos de pago. En Python, sdk.payment_methods.
| JavaScript | Python | Qué hace |
|---|---|---|
getReadiness | get_readiness | Si la organización puede cobrar con tarjeta. |
createSetupIntent | create_setup_intent | Empieza a guardar una tarjeta. |
list | list | Tarjetas activas del usuario. |
setDefault | set_default | Elige la predeterminada. |
remove | remove | Retira una tarjeta. |
payments
Guía: Cobros.
| JavaScript | Python | Qué hace |
|---|---|---|
payInvoice | pay_invoice | Cobra una factura con el usuario delante. |
getPaymentIntents | get_payment_intents | Historial de intentos de cobro. |
subscriptions
Guía: Suscripciones.
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Da de alta la cuota. |
list | list | Lista suscripciones. |
get | get | Detalle. |
update | update | Cambia condiciones. |
pause | pause | La pausa. |
resume | resume | La reanuda. |
cancel | cancel | La da de baja. |
reactivate | reactivate | Reactiva una dada de baja. |
generateNow | generate_now | Emite ya la factura del periodo. |
getUpcomingCharge | get_upcoming_charge | Próximo cobro y si el cobro automático está listo. |
listInvoices | list_invoices | Facturas generadas. |
listLogs | list_logs | Historial del generador. |
retryCharge | retry_charge | Reintenta el cobro de una de sus facturas. |
paymentAuthorizations
Guía: Autorizaciones de cobro. En Python, sdk.payment_authorizations. sdk.mandates es su alias en desuso.
| JavaScript | Python | Qué hace |
|---|---|---|
getConsentText | get_consent_text | Texto de consentimiento vigente. |
create | create | Registra la aceptación. |
list | list | Lista autorizaciones. |
get | get | Detalle de una. |
revoke | revoke | La retira. |
webhooks
Verificación de los avisos que UTILIA OS envía a tu servidor, de cualquier familia de eventos. Usa siempre el cuerpo tal cual llega, sin volver a convertirlo: reordenar las claves rompe la firma. El margen contra reenvíos se cambia con toleranceSeconds (tolerance_seconds). Más en Firma HMAC de los webhooks.
| JavaScript | Python | Qué hace |
|---|---|---|
verify | verify | Comprueba la firma y la ventana de 300 s contra reenvíos; devuelve el sobre. Desde la 4.2.0 lee también X-Utilia-Webhook-Signatures y acepta varias claves, con fecha de caducidad (validUntil, valid_until). |
parse | parse | Lo mismo, devolviendo el evento ya tipado. |
signTestPayload | sign_test_payload | Firma un aviso en local, igual que UTILIA OS, para probar tu receptor en tus pruebas unitarias. Lo que firma lo acepta verify con la misma clave (4.5.0). |
verifyInstallation | verify_installation y verify_installation_async | Verifica el aviso de una instalación del catálogo: lee X-Utilia-Installation-Id, pide la clave de firma de esa instalación a tu función y comprueba que el sobre firmado es de la misma instalación. Lanza WEBHOOK_INSTALLATION_MISSING, WEBHOOK_INSTALLATION_UNKNOWN o WEBHOOK_INSTALLATION_MISMATCH (4.7.0). |
ALL_WEBHOOK_EVENTS y WEBHOOK_EVENTS_BY_DOMAIN (4.6.0) traen los nombres de todos los avisos, comprobados contra el catálogo del servidor, e isWebhookEventName (is_webhook_event_name) dice si un texto es uno de ellos. Los eventos del chat llegan con su nombre en mayúsculas (CHAT_MESSAGE_CREATED), nunca con puntos.
Chat
chat
La aplicación participa en los canales de chat con identidad propia: publica mensajes y lee canales, miembros e historial según los canales que tenga concedidos. Además tiene chat.agents (agentes gestionados: install, list, update, pause, resume y remove) y chat.webhooks.verify, alias de sdk.webhooks.verify. Guía: SDK del chat.
| JavaScript | Python | Qué hace |
|---|---|---|
sendMessage | send_message | Publica un mensaje como aplicación. |
listChannels | list_channels | Canales a los que la aplicación tiene acceso. |
getChannel | get_channel | Detalle de un canal. |
listMembers | list_members | Miembros de un canal. |
listMessages | list_messages | Historial visible de un canal. |
getMessage | get_message | Un mensaje. |
createChannel | create_channel | Crea un canal. |
updateChannel | update_channel | Cambia un canal. |
archiveChannel | archive_channel | Archiva un canal. |
addMember | add_member | Añade un miembro. |
removeMember | remove_member | Quita un miembro. |
Servicios no alcanzables hoy
Estos servicios existen en los dos SDK con los mismos métodos, pero sus rutas exigen una sesión de usuario del panel (ver el aviso de arriba).
contacts
| JavaScript | Python | Qué hace |
|---|---|---|
create | create | Crea un contacto. |
get | get | Detalle. |
list | list | Lista contactos. |
update | update | Actualiza. |
delete | delete | Elimina. |
listByClient | list_by_client | Contactos de un cliente. |
searchByEmail | search_by_email | Busca por correo. |
changeStatus | change_status | Cambia el estado. |
setPrimary | set_primary | Lo marca como principal. |
linkClient | link_client | Lo vincula a un cliente. |
unlinkClient | unlink_client | Lo desvincula. |
updateClientLink | update_client_link | Cambia el vínculo. |
setPrimaryClient | set_primary_client | Marca el cliente principal del contacto. |
listClients | list_clients | Clientes vinculados. |
budgets
Presupuestos del CRM. Métodos, en JavaScript (en Python, los mismos en snake_case):
- Altas, versiones y consultas:
list,get,create,update,delete,deletePermanent,duplicate,createVersion,getHistory,listByClient,listByProjectylistByOpportunity. - Partidas y secciones:
addItem,updateItem,removeItem,reorderItems,listSections,addSection,updateSection,removeSectionyreorderSections. - Flujo y conversiones:
send,approve,reject,cancel,changeStatus,extendValidity,convertToProjectyconvertToInvoice. - PDF, adjuntos e imágenes:
generatePdf,viewPdf,getPdfUrl,getAttachments,uploadAttachment,deleteAttachment,uploadEditorImage,listImages,getImage,uploadImage,uploadImageToSection,createImageFromFile,scanLegacyImages,migrateLegacyImages,updateImagePosition,updateImageCrop,updateImageDimensions,updateImageCaption,replaceImageFile,deleteImageyreorderImages. - Códigos, estadísticas, lotes y exportación:
getNextCode,checkCode,getStats,bulkyexport. - Generación con IA:
generateItemsWithAi,streamGenerateItemsStatus,generateCompleteWithAiygenerateSectionsWithAi.
budgetTemplates
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Lista plantillas. |
get | get | Detalle. |
create | create | Crea una plantilla. |
update | update | La actualiza. |
delete | delete | La elimina. |
createFromBudget | create_from_budget | Crea una plantilla a partir de un presupuesto. |
applyTemplate | apply_template | Aplica una plantilla a un presupuesto. |
budgetComments
Desde la 4.6.0, con la clave de la aplicación, list (scope crm:budgets:comments:read) y create (scope crm:budgets:comments:write) van a /external/v1/budgets/{budgetId}/comments y funcionan, siempre con visibilidad CLIENT: por la API nunca se leen ni se escriben notas internas del equipo. get, bulkCreate y getTimeline se apoyan en esos dos. update y remove lanzan METHOD_NOT_AVAILABLE_WITH_API_KEY sin hacer la petición. Hasta la 4.5, todo iba a rutas del panel y respondía 401. Referencia de la API: Comentarios de presupuesto.
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Comentarios de un presupuesto. Con clave de API, solo los visibles para el cliente. |
get | get | Un comentario. Con clave de API lo busca en el listado y, si no está, lanza NOT_FOUND. |
create | create | Crea un comentario (INTERNAL o CLIENT; con clave de API, solo CLIENT). |
update | update | Lo edita. No disponible con clave de API. |
remove | remove | Lo elimina. No disponible con clave de API. |
bulkCreate | bulk_create | Crea varios a la vez. |
getTimeline | get_timeline | Cronología de comentarios. |
budgetSignatures
Desde la 4.2.0, con la clave de la aplicación, list, get y verify van a /external/v1/budgets/{budgetId}/signatures (scopes crm:budgets:signatures:read y crm:budgets:signatures:verify) y funcionan. Los demás lanzan METHOD_NOT_AVAILABLE_WITH_API_KEY sin hacer la petición. Con OAuth, todos van a las rutas del panel, que no admiten el token: las firmas se consultan entonces por MCP con la herramienta crm_budget_files (list_signers, get_signer, verify_signature...), que sustituye a la retirada crm_budget_signers. Cada evento del registro de auditoría trae la IP enmascarada (ipAddressMasked) y el navegador (deviceLabel); ipAddress y userAgent quedan en desuso y ya no llegan.
Firma electrónica de presupuestos: list, get, verify, downloadCertificate, getCertificateUrl, forceSendSignature, generateSigningLink, listSigningLinks, revokeSigningLink, getAuditTrail, listRequiredSigners, addRequiredSigner, updateRequiredSigner, removeRequiredSigner, extendValidity, revokeViewToken y regenerateSigningToken (en Python, en snake_case).
calendar
| JavaScript | Python | Qué hace |
|---|---|---|
getAvailability | get_availability | Huecos disponibles. |
checkAvailability | check_availability | Si un horario está libre. |
listOpenConflicts | — | Conflictos de horario abiertos (solo JavaScript). |
organizationSettings
| JavaScript | Python | Qué hace |
|---|---|---|
getPublicSettings | get_public_settings | Datos públicos de la organización: identidad, marca y valores de facturación. |
OAuth
Disponible solo si creas el cliente con oauth; si no, acceder a sdk.oauth lanza un error de validación. Guía: OAuth con el SDK.
| JavaScript | Python | Qué hace |
|---|---|---|
getAuthorizationUrl | get_authorization_url | Dirección de autorización con PKCE automático. |
getLoginUrl | get_login_url | Lo mismo, devolviendo verificador y state para gestionarlos tú. |
handleCallback | handle_callback | Canjea el código por tokens. |
loginWithPopup | — | Autorización en ventana emergente (solo navegador). |
refreshToken | refresh_token | Renueva el token de acceso. |
getAccessToken | get_access_token | Token vigente, renovado si hacía falta. |
isAuthenticated | is_authenticated | Si hay sesión utilizable. |
logout | logout | Revoca y borra la sesión. |
getUserInfo | get_user_info | Datos de la persona. |
revokeToken | revoke_token | Revoca un token de la sesión. |
revoke | revoke | Revoca un token cualquiera. |
introspect | introspect | Estado de un token (solo aplicaciones confidenciales, con clientSecret). |
getAuthorizedApps | get_authorized_apps | Aplicaciones autorizadas por la persona. |
revokeApp | revoke_app | Retira la autorización de una aplicación. |
MCP
sdk.mcp agrupa servicios tipados sobre las herramientas MCP de UTILIA OS (POST /api/mcp/{servidor}). Actúan en nombre de una persona, con su sesión OAuth, y cada uno apunta al servidor que le corresponde. Los errores de la herramienta llegan como UtiliaSDKError con el mensaje del servidor; por esta vía no viaja el errorCode de plan (ver Errores de plan).
| JavaScript | Python | Qué cubre |
|---|---|---|
mcp.crm | mcp.crm | Clientes, contactos y leads del CRM (crm_clients, crm_contacts, crm_leads): ficha, imagen, lotes de hasta 50, duplicados y fusión. La fusión exige scopes propios (crm:clients:merge, crm:contacts:merge, crm:leads:merge) que ningún conjunto incluye, ni crm:full; y su vista previa es la misma operación sin confirmar: mira dryRun antes de dar nada por fusionado. |
mcp.opportunities | mcp.opportunities | Analítica de oportunidades. Guía: Oportunidades. |
mcp.marketing | mcp.marketing | Marketing: informes, campañas, listas, entregabilidad, medición y envío. Guía: Marketing. |
mcp.attendance | mcp.attendance | Calendario laboral (holidays: getScope, setScope, import y list). Elegir el ámbito y cargar el año exigen hr:attendance:manage. |
mcp.fiscalCapture | mcp.fiscal_capture | Rectificativas recibidas: consulta, guardado y lotes de hasta 25. En «Próximamente», como Impuestos: hoy no está disponible para tu organización. |
mcp.tickets | mcp.tickets | Tickets de soporte interno: lectura y creación. Quien lo crea es siempre la persona autenticada. |
mcp.search | mcp.search | Buscador global: global y types. |
mcp.notifications | mcp.notifications | Avisos de la persona: list, get, unreadCount, markRead, markAllRead, dismiss, dismissAll, getPreferences y updatePreferences. |
mcp.integrations | mcp.integrations | Aplicaciones de desarrollador: OAuth, avisos a tu servidor, métricas y facturación. |
mcp.apiCredentials | mcp.api_credentials | Claves de API de la organización (utk_, desde la 4.5.0): orgKeysList, orgKeysGet, orgKeysUsage, orgKeysCatalog, orgKeysCandidates, orgKeysCreate, orgKeysUpdate, orgKeysRotate, orgKeysEndTransition y orgKeysRevoke (en Python, org_keys_list, org_keys_get… con el nombre de su operación). Crear, renovar y ampliar una clave lanzan APPROVAL_REQUIRED la primera vez y se repiten con twoFactorApprovalId (two_factor_approval_id) cuando la persona lo aprueba en el móvil. También credenciales PERSONAL y EXTERNAL_APP: list, get, getUsage, create, rotate, revoke y scopesCatalog. |
mcp.orgIntegrationsSettings | mcp.org_integrations_settings | Claves de API y formularios de captación. |
mcp.integrationsOverview | mcp.integrations_overview | Vista de conjunto de las integraciones, de solo lectura. |
mcp.onboarding | mcp.onboarding | Cómo va la preparación de la persona autenticada: dónde se quedó y qué le falta. Es progreso personal, no de la empresa. |
mcp.integrationsLegacy | mcp.integrations_legacy | Alias en desuso de orgIntegrationsSettings. |
El catálogo completo de herramientas y servidores está en Referencia de herramientas MCP.
mcp.opportunities
| JavaScript | Python | Qué hace |
|---|---|---|
assignmentCounts | assignment_counts | Contadores «Mías», «Equipo» y «Todas». |
recommendations | recommendations | Hasta cinco acciones recomendadas. |
analyticsStaleDetection | analytics_stale_detection | Estancadas y vencidas, por etapa. |
analyticsLossReasons | analytics_loss_reasons | Diez motivos de pérdida más frecuentes y la fila OTHER. |
analyticsTopContributors | analytics_top_contributors | Ranking por valor ganado (permiso «Ver el embudo del equipo»). |
getPipelineStats | get_pipeline_stats | Reparto por etapa. |
getForecast | get_forecast | Previsión a N meses (permiso «Ver información financiera de oportunidades»). |
getTimeline | get_timeline | Actividad de una oportunidad. |
listStages | list_stages | Etapas del embudo por defecto, en orden. |
mcp.marketing
Cubre ocho herramientas enteras: reports (marketing_reports, 12 operaciones), campaigns (marketing_campaigns, 41), lists (marketing_lists, 25), deliverability (marketing_deliverability, 14), trackingSettings (marketing_tracking_settings, 3), trackingDomains (email_tracking_domains, 8), bounceSettings (marketing_bounce_settings, 5) y sendingRoutes (email_sending_routes, 12). En Python, los sub-espacios van en snake_case (tracking_settings, sending_routes…). Exigen el aplicativo Marketing, salvo sendingRoutes, que exige la capacidad «Servidor de envío propio».
Informes (reports). Todas son de solo lectura.
| JavaScript | Python | Qué hace |
|---|---|---|
campaignStats | campaign_stats | Métricas de una campaña, con las tasas ya calculadas (EMAIL_MARKETING_VIEW). |
engagementOverview | engagement_overview | Agregados del periodo: campañas, aceptados, aperturas, clics, rebotes y bajas (EMAIL_MARKETING_VIEW). |
clickThrough | click_through | Clics por dirección de destino (EMAIL_MARKETING_VIEW). |
topCampaigns | top_campaigns | Ranking del periodo, sin reenvíos ni variantes A/B (EMAIL_MARKETING_ANALYTICS). |
engagementHeatmap | engagement_heatmap | Interacción por hora o por día de la semana (EMAIL_MARKETING_ANALYTICS). |
engagementTrends | engagement_trends | Serie por día, semana o mes (EMAIL_MARKETING_ANALYTICS). |
campaignAttribution | campaign_attribution | Negocio originado por una campaña, con desglose opcional (EMAIL_MARKETING_ANALYTICS y capacidad «Negocio por campaña»). |
attributionSummary | attribution_summary | El mismo agregado para un periodo (ídem). |
entityOrigin | entity_origin | De qué campaña vino una oportunidad o un cliente (EMAIL_MARKETING_VIEW y el permiso de la ficha). |
complaints | complaints | Quejas por correo no deseado; la tasa llega como null, nunca 0, si no se puede medir (EMAIL_MARKETING_ANALYTICS). |
linkHeatmap | link_heatmap | Qué enlace concreto se pulsa (EMAIL_MARKETING_VIEW y capacidad «Analítica avanzada de Marketing»). |
audienceTech | audience_tech | Aparato, programa de correo o país; por defecto sobre los clics (ídem). |
Cifras que se leen mal si no sabes qué cuentan
delivered vale null cuando la organización no detecta los correos devueltos: sin eso sería el mismo número que accepted. clickToOpenRate se divide entre las aperturas únicas, así que puede superar el 100 %. Los importes de la atribución no viajan por este servidor: llegan los recuentos y el bloque de dinero aparece en excludedBlocks con reason: 'missing_scope'; no lo presentes como un cero. Y las facturas emitidas con invoices.create no tienen vínculo comercial, así que quedan fuera del negocio originado por cualquier campaña. Las definiciones están en Métricas de Marketing.
Campañas (campaigns). Las 41 operaciones de la herramienta: el ciclo de vida de una campaña (list, get, create, update, editContent, delete, duplicate, send, getSendStatus, schedule, pause, resume, cancel, testSend, preview, previewHtml…), sus destinatarios, el comportamiento de la audiencia y los segundos intentos. Algunas a destacar:
| JavaScript | Python | Qué hace |
|---|---|---|
engagementBreakdown | engagement_breakdown | Reparto de la audiencia en los siete grupos (EMAIL_MARKETING_VIEW). |
resendPreview | resend_preview | Qué supondría volver a escribir a un grupo; no crea nada (EMAIL_MARKETING_VIEW y capacidad «Analítica avanzada de Marketing»). |
createResend | create_resend | Crea en borrador la campaña del segundo intento (EMAIL_MARKETING_CREATE y la capacidad). |
listResends | list_resends | Segundos intentos con su resultado (EMAIL_MARKETING_VIEW). |
preflight | preflight | Comprobación previa al envío, sin enviar. |
recipientTimeline | recipient_timeline | Historial de un correo concreto. |
listReplies | list_replies | Quién ha contestado. |
Los siete grupos de engagementBreakdown no son porciones de una tarta: opened ya incluye a clicked y a opened_not_clicked. En un segundo intento no se vuelve a escribir a quien se quejó, el asunto tiene que ser distinto, hay como mucho dos por campaña y los contadores de la original no se tocan. listRecipients devuelve aparato, programa de correo y país solo con el permiso EMAIL_MARKETING_VIEW_RECIPIENT_DETAIL y el scope marketing:recipients:detail:view; sin ellos responde igual, sin esos campos y con recipientDetailIncluded: false.
Listas (lists). Las 25 operaciones de la herramienta, entre ellas:
| JavaScript | Python | Qué hace |
|---|---|---|
listSubscribers | list_subscribers | Suscriptores con su interés y si están apartados (EMAIL_MARKETING_VIEW). |
engagementSummary | engagement_summary | Recuento por banda de interés (EMAIL_MARKETING_VIEW y capacidad). |
setAsideInactive | set_aside_inactive | Aparta a los inactivos; por defecto, solo vista previa (EMAIL_MARKETING_LISTS_MANAGE y capacidad). |
reactivateSubscriber | reactivate_subscriber | Vuelve a incluir a un apartado (ídem). |
Apartar no es dar de baja: no cambia la suscripción ni su consentimiento; la persona deja de recibir campañas y se la reincorpora en un clic. El servidor exige 90 días sin abrir ni pulsar y al menos dos correos recibidos.
Entregabilidad (deliverability). Las 14 operaciones de la herramienta, entre ellas:
| JavaScript | Python | Qué hace |
|---|---|---|
getComplaintPolicy | get_complaint_policy | Umbral propio de quejas, pausa automática, techo de la plataforma y estado del bloqueo. |
setComplaintPolicy | set_complaint_policy | Solo thresholdBps (de 10 a 30) y autoPauseEnabled (EMAIL_MARKETING_DELIVERABILITY_MANAGE). |
Solo puedes ser más estricto que la plataforma: el techo del 0,3 % y el bloqueo del servidor compartido no se configuran desde aquí.
Medición del origen (trackingSettings).
| JavaScript | Python | Qué hace |
|---|---|---|
get | get | Configuración vigente, con capabilityActive y canManage ya resueltos (EMAIL_MARKETING_VIEW). |
update | update | Cambia utmEnabled, utmTemplate, recipientTokenEnabled y recipientTokenTtlDays (EMAIL_MARKETING_TRACKING_MANAGE). |
previewLink | preview_link | Cómo quedaría un enlace; no firma ni emite nada real (EMAIL_MARKETING_VIEW). |
Encender recipientTokenEnabled es una decisión de protección de datos: exige la capacidad «Negocio por campaña» y conviene ampliar antes la información que recibe quien rellena el formulario. Ver Medición del origen de tus campañas.
Dominio propio de los enlaces (trackingDomains). Hace que los enlaces de las campañas vuelvan por un subdominio de la organización.
| JavaScript | Python | Qué hace |
|---|---|---|
list | list | Dominios de medición; como mucho uno vivo. |
get | get | Estado, caducidad del certificado y hasta cuándo se atiende. |
getSetupInstructions | get_setup_instructions | El registro CNAME que hay que publicar. |
create | create | Da de alta el subdominio; todavía no mide. |
verify | verify | Comprueba el CNAME en el DNS real. |
setEmission | set_emission | Enciende o apaga la medición por ese dominio. |
retryCertificate | retry_certificate | Vuelve a pedir el certificado. |
retire | retire | Programa el fin del servicio; no borra nada. |
Ninguna operación borra nada, porque un correo ya enviado lleva el dominio escrito: retire devuelve en serveUntil hasta cuándo se siguen atendiendo sus enlaces. Ver Enlaces con tu propio dominio.
Reintentos y errores
Desde la 4.6.0, el SDK solo repite lo que no puede duplicar nada:
- Se reintentan las lecturas,
PUT,PATCHyDELETE, losPOSTcon clave de idempotencia (el campoidempotencyKeyo, en JavaScript, la cabeceraIdempotency-Key) y losPOSTque solo consultan:invoices.validate,users.identify, el pase de conexión,diagnostics.checkRequest,diagnostics.runy el carril MCP. - Se intentan una sola vez las altas sin clave de idempotencia (tickets, mensajes, clientes, leads, conversión de un lead, canales, agentes, archivos e IA) y las escrituras que mueven dinero o emiten un documento, como
invoices.createeinvoices.cancel. Si fallan por la red, comprueba si se hicieron antes de repetirlas. - Ante un 429, o un 503 que la traiga, espera lo que pide
Retry-After.X-Utilia-Quota-Resetsolo cuenta en el 429 del cupo por hora agotado que no traeRetry-After; los 5xx y los demás 429 sinRetry-Afterse repiten con la espera creciente de siempre. Si la espera pasa demaxRetryAfterMs(60 000 ms por defecto;max_retry_after, 60 s en Python), no espera ni reintenta: lanza el error conretryAfterMs(retry_after, en segundos) para que decidas tú.
Un 409 llega como ErrorCode.CONFLICT; hasta la 4.5 llegaba como UNKNOWN. El error trae además, cuando el servidor los manda, fixedBy (quién lo arregla: developer, organization o utilia), docsUrl (el apartado de la documentación que lo explica) y requiredScopes (los permisos de la API que faltan, en el 403 INSUFFICIENT_SCOPE). Cada código está explicado en Errores, identificador de petición y reintentos.
Con onIgnoredFields (on_ignored_fields) recibes, una vez por método, ruta y campos, los campos que el servidor descartó sin error en una escritura (cabecera X-Utilia-Ignored-Fields): suele ser un nombre mal escrito, y ese dato no se ha guardado. Sin la opción, el SDK deja un aviso en la consola o en el registro utilia_sdk.
Tipos y más detalle
Todos los métodos lanzan UtiliaSDKError cuando algo falla. Qué trae y cómo tratarlo, incluidos los códigos de las credenciales y la confirmación en el móvil de las operaciones MCP (getApprovalChallenge), está en Gestionar errores. Los dos paquetes exportan además los tipos o modelos de todos los servicios y la constante SDK_LIMITS: ver Tipos y modelos y Límites y validaciones. El historial de cambios está en Versiones y compatibilidad.