Debt) es un cargo puntual a un deudor conocido: un importe fijo que se cobra a una persona o entidad identificada, con una fecha de vencimiento y medios de pago configurables. Es el caso de uso más común de la API.
Tú indicas quién paga, cuánto y cuándo vence. TapiPay resuelve internamente toda la complejidad (tu organización, las modalidades y los datos internos del sistema de cobranzas) y te devuelve un contrato limpio con la URL de pago lista para compartir.
Cuándo usar una deuda
Deuda
Un cobro único a alguien que conoces: una factura, una cuota, un servicio puntual.
Suscripción
Si el cobro se repite en el tiempo (mensualidades, cuotas).
Liga de pago
Si no conoces al deudor de antemano (donaciones, ventas sueltas).
Crear una deuda
Para crear una deuda necesitas, como mínimo, identificar al deudor, el monto y la fecha de vencimiento. El header opcionalIdempotency-Key se usa como externalRequestId de la deuda, y el debtId resultante es debt_<key> (en el ejemplo, debt_INV-2026-001). Si no lo envías, el backend genera el externalRequestId. Ver Idempotencia.
Identificar al deudor
Debes enviar uno de estos dos campos (no ambos, no ninguno):
Ver Contactos para el detalle del deudor reutilizable.
Un contacto puede tener más de un identificador. Si lo referencias por uno secundario, la deuda se crea con su identificador principal y
contact.externalClientId en la respuesta devuelve ese valor, no el que enviaste.Campos principales
number
requerido
Monto en pesos, con hasta 2 decimales (mínimo
0.01). Por ejemplo, 1500.50 equivale a $1,500.50 MXN.string
requerido
Fecha de vencimiento en formato
YYYY-MM-DD. Debe ser una fecha de calendario válida (2026-02-30 devuelve 400). No se valida que sea futura.string
predeterminado:"MXN"
Código de moneda. Valores permitidos:
MXN, ARS, PEN, COP, CLP, USD. Default MXN.string
Descripción visible para el deudor. Debe ser un string (otro tipo devuelve
400).string
ID de un producto existente en Tapi, con formato
prd_<número> (por ejemplo, prd_12985). Otro formato devuelve 400 INVALID_REQUEST. Excluyente con externalProductId (enviar los dos devuelve 400); no crea productos. Ver Productos.string
Tu identificador de un producto existente. Excluyente con
productId; no crea productos. No admite los caracteres ', ", \, ; (400).boolean
predeterminado:"true"
Habilita pagos parciales. Con
true, la deuda pasa a PARTIALLY_PAID hasta saldarse. Solo acepta true o false literal: "true", 1, etc. devuelven 400 con details[].boolean
predeterminado:"true"
Si es
false, la deuda no puede pagarse después del dueDate. Solo acepta true o false literal, igual que allowPartialPayments.object
Datos propios de tu sistema que quieras guardar en la deuda. Debe ser un objeto plano (un escalar, como un string o un número, devuelve
400) y no puede usar las claves reservadas que TapiPay escribe internamente: description, paymentMethods, productName, externalProductId, debtExpirationDate, overduePayment, allowPartialPayments, recurringDebt, debtReference. Si aparece alguna, la API responde 400 INVALID_REQUEST con details[].field = additionalData.La deuda no declara medio de pago: el cobro automático lo gobierna el medio de pago default que cada usuario registra una sola vez. Referenciar un producto (
productId/externalProductId) es lo que activa esa posibilidad. Los campos paymentMethods y autopay aplican solo a suscripciones. Ver Débito automático para el detalle completo.Nunca envías ni recibes datos internos del sistema (organización, modalidades,
generationData). Trabajas solo con conceptos de negocio.La respuesta
La respuesta de creación y de consulta incluyepaymentUrl (la URL lista para compartir con tu deudor; viene en null solo si falla la integración con el portal) y amountPaid (el acumulado pagado). La creación también incluye autopay (si el cobro automático quedó activo) y, cuando es false, el motivo en autopayReason. Si la deuda no referencia un producto, el motivo es NO_PRODUCT. Ver Débito automático.
debtIdes siempredebt_+externalRequestId.descriptionse devuelve en la creación y en las lecturas (GET /debts/{id},GET /debts) cuando la deuda tiene una; si no, el campo no viene.contact.contactIdtrae el prefijocon_, también cuando el contacto se crea en línea.- Las fechas
date-timevienen en UTC con milisegundos yZ. Ver Convenciones de la API.
Deep link de pago
ElpaymentUrl es un deep link que apunta directo a esa deuda puntual. Es una URL opaca: compártela tal cual con tu deudor, no la parsees ni la construyas a mano (su formato puede cambiar). Las deudas generadas por una suscripción también traen su propio deep link (lo ves en GET /subscriptions/{id}/debts).
Ciclo de vida
Consultar y listar
GET /debts/{id} acepta el debtId (debt_...) o el externalRequestId sin prefijo. También devuelve deudas canceladas (status: CANCELLED).
GET /debts devuelve tus deudas de la más reciente a la más antigua, paginadas con page y limit (ver Convenciones de la API). No incluye deudas canceladas: para leer una cancelada, usa GET /debts/{id}.
Regla de fechas de createdAtFrom y createdAtTo
Regla de fechas de createdAtFrom y createdAtTo
- Aceptan una fecha (
YYYY-MM-DD) o un date-time RFC 3339. Otro formato devuelve400. - Una fecha sola cubre el día UTC completo, incluido en los dos extremos:
createdAtFrom=2026-09-24empieza a las00:00:00.000ZycreatedAtTo=2026-09-24termina a las23:59:59.999Z. Con la misma fecha en los dos, obtienes las deudas de ese día. - Un date-time se convierte a UTC y la precisión del filtro es diaria: se incluye el día UTC completo que lo contiene. Un
createdAtToexactamente a las00:00:00Zno incluye ese día. - Sin
createdAtTo, el rango llega hasta hoy. UncreatedAtFromfuturo sincreatedAtTodevuelve una lista vacía. createdAtFromposterior acreatedAtTodevuelve400.
Actualizar y cancelar
Actualizar (PATCH /debts/{id})
Actualizar (PATCH /debts/{id})
Solo se puede actualizar una deuda en estado
PENDING. Intentarlo en otro estado, incluida una deuda cancelada, devuelve 422 BUSINESS_RULE_VIOLATION.Campos editables: amount y dueDate. Envía al menos uno: un body vacío o cualquier otro campo devuelve 400 INVALID_REQUEST. dueDate va en formato YYYY-MM-DD y debe ser una fecha de calendario válida. companyCode en el body se toma como contexto, no como campo a modificar.El PATCH no modifica allowPartialPayments. La respuesta trae dueDate como YYYY-MM-DD y amountPaid con el monto pagado actual.Cancelar (POST /debts/{id}/cancel)
Cancelar (POST /debts/{id}/cancel)
Se puede cancelar una deuda en estado
PENDING, PARTIALLY_PAID u OVERDUE. No se puede cancelar una deuda ya PAID o CANCELLED: cancelarla por segunda vez devuelve 422 BUSINESS_RULE_VIOLATION.El endpoint no lleva body (si envías uno, se ignora). La deuda cancelada se sigue leyendo con GET /debts/{id}, pero ya no aparece en GET /debts.Errores
Además del catálogo general, estas son las causas más comunes de error en los endpoints de deudas y elerror.code que devuelve cada una. El error.message es informativo y puede cambiar: decide tu lógica con el status, error.code y error.details[].field, no con el texto.
Algunos mensajes reales, solo como referencia:
Cuando la falla no es de validación, la API conserva el status real en lugar de convertirlo siempre en
500, así que también puedes recibir un 409 RESOURCE_CONFLICT o un 422 BUSINESS_RULE_VIOLATION fuera de los casos de la tabla. Estos errores no traen error.details, porque no señalan un campo puntual de tu payload.
Endpoints
Pruébalo en el API Reference
Explora cada endpoint con su playground interactivo.

