Cobrixia · Versión 1

API pública de Cobrixia

Conecte su marcador o CRM (Wolkvox, Five9 y otros): consulte deudores y campañas, registre el resultado de cada llamada y reciba avisos por webhook.

Empezar en 5 minutos OpenAPI (YAML) Colección de Postman

Inicio rápido (5 minutos)

URL base: https://api.cobrixia.com

  1. Pida la activación. Cobrixia habilita la API por organización. Mientras no esté habilitada, todas las llamadas responden 403 api_deshabilitada.
  2. 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.
  3. 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
    }
  4. Busque un deudor por cédula o teléfono (ver GET /v1/deudores) y registre una llamada (ver POST /v1/gestiones).
  5. 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.
Todo ejemplo de esta página se ejecuta automáticamente contra el ambiente de pruebas de Cobrixia antes de publicarla: las respuestas que ve son reales.

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.

TipoPrefijoVe
De pruebacbx_test_Solo deudores marcados como de prueba.
Realcbx_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
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.

JavaScript
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

GET/v1/ping

Valida 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
curl 'https://api.cobrixia.com/v1/ping' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "estado": "ok",
  "modo_prueba": true
}

GET /v1/resultados

GET/v1/resultados

Catálogo de resultados estándar para POST /v1/gestiones (la misma tabla de Resultados y tipificaciones).

Catálogo de resultados estándar

curl
curl 'https://api.cobrixia.com/v1/resultados' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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

GET/v1/deudores

Busca 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ámetroEnTipoObligatorioDescripción
cedulaURLstringNoCédula o identificación. Obligatorio si no se envía `telefono`.
telefonoURLstringNoTeléfono en cualquier formato. Obligatorio si no se envía `cedula`.

Campos de cada deudor

CampoTipoObligatorioDescripciónEjemplo
idstring (uuid)SíId del deudor; es el `deudor_id` de `POST /v1/gestiones`.5372c7f1-d286-406d-8d0b-c201323271ea
nombrestringSíMaría Fernanda Solano Vargas
cedulastringSí1-0987-0654
telefonostring, puede ser nullSíTeléfono principal tal como está en la cartera.+50688887777
cliente_acreedorstringSíEmpresa que le tercerizó la cobranza.Financiera Ejemplo S.A.
saldonumberSíSaldo pendiente en la moneda de la organización.150000
dias_moraintegerSíDías de mora.45
no_llamarbooleanSí'`true` si pidió no ser llamado o el número es equivocado. No debe marcarse.'false
campana_idstring (uuid), puede ser nullSí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
curl 'https://api.cobrixia.com/v1/deudores?cedula=1-0987-0654' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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
curl 'https://api.cobrixia.com/v1/deudores?telefono=%2B50688887777' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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

GET/v1/campanas

Campañas de la organización, de la más reciente a la más antigua.

ParámetroEnTipoObligatorioDescripción
estadoURLstring (activa | pausada | cerrada)NoFiltra por estado de la campaña.
limiteURLinteger, 1–100NoTamaño de página (1 a 100).
cursorURLstringNoValor de `siguiente_cursor` de la página anterior. Es opaco: no lo modifique.

Campos de cada campaña

CampoTipoObligatorioDescripciónEjemplo
idstring (uuid)Sí68c09a96-97da-442f-a5a3-4804ae577961
nombrestringSíCobro octubre — mora 30 a 90 días
tipostringSí'`ia` la trabaja Sofía; `gestores` la trabajan personas.' Valores: ia, gestores.gestores
estadostringSí Valores: activa, pausada, cerrada.activa
cliente_acreedorstringSíFinanciera Ejemplo S.A.
total_deudoresintegerSíDeudores activos y llamables en el modo de su llave.120
created_atstring (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
curl 'https://api.cobrixia.com/v1/campanas?limite=1' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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

GET/v1/campanas/{id}/deudores

Los 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ámetroEnTipoObligatorioDescripción
idrutastringSíId de la campaña (de `GET /v1/campanas`).
limiteURLinteger, 1–500NoTamaño de página (1 a 500).
cursorURLstringNoValor de `siguiente_cursor` de la página anterior.

Campos de cada deudor de campaña

CampoTipoObligatorioDescripciónEjemplo
deudor_idstring (uuid)Sí5372c7f1-d286-406d-8d0b-c201323271ea
nombrestringSíMaría Fernanda Solano Vargas
cedulastringSí1-0987-0654
telefonostring, puede ser nullSí+50688887777
saldonumberSí150000
dias_moraintegerSí45
prioridadintegerSí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
curl 'https://api.cobrixia.com/v1/campanas/e02838c1-e6c9-48c0-ba46-d9e81d995889/deudores?limite=2' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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

POST/v1/gestiones

Registra 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

CampoTipoObligatorioDescripciónEjemplo
deudor_idstring (uuid)SíId del deudor (campo `id` de `GET /v1/deudores`).5372c7f1-d286-406d-8d0b-c201323271ea
resultadostringNoResultado 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_originalstringNoTipificación propia de su marcador; se traduce con el mapeo de la organización. Sin mapeo responde 422.NO CONTESTA
llamada_id_externostringSí'Id de la llamada en su marcador. Obligatorio: evita gestiones duplicadas al reintentar.'WV-2026-000123
notastringNoComentario del agente. No incluya datos sensibles.Pagará por SINPE el viernes
agentestringNoUsuario o nombre del agente que hizo la llamada.ana.rojas
fecha_horastring (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'
promesaobjetoNoObjeto 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

CampoTipoObligatorioDescripciónEjemplo
montonumberSíMonto prometido, mayor que cero. Debe ser un número (no texto).75000
fechastring (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

CampoTipoObligatorioDescripciónEjemplo
gestion_idstring (uuid)Sí0b5f3c1e-5f5e-4c52-9a31-1c0c6a0f9d11
promesa_idstring (uuid), puede ser nullSíId de la promesa creada, o `null` si el resultado no era `promesa`.7d1e2b64-9b0a-4a3c-8f6e-2f9a4b1c0d22
duplicadobooleanSí'`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
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"
  }
}'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 201
{
  "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
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"
  }
}'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 200
{
  "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
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"
}'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 201
{
  "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
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"
}'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 201
{
  "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:

HTTPCódigoSignificadoQué hacer
400json_invalidoEl cuerpo no es un JSON válido.Revise la sintaxis del JSON que envía.
401llave_requeridaNo se envió el encabezado X-API-Key.Agregue X-API-Key con su llave.
401llave_invalidaLa llave no existe o fue revocada.Verifique que la copió completa; si fue revocada, pida al admin una nueva en Configuración → Integraciones.
403api_deshabilitadaLa API no está habilitada para su organización.Pida a Cobrixia que la habilite.
404ruta_no_encontradaLa ruta no existe.Revise la URL contra esta documentación.
404deudor_no_encontradoNo 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.
404campana_no_encontradaLa campaña no existe en su organización.Obtenga el id con GET /v1/campanas.
405metodo_no_permitidoEl método HTTP no sirve para esa ruta.Use el método indicado en el encabezado Allow.
409llamada_id_externo_repetidoEse llamada_id_externo ya se registró con otro deudor.Los ids de llamada deben ser únicos por llamada.
413cuerpo_muy_grandeEl cuerpo supera los 10 KB.Envíe solo los campos de la documentación.
415tipo_no_soportadoFalta Content-Type: application/json.Agregue el encabezado.
422parametro_invalidoUn parámetro de la URL no es válido (límite, estado, cédula/teléfono).El mensaje dice cuál; corríjalo.
422cursor_invalidoEl cursor está mal formado o es de otra consulta.Empiece de nuevo sin cursor; no modifique el cursor.
422resultado_requerido / resultado_desconocidoFalta el resultado o no es uno de los estándar.Use un código de GET /v1/resultados, o envíe tipificacion_original.
422tipificacion_sin_mapeoLa tipificación propia no tiene mapeo.El admin la agrega en Configuración → Integraciones → Mapeo de tipificaciones.
422promesa_requerida / promesa_no_aplicaEl resultado "promesa" exige el objeto promesa, y los demás no lo admiten.Envíe promesa solo con resultado "promesa".
422promesa_monto_invalido / promesa_invalida / promesa_fecha_fuera_de_rangoEl 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.
422cuerpo_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_rangoUn campo obligatorio falta o no cumple el formato o el largo.El mensaje dice cuál campo; ver la tabla de campos del endpoint.
429limite_excedidoSuperó el límite de solicitudes por minuto de la llave.Espere los segundos de Retry-After y reintente; reduzca la frecuencia.
500error_internoError 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
curl 'https://api.cobrixia.com/v1/ping'
JavaScript (Node 18+)
const BASE = 'https://api.cobrixia.com';

const res = await fetch(`${BASE}/v1/ping`, {
  method: 'GET',
});
console.log(res.status, await res.json());
Python (requests)
import os
import requests

BASE = "https://api.cobrixia.com"

r = requests.get(
    f"{BASE}/v1/ping",
)
print(r.status_code, r.json())
Respuesta real · HTTP 401
{
  "error": {
    "codigo": "llave_requerida",
    "mensaje": "Falta el encabezado X-API-Key",
    "solicitud_id": "4547b9d0-de7b-46fa-a4f7-44de6b986de2"
  }
}

Error 422: dato inválido

curl
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"
}'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 422
{
  "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
curl 'https://api.cobrixia.com/v1/campanas/00000000-0000-0000-0000-000000000000/deudores' \
  -H 'X-API-Key: cbx_live_TU_LLAVE'
JavaScript (Node 18+)
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());
Python (requests)
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())
Respuesta real · HTTP 404
{
  "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)NombreCuándo usarloQué hace Cobrixia
buzon_de_vozBuzón de vozLa llamada cayó al buzón.Solo registra la gestión.
disputaDisputaEl deudor disputa la deuda.Solo registra la gestión.
no_contestaNo contestaNadie contestó la llamada.Solo registra la gestión.
no_es_la_personaNo es la personaContestó otra persona (familiar, compañero). El número puede seguir siendo del deudor.Solo registra la gestión.
numero_equivocadoNúmero equivocadoEl número no es del deudor.Marca al deudor como "no llamar" (motivo número equivocado).
pago_realizadoPago realizadoEl deudor dice que ya pagó.Solo registra la gestión; el saldo cambia cuando el pago se carga a la cartera.
pidio_no_llamarPidió no ser llamadoLa persona pidió que no la vuelvan a llamar.Marca al deudor como "no llamar" (motivo pidió no llamar).
promesaPromesa de pagoEl deudor se comprometió a pagar. Exige el objeto promesa (monto y fecha).Crea la promesa de pago.
rechazoRechazoEl deudor contestó y se negó a pagar.Solo registra la gestión.
sin_acuerdoSin acuerdoHubo conversación pero no se llegó a un acuerdo.Solo registra la gestión.
volver_a_llamarVolver a llamarPidió 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:

  1. El administrador entra a Configuración → Integraciones → Mapeo de tipificaciones.
  2. 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.
  3. Su marcador envía tipificacion_original en lugar de resultado. Cobrixia la traduce y guarda ambas.
Tipificación de la agencia (ejemplo)Resultado estándar
CLIENTE PROMETEpromesa
NO CONTESTAno_contesta
BUZONbuzon_de_voz
NUMERO ERRADOnumero_equivocado
NO LLAMARpidio_no_llamar
LLAMAR DESPUÉSvolver_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.

EventoCuándo se envía
campana.creadaSe crea una campaña.
promesa.registradaSe registra una promesa de pago, venga de la API, de un gestor o de Sofía.
deudor.no_llamarUn 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

Cuerpo
{
  "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

Cuerpo
{
  "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

Cuerpo
{
  "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.

JavaScript (Node) · verificar-firma.js
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);
}
JavaScript · ejemplo con Express
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);
Python · verificar_firma.py
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", ""))
Python · ejemplo con Flask
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 segundos
Estos fragmentos se ejecutan en las pruebas automáticas con firmas reales (válida, alterada, vencida y con otro secreto).

Modo 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 responde 404.
  • 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/ping devuelve "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 entregaNo 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 nota de 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ónFechaCambios
1.0.02026-10-16Primera 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

Esta guía se basa en la documentación pública de Wolkvox (componente Rest api v2 de Wolkvox Studio e Integración web de Wolkvox Manager). Los nombres de menús pueden variar según la versión de su cuenta, y aún no se ha probado con una cuenta real de Wolkvox: haga la primera prueba con una llave de prueba (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.

  1. Buscar al deudor. En el flujo, agregue un componente Rest api v2:
    URLhttps://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étodoGET
    HeadersX-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 out10 segundos
    Resultado$res_api_deudor
    Si la búsqueda es por cédula use ?cedula= en vez de ?telefono=.
  2. Revisar el código HTTP. Con una bifurcación sobre $rest_api_code: 200 sigue el flujo; 401/403 = llave o habilitación (avise a su administrador); 429 = espere unos segundos y reintente; 5xx = reintente o siga sin datos.
  3. Tomar los datos de la respuesta. El JSON queda en $res_api_deudor. Necesita sacar de ahí el id del deudor (será el deudor_id del paso siguiente) y, si quiere mostrarlos al agente, nombre, saldo y dias_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).
  4. Registrar el resultado al terminar la llamada. Otro componente Rest api v2:
    URLhttps://api.cobrixia.com/v1/gestiones
    MétodoPOST
    HeadersX-API-Key = su llave · Content-Type = application/json
    Cuerporaw con el JSON de abajo
    Resultado$res_api_gestion
    Cuerpo (raw)
    {
      "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>"
    }
    Use como llamada_id_externo la 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).
  5. 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.

Importante: la integración web solo abre una URL en el navegador del agente; no puede enviar el encabezado 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:

  1. 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}
  2. 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 });
    });
  3. Cuando el agente guarda el resultado en esa página, su servidor llama a POST /v1/gestiones con llamada_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-Key y 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-DD dentro de los próximos 30 días?
  • ¿Cada tipificación del marcador tiene su mapeo?
  • ¿Envía un llamada_id_externo distinto 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.