Configurar el cliente
Opciones del cliente del SDK en JavaScript y Python, cabeceras automáticas, reintentos con espera creciente, depuración y autenticación con clave u OAuth.
Actualizado el . 5 min de lectura
Incluido en todos los planes. Ver precios
El cliente del SDK se crea una vez con la dirección base de la API y una credencial, y a partir de ahí añade solo las cabeceras, reintenta lo que se puede reintentar y convierte cualquier fallo en un UtiliaSDKError. Esta página recoge todas sus opciones, contrastadas con el código de la versión 4.1.0 de los dos paquetes.
Opciones
Las opciones son las mismas en los dos lenguajes; cambian el estilo del nombre y la unidad del tiempo de espera.
| JavaScript | Python | Por defecto | Para qué sirve |
|---|---|---|---|
baseURL | base_url | Obligatoria | Dirección base de la API: https://os.utilia.ai/api. |
apiKey | api_key | Sin valor | Clave de la aplicación externa (utl_...) para integraciones de servidor a servidor. |
oauth | oauth | Sin valor | Configuración OAuth 2.1 con PKCE, alternativa a la clave. |
timeout | timeout | 30000 ms / 30.0 s | Tiempo máximo de espera de cada petición. En JavaScript va en milisegundos; en Python, en segundos. |
retryAttempts | retry_attempts | 3 | Número total de intentos de cada petición, incluido el primero. 1 desactiva los reintentos. |
debug | debug | false / False | Activa las trazas de depuración. |
No hay más opciones: el cliente no tiene identificación automática de usuarios ni funciones de aviso propias. Si tu aplicación trabaja con usuarios externos, identifícalos de forma explícita con identify antes de operar sobre ellos.
En Python, base_url y api_key pueden ir por posición o por nombre; el resto, solo por nombre.
import { UtiliaSDK } from '@utilia-os/sdk-js';
const sdk = new UtiliaSDK({
baseURL: 'https://os.utilia.ai/api',
apiKey: process.env.UTILIA_API_KEY!,
timeout: 15000,
retryAttempts: 5,
debug: true,
});Autenticación: clave u OAuth, nunca las dos
Tienes que dar una credencial y solo una. Si no das ninguna, o das las dos, el cliente no se crea: en JavaScript lanza un UtiliaSDKError con código VALIDATION_ERROR y en Python, un ValueError.
| Clave de acceso | OAuth 2.1 con PKCE | |
|---|---|---|
| Para qué | Integraciones de servidor a servidor | Aplicaciones que actúan en nombre de una persona |
| Qué configuras | Un valor: la clave utl_... | Identificador de cliente, dirección de vuelta y scopes |
| Permisos | Los scopes concedidos a la aplicación externa | Solo los scopes que la persona aceptó |
| Cabecera que envía el SDK | X-Api-Key | Authorization: Bearer <token de acceso> |
| Caducidad | No caduca | El token de acceso caduca y el SDK lo renueva solo |
Con OAuth, la configuración lleva clientId y redirectUri (obligatorios), y opcionalmente clientSecret (solo aplicaciones confidenciales), scopes (por defecto openid, profile y email) y tokenStorage para guardar los tokens donde quieras. En Python los mismos campos van en snake_case y puedes pasarlos como diccionario o como instancia de OAuthConfig.
const sdk = new UtiliaSDK({
baseURL: 'https://os.utilia.ai/api',
oauth: {
clientId: 'client_xxxxxxxxxx',
redirectUri: 'http://localhost:3000/callback',
scopes: ['openid', 'profile', 'email'],
},
});El flujo completo (dirección de autorización, vuelta, almacenamiento y renovación de tokens) está en OAuth con el SDK.
Cabeceras automáticas
| Cabecera | Valor | Cuándo |
|---|---|---|
Content-Type | application/json | Siempre, salvo en las subidas de archivos, que van como multipart/form-data. |
X-Api-Key | Tu clave | Solo con autenticación por clave. |
Authorization | Bearer <token de acceso> | Solo con OAuth. |
x-request-id | Un UUID nuevo por petición | Siempre. |
El x-request-id sirve para relacionar un fallo de tu lado con los registros del servidor. Cuando la petición falla, el error lo trae en requestId (JavaScript) o request_id (Python): en Python es el valor que devuelve el servidor en su respuesta; en JavaScript, ese mismo o, si el servidor no lo devuelve, el que generó el SDK.
Reintentos
El SDK reintenta solo lo que tiene sentido repetir:
- Errores de red: sin respuesta del servidor (tiempo agotado, conexión rechazada o cortada).
- HTTP 429: límite de peticiones superado. También un 403 cuyo mensaje dice «rate limit», que el SDK trata igual.
- HTTP 5xx: errores del servidor.
No reintenta los 400 y 422 (datos no válidos), 401 (credencial no válida), 403 (acceso denegado o bloqueo por plan) ni 404 (no encontrado): repetirlos daría el mismo resultado.
Entre un intento y el siguiente espera cada vez el doble (0,5 s, 1 s, 2 s, 4 s…). Con el valor por defecto, 3, hace un intento y hasta dos reintentos:
Reintentos con la configuración por defecto
0 s
Intento 1
Falla por la red, con un 429 o con un 5xx.Espera de 0,5 s hasta el siguiente.
0,5 s
Intento 2
Vuelve a fallar por lo mismo.Espera de 1 s hasta el siguiente.
1,5 s
Intento 3
Si también falla, el SDK lanza el UtiliaSDKError del último intento.
Algunas escrituras no se repiten nunca
Las operaciones que no se pueden repetir sin riesgo de duplicar algo hacen un solo intento aunque configures más: emitir o anular una factura, enviarla, cobrarla sin el usuario delante, registrar un pago o una devolución, programar o reintentar un cobro, registrar una autorización de cobro y algunas operaciones de suscripciones. Si fallan por la red, comprueba el estado antes de volver a lanzarlas. El cobro con el usuario delante (payInvoice) sí sigue la política general de reintentos.
Con OAuth, un 401 provoca además una renovación automática del token y un nuevo intento con el token renovado. Si la renovación falla, el error llega tal cual.
Depuración
Con debug activado, el SDK deja una traza por petición y otra por respuesta:
- JavaScript escribe en la consola con el prefijo
[UtiliaSDK]:Petición: POST /external/v1/tickets,Respuesta: 201 /external/v1/ticketsy, si reintenta,Reintento 1/2, esperando 500ms. - Python usa el registro estándar con el nombre
utilia_sdky nivelDEBUG:POST /external/v1/tickets (intento 1)yRespuesta: 201 /external/v1/tickets. No imprime nada hasta que configuras el registro de tu aplicación, por ejemplo conlogging.getLogger("utilia_sdk").setLevel(logging.DEBUG).
No dejes la depuración activada en producción: las trazas muestran las rutas que llamas.
Conexiones en tiempo real
Las funciones que reciben eventos en tiempo real (por ejemplo, el seguimiento de sugerencias con IA) usan Server-Sent Events. Como EventSource no admite cabeceras propias, el SDK pone la credencial en la dirección de la conexión. Lo hace por dentro: no tienes que construir esa dirección tú.
Diferencias entre los dos lenguajes
| Aspecto | JavaScript | Python |
|---|---|---|
| Nombres | camelCase (baseURL, apiKey) | snake_case (base_url, api_key) |
| Tiempo de espera | Milisegundos | Segundos |
| Cliente HTTP | axios | httpx |
| Modelos | Interfaces de TypeScript | Modelos de Pydantic |
| Modo síncrono | No aplica | UtiliaSDKSync |
| Cerrar la sesión | No hace falta | async with / with, o close() |
| Comprobaciones del error | Métodos: error.isRateLimited() | Propiedades: error.is_rate_limited |