Inicio rápido (5 minutos)
URL base: https://api.cobrixia.com
- Pida la activación. Cobrixia habilita la API por organización. Mientras no esté habilitada, todas las llamadas responden
403 api_deshabilitada. - Cree una llave. Un administrador entra a Configuración → Integraciones → Llaves de API, escribe un nombre (por ejemplo «Wolkvox producción») y pulsa Crear llave. Se muestra una sola vez: cópiela. Para empezar, cree una llave de prueba (
cbx_test_…): solo ve deudores de prueba. - Haga la primera consulta. Guarde la llave en una variable de entorno y compruebe que funciona:
curl
export COBRIXIA_API_KEY='cbx_test_...' curl 'https://api.cobrixia.com/v1/ping' -H "X-API-Key: $COBRIXIA_API_KEY"Respuesta real · HTTP 200{ "estado": "ok", "modo_prueba": true } - Busque un deudor por cédula o teléfono (ver GET /v1/deudores) y registre una llamada (ver POST /v1/gestiones).
- Pase a producción. Cree una llave real, cambie la llave en su marcador y revoque la de prueba. Para rotar llaves sin cortar el servicio puede tener 2 activas a la vez.
Autenticación
Envíe su llave en el encabezado X-API-Key en cada solicitud. Las llaves se guardan cifradas (hash) en Cobrixia: si la pierde, revóquela y cree otra. Nunca la ponga en una URL, en JavaScript de un navegador ni en un repositorio.
| Tipo | Prefijo | Ve |
|---|---|---|
| De prueba | cbx_test_ | Solo deudores marcados como de prueba. |
| Real | cbx_live_ | Solo deudores reales. Mientras la organización esté en modo prueba, queda igual que una de prueba (ver Modo prueba). |
Solo el administrador de la organización crea y revoca llaves. Toda solicitud responde con X-Request-Id; si necesita soporte, envíelo.
Límites (429)
Cada llave admite 300 solicitudes por minuto por defecto (Cobrixia puede ajustarlo por organización). Cada respuesta trae X-RateLimit-Limit y X-RateLimit-Remaining. Al superarlo:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
{"error":{"codigo":"limite_excedido","mensaje":"Superó el límite de 300 solicitudes por minuto; reintente en 23 s","solicitud_id":"…"}}Espere los segundos de Retry-After y reintente. Una campaña de miles de deudores se descarga con páginas de 500, no consultando uno por uno.
Paginación con cursor
Las listas (/v1/campanas y /v1/campanas/{id}/deudores) se paginan con limite y cursor. La respuesta trae siguiente_cursor: si no es null, pídalo como ?cursor=… con el mismo limite. El cursor es opaco (no lo modifique) y es estable aunque se agreguen registros mientras pagina.
let cursor = null;
do {
const url = new URL(`${BASE}/v1/campanas/${campanaId}/deudores`);
url.searchParams.set('limite', '500');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers: { 'X-API-Key': process.env.COBRIXIA_API_KEY } });
const pagina = await res.json();
procesar(pagina.datos);
cursor = pagina.siguiente_cursor; // null en la última página
} while (cursor);GET /v1/ping
/v1/pingValida la llave y dice si está en modo prueba. Cuenta como una solicitud para el límite.
Comprobar la llave
Úselo para la primera prueba. "modo_prueba": true significa que esta llave solo ve deudores de prueba.
curl 'https://api.cobrixia.com/v1/ping' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/ping`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/ping",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
)
print(r.status_code, r.json()){
"estado": "ok",
"modo_prueba": true
}GET /v1/resultados
/v1/resultadosCatálogo de resultados estándar para POST /v1/gestiones (la misma tabla de Resultados y tipificaciones).
Catálogo de resultados estándar
curl 'https://api.cobrixia.com/v1/resultados' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/resultados`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/resultados",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
)
print(r.status_code, r.json()){
"datos": [
{
"codigo": "buzon_de_voz",
"nombre": "Buzón de voz",
"descripcion": "La llamada cayó al buzón.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "disputa",
"nombre": "Disputa",
"descripcion": "El deudor disputa la deuda.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "no_contesta",
"nombre": "No contesta",
"descripcion": "Nadie contestó la llamada.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "no_es_la_persona",
"nombre": "No es la persona",
"descripcion": "Contestó otra persona (familiar, compañero). El número puede seguir siendo del deudor.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "numero_equivocado",
"nombre": "Número equivocado",
"descripcion": "El número no es del deudor.",
"efecto": "Marca al deudor como \"no llamar\" (motivo número equivocado)."
},
{
"codigo": "pago_realizado",
"nombre": "Pago realizado",
"descripcion": "El deudor dice que ya pagó.",
"efecto": "Solo registra la gestión; el saldo cambia cuando el pago se carga a la cartera."
},
{
"codigo": "pidio_no_llamar",
"nombre": "Pidió no ser llamado",
"descripcion": "La persona pidió que no la vuelvan a llamar.",
"efecto": "Marca al deudor como \"no llamar\" (motivo pidió no llamar)."
},
{
"codigo": "promesa",
"nombre": "Promesa de pago",
"descripcion": "El deudor se comprometió a pagar. Exige el objeto promesa (monto y fecha).",
"efecto": "Crea la promesa de pago."
},
{
"codigo": "rechazo",
"nombre": "Rechazo",
"descripcion": "El deudor contestó y se negó a pagar.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "sin_acuerdo",
"nombre": "Sin acuerdo",
"descripcion": "Hubo conversación pero no se llegó a un acuerdo.",
"efecto": "Solo registra la gestión."
},
{
"codigo": "volver_a_llamar",
"nombre": "Volver a llamar",
"descripcion": "Pidió que lo llamen en otro momento.",
"efecto": "Solo registra la gestión."
}
]
}GET /v1/deudores
/v1/deudoresBusca por cédula o teléfono (exactamente uno). La cédula se compara sin guiones ni espacios; el teléfono por dígitos, con o sin código de país (mínimo 7 dígitos). Una persona puede aparecer una vez por cada cliente acreedor. Devuelve hasta 20 coincidencias; lista vacía si no hay.
| Parámetro | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
cedula | URL | string | No | Cédula o identificación. Obligatorio si no se envía `telefono`. |
telefono | URL | string | No | Teléfono en cualquier formato. Obligatorio si no se envía `cedula`. |
Campos de cada deudor
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
id | string (uuid) | Sí | Id del deudor; es el `deudor_id` de `POST /v1/gestiones`. | 5372c7f1-d286-406d-8d0b-c201323271ea |
nombre | string | Sí | María Fernanda Solano Vargas | |
cedula | string | Sí | 1-0987-0654 | |
telefono | string, puede ser null | Sí | Teléfono principal tal como está en la cartera. | +50688887777 |
cliente_acreedor | string | Sí | Empresa que le tercerizó la cobranza. | Financiera Ejemplo S.A. |
saldo | number | Sí | Saldo pendiente en la moneda de la organización. | 150000 |
dias_mora | integer | Sí | Días de mora. | 45 |
no_llamar | boolean | Sí | '`true` si pidió no ser llamado o el número es equivocado. No debe marcarse.' | false |
campana_id | string (uuid), puede ser null | Sí | Campaña activa en la que está, o `null`. | 68c09a96-97da-442f-a5a3-4804ae577961 |
Solo se entregan estos campos (ver datos mínimos). El id es el deudor_id que se envía a POST /v1/gestiones. Si no_llamar es true, no marque.
Buscar un deudor por cédula
La cédula se compara sin guiones ni espacios. Una persona puede aparecer una vez por cada cliente acreedor.
curl 'https://api.cobrixia.com/v1/deudores?cedula=1-0987-0654' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/deudores?cedula=1-0987-0654`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/deudores",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
params={
"cedula": "1-0987-0654",
},
)
print(r.status_code, r.json()){
"datos": [
{
"id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"nombre": "María Fernanda Solano Vargas",
"cedula": "1-0987-0654",
"telefono": "+50688887777",
"cliente_acreedor": "Financiera Ejemplo S.A.",
"saldo": 150000,
"dias_mora": 45,
"no_llamar": false,
"campana_id": "e02838c1-e6c9-48c0-ba46-d9e81d995889"
}
]
}Buscar un deudor por teléfono
Acepta el número con o sin código de país (8888-7777, +506 8888 7777). Mínimo 7 dígitos.
curl 'https://api.cobrixia.com/v1/deudores?telefono=%2B50688887777' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/deudores?telefono=%2B50688887777`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/deudores",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
params={
"telefono": "+50688887777",
},
)
print(r.status_code, r.json()){
"datos": [
{
"id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"nombre": "María Fernanda Solano Vargas",
"cedula": "1-0987-0654",
"telefono": "+50688887777",
"cliente_acreedor": "Financiera Ejemplo S.A.",
"saldo": 150000,
"dias_mora": 45,
"no_llamar": false,
"campana_id": "e02838c1-e6c9-48c0-ba46-d9e81d995889"
}
]
}GET /v1/campanas
/v1/campanasCampañas de la organización, de la más reciente a la más antigua.
| Parámetro | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
estado | URL | string (activa | pausada | cerrada) | No | Filtra por estado de la campaña. |
limite | URL | integer, 1–100 | No | Tamaño de página (1 a 100). |
cursor | URL | string | No | Valor de `siguiente_cursor` de la página anterior. Es opaco: no lo modifique. |
Campos de cada campaña
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
id | string (uuid) | Sí | 68c09a96-97da-442f-a5a3-4804ae577961 | |
nombre | string | Sí | Cobro octubre — mora 30 a 90 días | |
tipo | string | Sí | '`ia` la trabaja Sofía; `gestores` la trabajan personas.' Valores: ia, gestores. | gestores |
estado | string | Sí | Valores: activa, pausada, cerrada. | activa |
cliente_acreedor | string | Sí | Financiera Ejemplo S.A. | |
total_deudores | integer | Sí | Deudores activos y llamables en el modo de su llave. | 120 |
created_at | string (date-time) | Sí | '2026-10-16T12:30:24.857911+00:00' |
Listar campañas (paginado)
Si "siguiente_cursor" no es null, pídalo como ?cursor=… para la página siguiente.
curl 'https://api.cobrixia.com/v1/campanas?limite=1' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/campanas?limite=1`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/campanas",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
params={
"limite": "1",
},
)
print(r.status_code, r.json()){
"datos": [
{
"id": "e02838c1-e6c9-48c0-ba46-d9e81d995889",
"nombre": "Cobro octubre — mora 30 a 90 días",
"tipo": "ia",
"estado": "activa",
"cliente_acreedor": "Financiera Ejemplo S.A.",
"total_deudores": 3,
"created_at": "2026-10-16T12:39:22.140992+00:00"
}
],
"siguiente_cursor": "eyJ0IjoiMjAyNi0xMC0xNlQxMjozOToyMi4xNDA5OTIrMDA6MDAiLCJpIjoiZTAyODM4YzEtZTZjOS00OGMwLWJhNDYtZDllODFkOTk1ODg5In0"
}GET /v1/campanas/{id}/deudores
/v1/campanas/{id}/deudoresLos deudores a llamar de una campaña activa, por prioridad (mayor primero). No incluye a quienes pidieron que no los llamen ni a los casos que salieron de la campaña. Las campañas pausadas o cerradas devuelven lista vacía. Si el id no es de su organización responde 404.
| Parámetro | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | ruta | string | Sí | Id de la campaña (de `GET /v1/campanas`). |
limite | URL | integer, 1–500 | No | Tamaño de página (1 a 500). |
cursor | URL | string | No | Valor de `siguiente_cursor` de la página anterior. |
Campos de cada deudor de campaña
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
deudor_id | string (uuid) | Sí | 5372c7f1-d286-406d-8d0b-c201323271ea | |
nombre | string | Sí | María Fernanda Solano Vargas | |
cedula | string | Sí | 1-0987-0654 | |
telefono | string, puede ser null | Sí | +50688887777 | |
saldo | number | Sí | 150000 | |
dias_mora | integer | Sí | 45 | |
prioridad | integer | Sí | Mayor número = llamar antes. | 100 |
Deudores de una campaña (paginado)
Ordenados por prioridad (mayor primero). No incluye a quien pidió que no lo llamen ni a los casos fuera de la campaña.
curl 'https://api.cobrixia.com/v1/campanas/e02838c1-e6c9-48c0-ba46-d9e81d995889/deudores?limite=2' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/campanas/e02838c1-e6c9-48c0-ba46-d9e81d995889/deudores?limite=2`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/campanas/e02838c1-e6c9-48c0-ba46-d9e81d995889/deudores",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
params={
"limite": "2",
},
)
print(r.status_code, r.json()){
"datos": [
{
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"nombre": "María Fernanda Solano Vargas",
"cedula": "1-0987-0654",
"telefono": "+50688887777",
"saldo": 150000,
"dias_mora": 45,
"prioridad": 100
},
{
"deudor_id": "cdcaf5c3-bb7f-4ad9-bbf3-df4e55bd0511",
"nombre": "Carlos Andrés Jiménez Rojas",
"cedula": "2-0456-0789",
"telefono": "+50687654321",
"saldo": 80000,
"dias_mora": 20,
"prioridad": 99
}
],
"siguiente_cursor": "eyJwIjo5OSwiYyI6MjYwfQ"
}POST /v1/gestiones
/v1/gestionesRegistra el resultado de una llamada. Si el resultado es promesa, crea también la promesa de pago. Es idempotente por llamada_id_externo: si su sistema reintenta, no se duplica nada (responde 200 con "duplicado": true). Envíe Content-Type: application/json (máximo 10 KB).
Los resultados pidio_no_llamar y numero_equivocado marcan al deudor como «no llamar»: sale de las campañas y se dispara el webhook deudor.no_llamar.
Cuerpo
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
deudor_id | string (uuid) | Sí | Id del deudor (campo `id` de `GET /v1/deudores`). | 5372c7f1-d286-406d-8d0b-c201323271ea |
resultado | string | No | Resultado estándar (ver `GET /v1/resultados`). Valores: promesa, rechazo, no_contesta, buzon_de_voz, numero_equivocado, pidio_no_llamar, volver_a_llamar, sin_acuerdo, disputa, no_es_la_persona, pago_realizado. | promesa |
tipificacion_original | string | No | Tipificación propia de su marcador; se traduce con el mapeo de la organización. Sin mapeo responde 422. | NO CONTESTA |
llamada_id_externo | string | Sí | 'Id de la llamada en su marcador. Obligatorio: evita gestiones duplicadas al reintentar.' | WV-2026-000123 |
nota | string | No | Comentario del agente. No incluya datos sensibles. | Pagará por SINPE el viernes |
agente | string | No | Usuario o nombre del agente que hizo la llamada. | ana.rojas |
fecha_hora | string (date-time) | No | 'Cuándo ocurrió la llamada (ISO 8601). Por defecto, ahora. No puede ser futura ni de hace más de 30 días.' | '2026-10-16T14:30:00-06:00' |
promesa | objeto | No | Objeto con monto y fecha (ver abajo). |
Envíe resultado o tipificacion_original (al menos uno; si manda ambos, rige resultado). Con resultado: "promesa" el objeto promesa es obligatorio; con cualquier otro, no se admite.
Objeto promesa
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
monto | number | Sí | Monto prometido, mayor que cero. Debe ser un número (no texto). | 75000 |
fecha | string (date) | Sí | 'Fecha de pago AAAA-MM-DD, entre hoy y el máximo de días de promesa de la organización (30 por defecto).' | 2026-10-21 |
Respuesta
| Campo | Tipo | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|
gestion_id | string (uuid) | Sí | 0b5f3c1e-5f5e-4c52-9a31-1c0c6a0f9d11 | |
promesa_id | string (uuid), puede ser null | Sí | Id de la promesa creada, o `null` si el resultado no era `promesa`. | 7d1e2b64-9b0a-4a3c-8f6e-2f9a4b1c0d22 |
duplicado | boolean | Sí | '`true` si la llamada ya estaba registrada.' | false |
Códigos: 201 creada · 200 ya existía (idempotente) · 404 deudor inexistente · 409 el llamada_id_externo ya se usó con otro deudor · 422 dato inválido. Ver Errores.
Registrar una llamada con promesa de pago
llamada_id_externo es el id de la llamada en su marcador: reenviar la misma solicitud no duplica nada.
curl -X POST 'https://api.cobrixia.com/v1/gestiones' \
-H 'X-API-Key: cbx_live_TU_LLAVE' \
-H 'Content-Type: application/json' \
-d '{
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21"
}
}'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/gestiones`, {
method: 'POST',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21"
}
}),
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.post(
f"{BASE}/v1/gestiones",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
json={
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21",
},
},
)
print(r.status_code, r.json()){
"gestion_id": "0413c001-9192-4f94-86f9-6d629bfee4b6",
"promesa_id": "afb9f1e5-1db8-488a-a934-53fe5dfce96a",
"duplicado": false
}Reenviar la misma gestión (idempotente)
Mismo llamada_id_externo: responde 200 con "duplicado": true y los mismos ids.
curl -X POST 'https://api.cobrixia.com/v1/gestiones' \
-H 'X-API-Key: cbx_live_TU_LLAVE' \
-H 'Content-Type: application/json' \
-d '{
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21"
}
}'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/gestiones`, {
method: 'POST',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21"
}
}),
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.post(
f"{BASE}/v1/gestiones",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
json={
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"nota": "Pagará por SINPE el viernes",
"llamada_id_externo": "WV-2026-000123",
"agente": "ana.rojas",
"fecha_hora": "2026-10-16T12:39:23.891Z",
"promesa": {
"monto": 75000,
"fecha": "2026-10-21",
},
},
)
print(r.status_code, r.json()){
"gestion_id": "0413c001-9192-4f94-86f9-6d629bfee4b6",
"promesa_id": "afb9f1e5-1db8-488a-a934-53fe5dfce96a",
"duplicado": true
}Registrar con la tipificación propia de la agencia
Cobrixia traduce la tipificación con el mapeo de Configuración → Integraciones. Sin mapeo responde 422.
curl -X POST 'https://api.cobrixia.com/v1/gestiones' \
-H 'X-API-Key: cbx_live_TU_LLAVE' \
-H 'Content-Type: application/json' \
-d '{
"deudor_id": "cdcaf5c3-bb7f-4ad9-bbf3-df4e55bd0511",
"tipificacion_original": "NO CONTESTA",
"llamada_id_externo": "WV-2026-000124",
"agente": "luis.mora"
}'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/gestiones`, {
method: 'POST',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"deudor_id": "cdcaf5c3-bb7f-4ad9-bbf3-df4e55bd0511",
"tipificacion_original": "NO CONTESTA",
"llamada_id_externo": "WV-2026-000124",
"agente": "luis.mora"
}),
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.post(
f"{BASE}/v1/gestiones",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
json={
"deudor_id": "cdcaf5c3-bb7f-4ad9-bbf3-df4e55bd0511",
"tipificacion_original": "NO CONTESTA",
"llamada_id_externo": "WV-2026-000124",
"agente": "luis.mora",
},
)
print(r.status_code, r.json()){
"gestion_id": "49b871ec-57be-491c-bfff-b4fa41b2fd20",
"promesa_id": null,
"duplicado": false
}El deudor pidió que no lo llamen
Marca al deudor como "no llamar": sale de las campañas y se dispara el evento deudor.no_llamar.
curl -X POST 'https://api.cobrixia.com/v1/gestiones' \
-H 'X-API-Key: cbx_live_TU_LLAVE' \
-H 'Content-Type: application/json' \
-d '{
"deudor_id": "99d70ed6-5dff-4aee-abd3-ad02e9c9d5ed",
"resultado": "pidio_no_llamar",
"nota": "Pidió no recibir más llamadas",
"llamada_id_externo": "WV-2026-000125",
"agente": "luis.mora"
}'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/gestiones`, {
method: 'POST',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"deudor_id": "99d70ed6-5dff-4aee-abd3-ad02e9c9d5ed",
"resultado": "pidio_no_llamar",
"nota": "Pidió no recibir más llamadas",
"llamada_id_externo": "WV-2026-000125",
"agente": "luis.mora"
}),
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.post(
f"{BASE}/v1/gestiones",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
json={
"deudor_id": "99d70ed6-5dff-4aee-abd3-ad02e9c9d5ed",
"resultado": "pidio_no_llamar",
"nota": "Pidió no recibir más llamadas",
"llamada_id_externo": "WV-2026-000125",
"agente": "luis.mora",
},
)
print(r.status_code, r.json()){
"gestion_id": "5337da4e-0bb9-4edc-a390-878a06203bfb",
"promesa_id": null,
"duplicado": false
}Errores
Todo error tiene la misma forma, con un codigo estable para programar la reacción, un mensaje en español para personas y el solicitud_id para soporte:
| HTTP | Código | Significado | Qué hacer |
|---|---|---|---|
| 400 | json_invalido | El cuerpo no es un JSON válido. | Revise la sintaxis del JSON que envía. |
| 401 | llave_requerida | No se envió el encabezado X-API-Key. | Agregue X-API-Key con su llave. |
| 401 | llave_invalida | La llave no existe o fue revocada. | Verifique que la copió completa; si fue revocada, pida al admin una nueva en Configuración → Integraciones. |
| 403 | api_deshabilitada | La API no está habilitada para su organización. | Pida a Cobrixia que la habilite. |
| 404 | ruta_no_encontrada | La ruta no existe. | Revise la URL contra esta documentación. |
| 404 | deudor_no_encontrado | No hay un deudor con ese deudor_id en su organización (o es de otro modo: prueba/real). | Búsquelo primero con GET /v1/deudores. Con llave de prueba solo existen deudores de prueba. |
| 404 | campana_no_encontrada | La campaña no existe en su organización. | Obtenga el id con GET /v1/campanas. |
| 405 | metodo_no_permitido | El método HTTP no sirve para esa ruta. | Use el método indicado en el encabezado Allow. |
| 409 | llamada_id_externo_repetido | Ese llamada_id_externo ya se registró con otro deudor. | Los ids de llamada deben ser únicos por llamada. |
| 413 | cuerpo_muy_grande | El cuerpo supera los 10 KB. | Envíe solo los campos de la documentación. |
| 415 | tipo_no_soportado | Falta Content-Type: application/json. | Agregue el encabezado. |
| 422 | parametro_invalido | Un parámetro de la URL no es válido (límite, estado, cédula/teléfono). | El mensaje dice cuál; corríjalo. |
| 422 | cursor_invalido | El cursor está mal formado o es de otra consulta. | Empiece de nuevo sin cursor; no modifique el cursor. |
| 422 | resultado_requerido / resultado_desconocido | Falta el resultado o no es uno de los estándar. | Use un código de GET /v1/resultados, o envíe tipificacion_original. |
| 422 | tipificacion_sin_mapeo | La tipificación propia no tiene mapeo. | El admin la agrega en Configuración → Integraciones → Mapeo de tipificaciones. |
| 422 | promesa_requerida / promesa_no_aplica | El resultado "promesa" exige el objeto promesa, y los demás no lo admiten. | Envíe promesa solo con resultado "promesa". |
| 422 | promesa_monto_invalido / promesa_invalida / promesa_fecha_fuera_de_rango | El monto debe ser un número mayor que cero; la fecha AAAA-MM-DD, entre hoy y el máximo de días de promesa de la organización (30 por defecto). | Corrija el monto o la fecha. |
| 422 | cuerpo_invalido / llamada_id_externo_invalido / deudor_id_invalido / tipo_invalido / nota_muy_larga / agente_muy_largo / tipificacion_muy_larga / fecha_hora_invalida / fecha_hora_fuera_de_rango | Un campo obligatorio falta o no cumple el formato o el largo. | El mensaje dice cuál campo; ver la tabla de campos del endpoint. |
| 429 | limite_excedido | Superó el límite de solicitudes por minuto de la llave. | Espere los segundos de Retry-After y reintente; reduzca la frecuencia. |
| 500 | error_interno | Error de Cobrixia. | Reintente en unos segundos; si persiste, envíe el solicitud_id de la respuesta a soporte. |
Reintente solo 429, 500 y errores de red (con espera creciente). Los 4xx restantes no se arreglan reintentando: corrija la solicitud.
Ejemplos reales
Error 401: falta la llave
curl 'https://api.cobrixia.com/v1/ping'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/ping`, {
method: 'GET',
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/ping",
)
print(r.status_code, r.json()){
"error": {
"codigo": "llave_requerida",
"mensaje": "Falta el encabezado X-API-Key",
"solicitud_id": "4547b9d0-de7b-46fa-a4f7-44de6b986de2"
}
}Error 422: dato inválido
curl -X POST 'https://api.cobrixia.com/v1/gestiones' \
-H 'X-API-Key: cbx_live_TU_LLAVE' \
-H 'Content-Type: application/json' \
-d '{
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"llamada_id_externo": "WV-2026-000126"
}'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/gestiones`, {
method: 'POST',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"llamada_id_externo": "WV-2026-000126"
}),
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.post(
f"{BASE}/v1/gestiones",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
json={
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"resultado": "promesa",
"llamada_id_externo": "WV-2026-000126",
},
)
print(r.status_code, r.json()){
"error": {
"codigo": "promesa_requerida",
"mensaje": "El resultado \"promesa\" exige el objeto promesa con monto y fecha",
"solicitud_id": "78b17987-4676-473d-99d6-be4e8b3c88fd"
}
}Error 404: campaña inexistente
curl 'https://api.cobrixia.com/v1/campanas/00000000-0000-0000-0000-000000000000/deudores' \
-H 'X-API-Key: cbx_live_TU_LLAVE'const BASE = 'https://api.cobrixia.com';
const res = await fetch(`${BASE}/v1/campanas/00000000-0000-0000-0000-000000000000/deudores`, {
method: 'GET',
headers: {
'X-API-Key': process.env.COBRIXIA_API_KEY,
},
});
console.log(res.status, await res.json());import os
import requests
BASE = "https://api.cobrixia.com"
r = requests.get(
f"{BASE}/v1/campanas/00000000-0000-0000-0000-000000000000/deudores",
headers={"X-API-Key": os.environ["COBRIXIA_API_KEY"]},
)
print(r.status_code, r.json()){
"error": {
"codigo": "campana_no_encontrada",
"mensaje": "No existe una campaña con ese id",
"solicitud_id": "a414fb66-f0b1-4fb1-977a-e14e69ad5bce"
}
}Resultados estándar y tipificaciones propias
Cada llamada termina en uno de estos resultados estándar:
Código (resultado) | Nombre | Cuándo usarlo | Qué hace Cobrixia |
|---|---|---|---|
buzon_de_voz | Buzón de voz | La llamada cayó al buzón. | Solo registra la gestión. |
disputa | Disputa | El deudor disputa la deuda. | Solo registra la gestión. |
no_contesta | No contesta | Nadie contestó la llamada. | Solo registra la gestión. |
no_es_la_persona | No es la persona | Contestó otra persona (familiar, compañero). El número puede seguir siendo del deudor. | Solo registra la gestión. |
numero_equivocado | Número equivocado | El número no es del deudor. | Marca al deudor como "no llamar" (motivo número equivocado). |
pago_realizado | Pago realizado | El deudor dice que ya pagó. | Solo registra la gestión; el saldo cambia cuando el pago se carga a la cartera. |
pidio_no_llamar | Pidió no ser llamado | La persona pidió que no la vuelvan a llamar. | Marca al deudor como "no llamar" (motivo pidió no llamar). |
promesa | Promesa de pago | El deudor se comprometió a pagar. Exige el objeto promesa (monto y fecha). | Crea la promesa de pago. |
rechazo | Rechazo | El deudor contestó y se negó a pagar. | Solo registra la gestión. |
sin_acuerdo | Sin acuerdo | Hubo conversación pero no se llegó a un acuerdo. | Solo registra la gestión. |
volver_a_llamar | Volver a llamar | Pidió que lo llamen en otro momento. | Solo registra la gestión. |
Cómo mapear las tipificaciones de su marcador
Su agencia ya tiene sus propias tipificaciones («CLIENTE PROMETE», «NO CONTESTA», «NÚMERO ERRADO»…). No hace falta cambiarlas en el marcador:
- El administrador entra a Configuración → Integraciones → Mapeo de tipificaciones.
- Escribe la tipificación tal como la envía su marcador y elige el resultado estándar equivalente. No distingue mayúsculas ni espacios al inicio o al final.
- Su marcador envía
tipificacion_originalen lugar deresultado. Cobrixia la traduce y guarda ambas.
| Tipificación de la agencia (ejemplo) | Resultado estándar |
|---|---|
| CLIENTE PROMETE | promesa |
| NO CONTESTA | no_contesta |
| BUZON | buzon_de_voz |
| NUMERO ERRADO | numero_equivocado |
| NO LLAMAR | pidio_no_llamar |
| LLAMAR DESPUÉS | volver_a_llamar |
Si llega una tipificación sin mapeo, la API responde 422 tipificacion_sin_mapeo y no registra nada: agregue el mapeo y reenvíe la misma llamada (el mismo llamada_id_externo).
Webhooks salientes
Cobrixia avisa a su sistema cuando ocurre algo. El administrador configura la URL en Configuración → Integraciones → Webhooks salientes (debe ser https con un dominio público) y elige los eventos. Al guardar por primera vez se muestra el secreto (whsec_…) una sola vez; puede rotarlo cuando quiera.
| Evento | Cuándo se envía |
|---|---|
campana.creada | Se crea una campaña. |
promesa.registrada | Se registra una promesa de pago, venga de la API, de un gestor o de Sofía. |
deudor.no_llamar | Un deudor queda marcado «no llamar» (lo pidió o el número es equivocado). |
Qué recibe su URL
Un POST con JSON y estos encabezados: X-Cobrixia-Event (evento), X-Cobrixia-Delivery (id del envío) y X-Cobrixia-Signature (t=<segundos>,v1=<firma>). Responda cualquier 2xx en menos de 10 segundos. Si no, reintentamos a 1 min, 5 min, 30 min, 2 h y 6 h; luego queda como fallido (se ve en Configuración). No seguimos redirecciones. La entrega es al menos una vez: use el id del evento para ignorar repetidos. El campo prueba es true si el evento es de un deudor de prueba.
promesa.registrada
{
"id": "3a2f6b1e-0c9d-4c7a-8e21-7f5d9b3c1a40",
"evento": "promesa.registrada",
"creado": "2026-10-16T14:31:02.114+00:00",
"prueba": false,
"datos": {
"deudor_id": "4c50f6e6-4133-4355-a0c3-319edc3dd26e",
"cedula": "1-0987-0654",
"promesa_id": "7d1e2b64-9b0a-4a3c-8f6e-2f9a4b1c0d22",
"acuerdo_id": "7d1e2b64-9b0a-4a3c-8f6e-2f9a4b1c0d22",
"monto": 75000,
"fecha": "2026-10-21",
"origen": "api"
}
}campana.creada
{
"id": "0e8c1d2f-7a64-4b19-b5c3-91d7f2a6e803",
"evento": "campana.creada",
"creado": "2026-10-16T12:30:24.857+00:00",
"prueba": false,
"datos": {
"campana_id": "e02838c1-e6c9-48c0-ba46-d9e81d995889",
"nombre": "Cobro octubre — mora 30 a 90 días",
"tipo": "gestores"
}
}deudor.no_llamar
{
"id": "b94d6a10-3e2c-4f87-a1d5-6c0e8f7b2a19",
"evento": "deudor.no_llamar",
"creado": "2026-10-16T14:40:11.502+00:00",
"prueba": false,
"datos": {
"deudor_id": "99d70ed6-5dff-4aee-abd3-ad02e9c9d5ed",
"cedula": "3-101-654321",
"motivo": "pidio_no_llamar"
}
}Verificar la firma (HMAC-SHA256)
La firma es el HMAC-SHA256, en hexadecimal, de "<t>.<cuerpo exacto>" con su secreto. Verifíquela siempre, con el cuerpo tal como llegó (sin parsear antes), compare en tiempo constante y rechace marcas de tiempo con más de 5 minutos de diferencia.
import crypto from 'node:crypto';
/**
* Verifica la firma de un webhook de Cobrixia.
* @param {string} cuerpoCrudo El cuerpo EXACTO recibido (sin parsear ni reformatear el JSON).
* @param {string} cabecera Valor del encabezado X-Cobrixia-Signature ("t=...,v1=...").
* @param {string} secreto Su secreto whsec_... de Configuración → Integraciones.
*/
export function verificarFirma(cuerpoCrudo, cabecera, secreto, toleranciaSeg = 300) {
const partes = Object.fromEntries((cabecera ?? '').split(',').map(p => p.split('=')));
const t = Number(partes.t);
if (!t || Math.abs(Date.now() / 1000 - t) > toleranciaSeg) return false; // marca de tiempo vieja o ausente
const esperada = crypto.createHmac('sha256', secreto).update(`${t}.${cuerpoCrudo}`).digest('hex');
const a = Buffer.from(esperada);
const b = Buffer.from(partes.v1 ?? '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}import express from 'express';
import { verificarFirma } from './verificar-firma.js';
const app = express();
// Importante: express.raw, para conservar el cuerpo exacto que se firmó.
app.post('/webhooks/cobrixia', express.raw({ type: 'application/json' }), (req, res) => {
const cuerpo = req.body.toString('utf8');
if (!verificarFirma(cuerpo, req.get('X-Cobrixia-Signature'), process.env.COBRIXIA_WEBHOOK_SECRET)) {
return res.sendStatus(401);
}
const evento = JSON.parse(cuerpo);
// Cobrixia entrega "al menos una vez": ignore los ids que ya procesó.
console.log(evento.evento, evento.datos);
res.sendStatus(200); // cualquier 2xx en menos de 10 segundos
});
app.listen(3000);import hashlib
import hmac
import time
def verificar_firma(cuerpo_crudo: bytes, cabecera: str, secreto: str, tolerancia_seg: int = 300) -> bool:
"""Verifica la firma de un webhook de Cobrixia.
cuerpo_crudo: el cuerpo EXACTO recibido (bytes, sin parsear).
cabecera: valor del encabezado X-Cobrixia-Signature ("t=...,v1=...").
secreto: su secreto whsec_... de Configuración → Integraciones.
"""
try:
partes = dict(p.split("=", 1) for p in (cabecera or "").split(","))
t = int(partes["t"])
except (KeyError, ValueError):
return False
if abs(time.time() - t) > tolerancia_seg: # marca de tiempo vieja
return False
esperada = hmac.new(secreto.encode(), f"{t}.".encode() + cuerpo_crudo, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperada, partes.get("v1", ""))import os
from flask import Flask, request, abort
from verificar_firma import verificar_firma
app = Flask(__name__)
@app.post("/webhooks/cobrixia")
def webhook_cobrixia():
cuerpo = request.get_data() # bytes exactos, antes de parsear
if not verificar_firma(cuerpo, request.headers.get("X-Cobrixia-Signature", ""), os.environ["COBRIXIA_WEBHOOK_SECRET"]):
abort(401)
evento = request.get_json()
# Cobrixia entrega "al menos una vez": ignore los ids que ya procesó.
print(evento["evento"], evento["datos"])
return "", 200 # cualquier 2xx en menos de 10 segundosModo prueba y datos que se entregan
Cómo funciona el modo prueba
- Un deudor puede estar marcado de prueba (solo lo marca el dueño de la plataforma). Sirve para ensayar la integración sin tocar personas reales.
- Una llave de prueba (
cbx_test_…) solo ve y modifica deudores de prueba. Con ella, un deudor real responde404. - Una llave real (
cbx_live_…) solo ve deudores reales… mientras la organización no esté en modo prueba. Cobrixia mantiene cada organización en modo prueba hasta revisarla; en ese estado la llave real también ve solo deudores de prueba (igual que Sofía, que en modo prueba solo contacta deudores de prueba).GET /v1/pingdevuelve"modo_prueba"con el modo efectivo de su llave. - Los eventos de webhook de un deudor de prueba llevan
"prueba": true. - Las organizaciones están aisladas: una llave solo alcanza los datos de su propia organización, nunca los de otra.
Datos que se entregan (PRODHAB)
Cobrixia entrega únicamente lo necesario para gestionar la llamada:
| Se entrega | No se entrega nunca |
|---|---|
| Nombre, cédula, teléfono, cliente acreedor, saldo, días de mora, si está marcado «no llamar» y la campaña a la que pertenece. | Correo electrónico, dirección, facturas ni su detalle, historial de gestiones, grabaciones, documentos, ni datos de otros deudores o clientes. |
- Cada llamada a la API con llave válida queda registrada (método, ruta, estado, IP, tiempo e identificadores). No se guardan cédulas, teléfonos ni notas en ese registro, que se conserva 90 días y el administrador consulta en Configuración.
- El campo
notade las gestiones es texto libre: no incluya en él datos sensibles. - Su organización es responsable del tratamiento de los datos una vez que salen de Cobrixia hacia su marcador o CRM (finalidad, conservación y seguridad en su sistema).
Versionado y registro de cambios
La versión va en la ruta (/v1/…). Dentro de v1 solo hacemos cambios compatibles: agregar endpoints, campos opcionales o nuevos valores en campos de texto de listas cerradas. Por eso su integración debe ignorar los campos que no conozca y tolerar códigos de error nuevos. Un cambio que rompa compatibilidad saldrá como /v2, y /v1 seguirá funcionando al menos 6 meses después de anunciarlo.
| Versión | Fecha | Cambios |
|---|---|---|
| 1.0.0 | 2026-10-16 | Primera versión: GET /v1/ping, /v1/resultados, /v1/deudores, /v1/campanas, /v1/campanas/{id}/deudores, POST /v1/gestiones; llaves por organización (hasta 2 activas), límite por minuto, mapeo de tipificaciones y webhooks firmados (campana.creada, promesa.registrada, deudor.no_llamar). |
Guía paso a paso: Wolkvox
cbx_test_…) y avísenos de cualquier diferencia.Antes de empezar
- La API habilitada para su organización y una llave de Cobrixia (mejor, primero una de prueba).
- Acceso a Wolkvox Studio (para editar flujos) y a Wolkvox Manager (para Integraciones).
- El mapeo de tipificaciones cargado en Cobrixia (ver arriba).
A. Con Wolkvox Studio: el flujo habla con Cobrixia
Studio consume servicios externos con el componente Rest api v2 (grupo Communications). Tiene URL, método, Headers, Cuerpo (raw para JSON), Time out y Resultado (la variable donde queda la respuesta, por ejemplo $res_api_deudor). Además crea $rest_api_code con el código HTTP. La pestaña Probar api permite ensayar la llamada antes de compilar el flujo.
- Buscar al deudor. En el flujo, agregue un componente Rest api v2:
Si la búsqueda es por cédula useURL https://api.cobrixia.com/v1/deudores?telefono=+ la variable de Studio con el teléfono de la llamada (en llamadas entrantes,$ani; en campañas salientes, la variable que contenga el número marcado en su diseño)Método GET Headers X-API-Key= su llave (la documentación de Wolkvox indica que un token no debe pasar de 257 caracteres: la llave de Cobrixia tiene 73)Time out 10 segundos Resultado $res_api_deudor?cedula=en vez de?telefono=. - Revisar el código HTTP. Con una bifurcación sobre
$rest_api_code:200sigue el flujo;401/403= llave o habilitación (avise a su administrador);429= espere unos segundos y reintente;5xx= reintente o siga sin datos. - Tomar los datos de la respuesta. El JSON queda en
$res_api_deudor. Necesita sacar de ahí eliddel deudor (será eldeudor_iddel paso siguiente) y, si quiere mostrarlos al agente,nombre,saldoydias_mora. La guía pública de Wolkvox para este componente no detalla cómo leer campos de un JSON: use el componente de su versión de Studio para extraer valores de texto JSON (consúltelo con su ejecutivo de Wolkvox). - Registrar el resultado al terminar la llamada. Otro componente Rest api v2:
URL https://api.cobrixia.com/v1/gestionesMétodo POST Headers X-API-Key= su llave ·Content-Type=application/jsonCuerpo raw con el JSON de abajo Resultado $res_api_gestionCuerpo (raw)Use como{ "deudor_id": "<id del deudor, del paso 3>", "tipificacion_original": "<la tipificación que eligió el agente>", "llamada_id_externo": "<id de la llamada en Wolkvox>", "agente": "<id o nombre del agente>", "nota": "<comentario opcional>" }llamada_id_externola variable de Studio que contiene el identificador de la llamada: así los reintentos no duplican nada. Si la tipificación es una promesa, agregue"promesa": {"monto": 75000, "fecha": "2026-10-21"}(el monto va como número, sin comillas). - Probar. Use Probar api con la llave de prueba y un deudor de prueba. Si responde
422 tipificacion_sin_mapeo, agregue esa tipificación en el mapeo de Cobrixia. Cuando todo funcione, cambie la llave por la real.
B. Con la Integración web de Wolkvox Manager
En Wolkvox Manager → Integraciones → Integración web se define un Link de integración: una URL que Wolkvox abre como ventana emergente (en el navegador predeterminado o en el de AgentBox) cuando el agente recibe o hace una llamada, con datos de la llamada incluidos. Wolkvox permite usar variables en ese enlace, entre ellas la identificación del cliente {id_customer}, el teléfono {TELEFONO}, el id de la llamada {id_call} y los datos del agente ({id_agent}, {name_agent}), además de funciones para codificar en BASE64.
X-API-Key. Nunca ponga la llave de Cobrixia en el enlace ni en JavaScript de esa página (cualquiera podría verla). La llave debe vivir solo en el servidor de su CRM.El patrón correcto:
- En Manager, el Link de integración apunta a una página de su CRM, pasando los datos de la llamada:
Link de integración
https://su-crm.com/cobranza/ficha?cedula={id_customer}&telefono={TELEFONO}&llamada={id_call}&agente={id_agent} - El servidor de su CRM recibe esa solicitud y consulta Cobrixia con la llave guardada en su configuración:
Node.js (servidor de su CRM)
app.get('/cobranza/ficha', async (req, res) => { const r = await fetch(`https://api.cobrixia.com/v1/deudores?cedula=${encodeURIComponent(req.query.cedula)}`, { headers: { 'X-API-Key': process.env.COBRIXIA_API_KEY }, }); const { datos } = await r.json(); res.render('ficha', { deudor: datos[0], llamada: req.query.llamada, agente: req.query.agente }); }); - Cuando el agente guarda el resultado en esa página, su servidor llama a
POST /v1/gestionesconllamada_id_externo= el{id_call}recibido:Node.js (servidor de su CRM)app.post('/cobranza/resultado', express.json(), async (req, res) => { const r = await fetch('https://api.cobrixia.com/v1/gestiones', { method: 'POST', headers: { 'X-API-Key': process.env.COBRIXIA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ deudor_id: req.body.deudorId, tipificacion_original: req.body.tipificacion, llamada_id_externo: req.body.llamada, // el {id_call} de Wolkvox agente: req.body.agente, }), }); res.status(r.status).json(await r.json()); });
C. Webhooks: avisos hacia su sistema
Los webhooks de Cobrixia van a una URL de su servidor (no directamente a Wolkvox). Úselos, por ejemplo, para que su integración cargue una campaña nueva cuando llegue campana.creada (descargando los deudores con GET /v1/campanas/{id}/deudores) o para sacar de la marcación a quien llegue en deudor.no_llamar. Verifique siempre la firma (ver arriba).
Lista de verificación
- ¿La API está habilitada y la llave es del tipo correcto (prueba / real)? Pruebe con
GET /v1/ping. - ¿El encabezado es exactamente
X-API-Keyy la llave está completa, sin espacios ni saltos de línea? - ¿El monto de la promesa es un número y la fecha
AAAA-MM-DDdentro de los próximos 30 días? - ¿Cada tipificación del marcador tiene su mapeo?
- ¿Envía un
llamada_id_externodistinto por cada llamada?
Fuentes de Wolkvox consultadas: Cómo se configura el componente Rest api · Cómo integrar otros CRMs a Wolkvox · Variables disponibles en wolkvox Studio.
Colección de Postman
Descargue cobrixia.postman_collection.json e impórtela en Postman (Import). Trae todos los endpoints con ejemplos y variables de colección: base_url y api_key (pegue su llave) además de cedula, telefono, campana_id y deudor_id. Las pruebas de cada solicitud verifican el código HTTP esperado.
También puede importar openapi.yaml directamente en Postman, Insomnia o Swagger UI.
Soporte
Si algo no responde como esta guía, escriba a soporte@cobrixia.com con el solicitud_id de la respuesta (o el encabezado X-Request-Id), la hora y la ruta consultada. No envíe su llave.