Botyconnect API v1.1

Integra la cartera de tu ERP con la cobranza por WhatsApp

Tu ERP sigue siendo la fuente de verdad. Boty recibe deudas, cuotas y pagos externos; ejecuta la cobranza y te informa los pagos originados dentro de Boty.

Base URL

https://api.botyconnect.com/api/v1/botyconnect

Inicio rápido

  1. 1Crea una API key con cartera:read y cartera:write.
  2. 2Obtén el account_id wacc_ del número que hará la cobranza.
  3. 3Envía la carga inicial por /cartera/deudas/lote.
  4. 4Registra deuda y pagos incrementalmente; configura el webhook de pagos Boty.

ERP = fuente de verdad

Boty mantiene una réplica operativa para cobrar; el external_id lo define tu sistema.

Orden de eventos

Usa external_version creciente o external_updated_at para ignorar reintentos atrasados.

Aislamiento por tenant

Una API key nunca puede leer una deuda ni usar un account_id de otra empresa.

Estados en inglés

Usa pending, partial, paid, overdue, cancelled y written_off exactamente como aparecen.

Autenticación e idempotencia

Usa una key bc_live_ con cartera:read y/o cartera:write. Toda escritura exige un Idempotency-Key único por operación lógica.

Headers obligatorios
Authorization: Bearer bc_live_bck_xxxxxxxx.xxxxxxxxxxxxxxxx
Accept: application/json
Content-Type: application/json
Idempotency-Key: 39f350eb-f2a2-4dad-9574-91f0bd6df7bd
  • Misma key y mismo body: se devuelve la respuesta original con X-Botyconnect-Idempotent-Replay: true.
  • Misma key con body distinto: 409 idempotency_key_conflict.
  • Sin key en una escritura: 422 idempotency_key_required.
  • La identidad de una deuda es tenant + external_id; rotar la API key no crea duplicados.
POST/cartera/deudascartera:write

Crear o actualizar una deuda

Envía una deuda completa o actualiza su cabecera y saldo. Usa external_version creciente para evitar que un evento atrasado sobrescriba información nueva.

Request

cURL
curl -X POST 'https://api.botyconnect.com/api/v1/botyconnect/cartera/deudas' \
  -H 'Authorization: Bearer bc_live_...' \
  -H 'Idempotency-Key: debt-CRED-000123-v7' \
  -H 'Content-Type: application/json' \
  --data @deuda.json
JSON
{
  "account_id": "wacc_x8k2m9p4q7w1n5r3t6y0u2i4",
  "external_id": "CRED-000123",
  "external_version": 7,
  "deudor": {
    "nombre": "Johani Ramirez",
    "documento": "1033694167",
    "telefono": "573235529764"
  },
  "moneda": "COP",
  "referencia": "Credito mueble sala",
  "monto_original": 1360000,
  "saldo_pendiente": 870000,
  "tipo": "installments",
  "auto_send": true,
  "cuotas": [
    {
      "external_id": "CUO-0007",
      "numero": 7,
      "monto": 80000,
      "vence": "2026-09-15",
      "estado": "pending"
    },
    {
      "external_id": "CUO-0008",
      "numero": 8,
      "monto": 80000,
      "vence": "2026-10-15",
      "estado": "pending"
    }
  ]
}

Response

201 Created
{
  "success": true,
  "data": {
    "action": "created",
    "deuda": {
      "external_id": "CRED-000123",
      "saldo_pendiente": 870000,
      "status": "pending",
      "external_version": 7
    }
  }
}

cuotas ausente

Conserva el cronograma que ya existe en Boty.

cuotas: []

Cancela solo las cuotas abiertas; conserva las pagadas.

snapshot con cuotas

Actualiza las recibidas y cancela abiertas que ya no vengan.

POST/cartera/deudas/lotecartera:write

Carga inicial o sincronización por lote

Acepta de 1 a 500 deudas. Los errores de negocio se reportan por elemento; los registros válidos sí se guardan.

Request

JSON
{
  "deudas": [
    {
      "account_id": "wacc_x8k2m9p4q7w1n5r3t6y0u2i4",
      "external_id": "CRED-000123",
      "external_version": 7,
      "deudor": {
        "nombre": "Johani Ramirez",
        "documento": "1033694167",
        "telefono": "573235529764"
      },
      "moneda": "COP",
      "referencia": "Credito mueble sala",
      "monto_original": 1360000,
      "saldo_pendiente": 870000,
      "tipo": "installments",
      "auto_send": true,
      "cuotas": [
        {
          "external_id": "CUO-0007",
          "numero": 7,
          "monto": 80000,
          "vence": "2026-09-15",
          "estado": "pending"
        },
        {
          "external_id": "CUO-0008",
          "numero": 8,
          "monto": 80000,
          "vence": "2026-10-15",
          "estado": "pending"
        }
      ]
    },
    {
      "account_id": "wacc_x8k2m9p4q7w1n5r3t6y0u2i4",
      "external_id": "CRED-000124",
      "external_version": 1,
      "deudor": {
        "nombre": "Johani Ramirez",
        "documento": "1033694167",
        "telefono": "573235529764"
      },
      "moneda": "COP",
      "referencia": "Credito mueble sala",
      "monto_original": 1360000,
      "saldo_pendiente": 870000,
      "tipo": "installments",
      "auto_send": true,
      "cuotas": [
        {
          "external_id": "CUO-0007",
          "numero": 7,
          "monto": 80000,
          "vence": "2026-09-15",
          "estado": "pending"
        },
        {
          "external_id": "CUO-0008",
          "numero": 8,
          "monto": 80000,
          "vence": "2026-10-15",
          "estado": "pending"
        }
      ]
    }
  ]
}

Response

200 OK
{
  "success": true,
  "data": {
    "summary": {
      "created": 1,
      "updated": 1,
      "ignored_stale": 0,
      "errors": 0
    },
    "results": [
      {
        "external_id": "CRED-000123",
        "success": true,
        "action": "updated"
      },
      {
        "external_id": "CRED-000124",
        "success": true,
        "action": "created"
      }
    ]
  }
}
Usa una sola Idempotency-Key para la operación de lote. Si necesitas reintentar solo errores, envíalos en un lote nuevo con otra key.
GET/cartera/deudas/{external_id}cartera:read

Consultar estado para conciliación

Devuelve saldo, estado, deudor, cuotas y pagos conocidos por Boty sin exponer IDs internos.

Request

cURL
curl 'https://api.botyconnect.com/api/v1/botyconnect/cartera/deudas/CRED-000123' \
  -H 'Authorization: Bearer bc_live_...' \
  -H 'Accept: application/json'

Response

200 OK
{
  "success": true,
  "data": {
    "deuda": {
      "external_id": "CRED-000123",
      "account_id": "wacc_x8k2m9p4q7w1n5r3t6y0u2i4",
      "deudor": {
        "nombre": "Johani Ramirez",
        "documento": "1033694167",
        "telefono": "573235529764"
      },
      "moneda": "COP",
      "monto_original": 1360000,
      "saldo_pendiente": 870000,
      "status": "pending",
      "cuotas": [
        {
          "external_id": "CUO-0007",
          "numero": 7,
          "monto": 80000,
          "vence": "2026-09-15",
          "estado": "pending"
        }
      ],
      "pagos": []
    }
  }
}
POST/cartera/pagoscartera:write

Registrar un pago recibido por el ERP

Aplica el pago una sola vez por external_id, reduce el saldo y distribuye el monto por FIFO entre varias cuotas abiertas.

Request

JSON
{
  "external_id": "PAGO-99881",
  "deuda_external_id": "CRED-000123",
  "monto": 120000,
  "moneda": "COP",
  "metodo": "transferencia",
  "pagado_en": "2026-08-17T14:30:00-05:00"
}

Response

201 Created
{
  "success": true,
  "data": {
    "action": "created",
    "pago": {
      "external_id": "PAGO-99881",
      "deuda_external_id": "CRED-000123",
      "monto": 120000,
      "asignaciones": [
        {
          "cuota_external_id": "CUO-0007",
          "numero": 7,
          "monto": 80000
        },
        {
          "cuota_external_id": "CUO-0008",
          "numero": 8,
          "monto": 40000
        }
      ]
    },
    "saldo_pendiente": 750000,
    "monto_sin_asignar": 0
  }
}
Los sobrepagos se aceptan y el remanente aparece en monto_sin_asignar. Los pagos nuevos sobre deudas resueltas se rechazan. Un pago externo no genera un webhook de vuelta al ERP.
POST/cartera/deudas/{external_id}/resolvercartera:write

Resolver y detener la cobranza

Marca una deuda como pagada, cancelada o castigada y cancela cuotas y recordatorios abiertos.

Request

JSON
{
  "status": "written_off",
  "reason": "Castigo aprobado por el ERP"
}

Response

200 OK
{
  "success": true,
  "data": {
    "deuda": {
      "external_id": "CRED-000123",
      "saldo_pendiente": 750000,
      "status": "written_off"
    }
  }
}
Estados permitidos: paid, cancelled y written_off.

Boty → ERP

Webhook debt.payment_received

Se envía cuando un pago Wompi o manual se origina dentro de Boty para una deuda sincronizada. Configúralo en el portal y valida la firma HMAC con el cuerpo crudo.

Headers
X-Botyconnect-Event-Id: evt_x8k2m9p4q7w1n5r3t6y0u2i4
X-Botyconnect-Event: debt.payment_received
X-Botyconnect-Timestamp: 1786971731
X-Botyconnect-Signature: sha256=<hmac>
Payload
{
  "id": "evt_x8k2m9p4q7w1n5r3t6y0u2i4",
  "event": "debt.payment_received",
  "created_at": "2026-08-17T19:02:11Z",
  "data": {
    "deuda_external_id": "CRED-000123",
    "pago": {
      "boty_payment_id": "bpay_981",
      "external_id": null,
      "transaction_id": "wompi-transaction-123",
      "monto": 80000,
      "moneda": "COP",
      "metodo": "wompi",
      "pagado_en": "2026-08-17T19:02:10Z"
    },
    "saldo_pendiente": 790000,
    "status": "partial"
  }
}
  • Firma: sha256=HMAC(signing_secret, timestamp + "." + raw_body).
  • Deduplica por X-Botyconnect-Event-Id.
  • Responde 2xx rápido; Boty reintenta 5 veces con backoff.

Errores que debes manejar

HTTPCódigoQué hacer
401unauthorizedRevisa Authorization y que la API key esté activa.
403forbidden_scopeCrea o rota una key con el scope requerido.
404account_not_found / debt_not_foundVerifica account_id, external_id y tenant.
409debtor_identity_conflictDocumento y teléfono apuntan a personas distintas; corrige el ERP.
409payment_external_id_conflictNo reutilices el ID de un pago con otro monto o deuda.
409payment_currency_mismatchEnvía la misma moneda de la deuda.
409debt_not_payableNo envíes pagos nuevos para una deuda ya resuelta.
422validation_failedCorrige los campos detallados en error.details.
429rate_limitedReintenta con backoff y respeta Retry-After cuando venga.

Checklist para salir a producción

  • ✓Guardar API key y signing secret en un gestor de secretos.
  • ✓Usar external_id estable e inmutable para deudas, cuotas y pagos.
  • ✓Enviar external_version creciente en cada cambio de deuda.
  • ✓Persistir Idempotency-Key para poder reintentar tras timeouts.
  • ✓Validar HMAC sobre el raw body antes de parsear el webhook.
  • ✓Deduplicar webhooks por Event-Id y responder 2xx rápidamente.
  • ✓Probar carga inicial con un lote pequeño antes de enviar hasta 500.
  • ✓Conciliar periódicamente una muestra con GET /cartera/deudas/{external_id}.