Reach us out
Reach out directly to our team*
- Email hi@kleva.co
- WhatsApp +1 704-816-9059
- Office Miami, Florida
Guía técnica completa sobre cómo integrar APIs de voz con IA en sistemas de cobranza existentes, incluyendo arquitectura, endpoints críticos, flujos de datos, autenticación, y mejores prácticas de implementación.
May 15, 2026 12 min read
|La mayoría de las instituciones financieras que buscan automatizar su cobranza ya tienen sistemas funcionando: cores bancarios, CRMs, plataformas de gestión de cartera, y procesos establecidos. La pregunta crítica no es si implementar voice agents con IA, sino cómo integrarlos con el stack tecnológico existente sin disrupciones operativas.
Las APIs (Application Programming Interfaces) modernas de voz con IA están diseñadas para integraciones rápidas y robustas. Plataformas como Kleva, que procesa más de 900,000 minutos mensuales en 7 países de LATAM logrando 73% de tasa de recuperación y 94% de resolución en primera llamada, ofrecen APIs RESTful bien documentadas que permiten integraciones en 1-3 semanas incluso con sistemas legacy.
Una integración completa de API de voz IA con sistema de cobranza involucra:
El flujo operativo estándar:
POST /campaigns - Crear nueva campaña de cobranza
{
"name": "Mora 1-30 días Tarjetas",
"start_date": "2026-05-15T08:00:00Z",
"end_date": "2026-05-20T20:00:00Z",
"priority": "high",
"strategy": "early_delinquency",
"hours_allowed": {
"weekdays": ["08:00-20:00"],
"weekends": ["09:00-13:00"]
},
"max_attempts": 3,
"channels": ["voice", "whatsapp", "sms"]
}
GET /campaigns/{campaign_id} - Obtener estado de campaña
PUT /campaigns/{campaign_id} - Actualizar parámetros de campaña
DELETE /campaigns/{campaign_id} - Cancelar campaña
POST /contacts - Agregar contactos a campañas
{
"campaign_id": "camp_123456",
"contacts": [
{
"external_id": "CUST-78901",
"name": "Juan Pérez",
"phone": "+50612345678",
"email": "juan.perez@example.com",
"debt_amount": 15000,
"debt_currency": "CRC",
"days_overdue": 12,
"product_type": "credit_card",
"last_payment_date": "2026-03-15",
"customer_segment": "premium",
"metadata": {
"account_number": "4532-****-1234",
"payment_options": ["bank_transfer", "card", "cash"]
}
}
]
}
GET /contacts/{contact_id} - Obtener información y estado de contacto
PUT /contacts/{contact_id} - Actualizar datos de contacto
GET /interactions - Listar interacciones (con filtros)
GET /interactions?campaign_id=camp_123&status=completed&date_from=2026-05-15
Response:
{
"interactions": [
{
"id": "int_789012",
"contact_id": "cont_345678",
"campaign_id": "camp_123456",
"channel": "voice",
"status": "completed",
"outcome": "payment_promise",
"started_at": "2026-05-15T09:23:45Z",
"duration_seconds": 187,
"recording_url": "https://api.example.com/recordings/int_789012",
"transcript": "[Transcripción completa...]",
"promise_date": "2026-05-18",
"promise_amount": 15000,
"sentiment": "neutral",
"escalated": false
}
],
"pagination": {...}
}
GET /interactions/{interaction_id} - Detalle de interacción específica
GET /interactions/{interaction_id}/recording - Descargar grabación
GET /interactions/{interaction_id}/transcript - Obtener transcripción
POST /webhooks - Configurar webhook para eventos
{
"url": "https://tu-sistema.com/webhooks/cobranza",
"events": [
"interaction.completed",
"payment.promised",
"contact.unreachable",
"escalation.required"
],
"secret": "tu_secreto_para_validar_firma"
}
Cuando ocurre evento, la API envía POST a tu URL:
POST https://tu-sistema.com/webhooks/cobranza
{
"event_type": "interaction.completed",
"timestamp": "2026-05-15T09:25:12Z",
"data": {
"interaction_id": "int_789012",
"contact_id": "cont_345678",
"outcome": "payment_promise",
"promise_date": "2026-05-18",
"promise_amount": 15000
}
}
GET /reports/campaign-performance - Métricas de campaña
{
"campaign_id": "camp_123456",
"metrics": {
"total_contacts": 1000,
"attempted": 950,
"contacted": 712,
"contact_rate": 0.75,
"promises": 428,
"promise_rate": 0.60,
"paid": 312,
"payment_rate": 0.73,
"amount_promised": 6420000,
"amount_collected": 4680000,
"avg_duration_seconds": 165,
"escalations": 87
}
}
La mayoría de APIs modernas usan OAuth 2.0 o API keys para autenticación:
// Autenticación con API Key
GET /campaigns
Authorization: Bearer sk_live_1234567890abcdef
// O con OAuth 2.0
1. Obtener token:
POST /oauth/token
{
"client_id": "tu_client_id",
"client_secret": "tu_client_secret",
"grant_type": "client_credentials"
}
2. Usar token en requests:
GET /campaigns
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Para validar que webhook proviene realmente de la API:
// La API envía firma HMAC en header
X-Webhook-Signature: sha256=5f3d8b2a1c...
// Tu sistema valida:
function validateWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from('sha256=' + expectedSignature)
);
}
Para sistemas core que no permiten integraciones en tiempo real:
Ventaja: No requiere cambios en sistema core. Desventaja: Datos no en tiempo real.
Para sistemas con arquitectura de eventos:
Ventaja: Tiempo real, escalable. Desventaja: Requiere arquitectura moderna.
Balance entre batch y tiempo real:
Ventaja: Balance entre tiempo real y no sobrecargar sistemas. Desventaja: Complejidad media.
AspectoBatch DiarioEvent-DrivenHíbrido con Queue
Latencia de datos24 horasSegundosMinutos a horas
Complejidad implementaciónBajaAltaMedia
Requisitos de infraestructuraMínimos (cron job)Event bus, microserviciosQueue, workers
Tiempo de implementación1-2 semanas3-4 semanas2-3 semanas
EscalabilidadLimitadaAltaMedia-Alta
Tolerancia a fallasMediaAlta (con retry)Alta (queue persiste)
Compatibilidad con legacyExcelenteBajaMedia
Costo operativoBajoMedio-AltoMedio
Implementar retry exponencial para errores transitorios:
async function callAPIWithRetry(endpoint, data, maxRetries = 3) {
let lastError;
for (let i = 0; i = 500) {
throw new Error(`Server error: ${response.status}`);
}
// Si es error 4xx (cliente), no reintentar
throw new Error(`Client error: ${response.status}`);
} catch (error) {
lastError = error;
// Espera exponencial: 1s, 2s, 4s
const waitTime = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
throw lastError;
}
Para proteger tu sistema si API tiene problemas:
class CircuitBreaker {
constructor(threshold = 5, timeout = 60000) {
this.failureCount = 0;
this.threshold = threshold;
this.timeout = timeout;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.nextAttempt = Date.now();
}
async call(fn) {
if (this.state === 'OPEN') {
if (Date.now() = this.threshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.timeout;
}
}
}
Asegurar que reintentos no creen duplicados:
POST /contacts
{
"idempotency_key": "unique-key-12345",
"contacts": [...]
}
// La API garantiza que mismo idempotency_key
// no crea contactos duplicados
{
"timestamp": "2026-05-15T09:23:45.123Z",
"level": "info",
"service": "cobranza-integration",
"event": "api_call",
"endpoint": "POST /contacts",
"duration_ms": 234,
"status_code": 200,
"campaign_id": "camp_123456",
"contacts_count": 50,
"request_id": "req_789012"
}
Configurar alertas para:
const express = require('express');
const axios = require('axios');
const app = express();
const KLEVA_API_URL = 'https://api.kleva.co/v1';
const API_KEY = process.env.KLEVA_API_KEY;
// Endpoint para recibir webhooks de Kleva
app.post('/webhooks/kleva', async (req, res) => {
const { event_type, data } = req.body;
// Validar firma del webhook
if (!validateWebhookSignature(req)) {
return res.status(401).send('Invalid signature');
}
try {
switch(event_type) {
case 'interaction.completed':
await handleInteractionCompleted(data);
break;
case 'payment.promised':
await handlePaymentPromised(data);
break;
case 'escalation.required':
await handleEscalation(data);
break;
}
res.status(200).send('OK');
} catch (error) {
console.error('Error processing webhook:', error);
res.status(500).send('Error');
}
});
// Función para crear campaña
async function createCampaign(config) {
const response = await axios.post(
`${KLEVA_API_URL}/campaigns`,
config,
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Función para agregar contactos
async function addContacts(campaignId, contacts) {
const response = await axios.post(
`${KLEVA_API_URL}/contacts`,
{
campaign_id: campaignId,
contacts: contacts
},
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Handler para interacción completada
async function handleInteractionCompleted(data) {
const { interaction_id, contact_id, outcome, promise_date, promise_amount } = data;
// Actualizar CRM con resultado
await updateCRM({
contact_id,
last_interaction: new Date(),
outcome,
promise_date,
promise_amount
});
// Si hay promesa, crear recordatorio
if (outcome === 'payment_promise') {
await createPaymentReminder({
contact_id,
due_date: promise_date,
amount: promise_amount
});
}
}
app.listen(3000, () => {
console.log('Integration service running on port 3000');
});
Usar versiones explícitas en URLs:
https://api.kleva.co/v1/campaigns // Versión 1
https://api.kleva.co/v2/campaigns // Versión 2 (cuando exista)
Respetar límites de la API:
// Típicamente en headers de respuesta:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1620123456
// Implementar throttling en tu lado:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minuto
max: 100 // máximo 100 requests por minuto
});
Para endpoints que retornan listas grandes:
GET /interactions?page=1&limit=100
Response:
{
"interactions": [...],
"pagination": {
"current_page": 1,
"total_pages": 24,
"total_items": 2367,
"next_page": 2
}
}
GET /interactions?
campaign_id=camp_123&
status=completed&
outcome=payment_promise&
date_from=2026-05-01&
date_to=2026-05-15&
sort=-created_at&
limit=50
Para reducir payload:
GET /interactions?fields=id,contact_id,outcome,promise_amount
Para una integración exitosa:
El tiempo de integración típicamente varía entre 1 y 3 semanas dependiendo de la complejidad de tu stack tecnológico y el patrón elegido. Con un sistema moderno y APIs bien documentadas como las de Kleva, una integración batch simple puede estar funcionando en 1 semana, mientras una integración event-driven completa puede tomar 2-3 semanas. El factor crítico suele ser la disponibilidad de tu equipo técnico y la complejidad de tu sistema core, no la API de voz en sí.
No necesariamente. El patrón de integración batch permite conectar sin modificar el core: un job extrae datos del core (vía SQL query o export), los transforma al formato de la API, y carga resultados de vuelta. Esto funciona incluso con sistemas legacy cerrados. Si tu core tiene capacidades de integración modernas (webhooks, APIs), puedes implementar patrones más avanzados en tiempo real, pero no es requisito. La mayoría de implementaciones exitosas usan enfoque híbrido que no requiere cambios disruptivos al core.
Las APIs profesionales de voz IA implementan múltiples capas de seguridad: comunicación exclusiva sobre HTTPS/TLS 1.3, cifrado end-to-end de datos en tránsito y reposo, autenticación mediante OAuth 2.0 o API keys con rotación periódica, y cumplimiento con regulaciones de protección de datos (GDPR, LGPD, leyes locales). Adicionalmente, puedes implementar tokenización de datos sensibles (números de cuenta, etc.) en tu lado, enviando solo tokens a la API. Kleva opera con cero violaciones en 7 países de LATAM cumpliendo estrictamente con protección de datos.
Una integración robusta implementa múltiples mecanismos de resilencia: retry logic con backoff exponencial para errores transitorios, circuit breaker que detecta cuando API está caída y evita sobrecargarla, queues que persisten mensajes si API no está disponible temporalmente, y fallback a proceso manual si la caída es prolongada. Adicionalmente, las plataformas empresariales tienen SLAs de uptime (típicamente 99.9%+) y redundancia geográfica. El diseño correcto de integración asegura que una caída temporal no paralice tu operación de cobranza.
La reconciliación típicamente se hace mediante jobs periódicos que comparan: número de contactos enviados vs. número de interacciones registradas, promesas de pago capturadas vs. compromisos registrados en core, pagos recibidos vs. gestiones cerradas. Las APIs modernas proporcionan endpoints de reportes y exportación que facilitan esta reconciliación. Se recomienda proceso diario de validación que identifica discrepancias (ej. promesa capturada pero no registrada en CRM) y las corrige. Los webhooks en tiempo real minimizan discrepancias al actualizar sistemas inmediatamente después de cada interacción.
No bots, no endless forms. Fill in your details and someone from our team will reach out.
Reach out directly to our team*
No bots, no endless forms.