Revisión del contrato de la API
Esta versión hace más estricta la validación de entrada y corrige varias respuestas para que coincidan con lo documentado. Revisa primero la lista de cambios que pueden afectar tu integración.
Cambios que pueden afectar tu integración
Son cambios en los que una petición que antes pasaba (o daba5xx) ahora devuelve 4xx, o en los que cambia un valor de la respuesta que tu código podría estar leyendo.- Booleanos estrictos en
POST /v2/debtsyPOST/PATCH /subscriptions:allowOverduePayment,allowPartialPayments,autopayyenforcePaymentOrderaceptan solotrue/false."true",1, etc. devuelven400condetails[].descriptiondebe ser string (400). Ver Convenciones de la API. additionalDataenPOST /v2/debts,POST /payment-linksyPOST/PATCH /subscriptions: debe ser un objeto plano y no puede usar claves reservadas (description,paymentMethods,productName, etc.). Si no,400. Ver Convenciones de la API.POST /payment-links: unexternalClientIdque no corresponde a un contacto devuelve422 BUSINESS_RULE_VIOLATION(antes se creaba la liga igual). Ver Ligas de pago.POST/PATCH /payment-links:expiresAtdebe ser un date-time RFC 3339 (2026-12-31 23:59o solo fecha devuelven400). En elPATCH,expiresAt: nulldevuelve400(antes500; las ligas siempre vencen),metadatanullo que no sea objeto devuelve400ydescriptionvacía devuelve400. Ver Ligas de pago.PATCH /subscriptions/{id}: valida tipos, el enum depaymentMethodsy la exclusión entreautopay: trueypaymentMethods(400). Una suscripciónCANCELLEDoENDEDdevuelve422(antes200). Ver Suscripciones.POST /subscriptions:intervalUnitdistingue mayúsculas (MONTHdevuelve400) y, si la programación es inválida, no se crea el producto ni el contacto en línea. Ver Suscripciones.PATCH /contacts/{id}:phones: []devuelve400(antes200sin efecto). Ver Contactos.GET /contacts:identifieryexternalClientIdcon valores distintos devuelven400. Ver Contactos.GET /products:activedistinto detrue/falsedevuelve400(antes se leía comofalse). Ver Productos.GET /payment-links:createdAtFrom/createdAtTocon formato inválido devuelven400(antes se comparaban como texto). Ver Ligas de pago.GET /subscriptions:externalClientIdahora filtra (antes se ignoraba y devolvía suscripciones de otros contactos). Vacío o en blanco devuelve400. Ver Suscripciones.GET /debts/{id},PATCH /debts/{id},POST /debts/{id}/cancel: una deuda cancelada se puede leer (200,status: CANCELLED); cancelarla otra vez o hacerlePATCHdevuelve422(antes404). Ver Deudas.POST /v2/debts: nuevo valorautopayReason: "NO_PRODUCT". Si validasautopayReasoncontra una lista cerrada, agrégalo. Ver Débito automático.- Fechas en contactos, deudas y pagos de ligas: los
date-timese devuelven en UTC con milisegundos yZ(2026-09-24T21:09:41.835Z). Antes podían venir sin zona, con+00:00o con microsegundos. Ver Convenciones de la API. PATCH /debts/{id}:dueDateen la respuesta pasa aYYYY-MM-DD(antes date-time). Ver Deudas.POST /payment-linkssin deudor:paymentUrlpasa a ser la URL corta (ya no contiene elidentifierValue) y puede sernullsi falla su generación. Trátala como una URL opaca. Ver Ligas de pago.- Ligas de pago, todas las respuestas:
expiresAtse devuelve siempre en UTC con milisegundos yZ(2026-12-31T23:59:59.000Z), aunque se haya enviado con offset (-06:00). Las ligas antiguas guardadas con fecha sola (2026-12-01) salen como el inicio de ese día UTC (2026-12-01T00:00:00.000Z). Ver Ligas de pago. - Ligas de pago sin llave externa, todas las respuestas:
externalPaymentLinkIdesnullcuando la liga se creó sinexternalPaymentLinkIdni headerIdempotency-Key(antes devolvía un valorplk_<uuid>igual alpaymentLinkId). Ver Ligas de pago. GET /debtsyGET /payment-links/{id}/payments:createdAtTocomo fecha sola ahora incluye ese día (antes filtraba hasta su inicio). Si enviabas el día siguiente para compensar, ahora recibes un día de más.createdAtFromposterior acreatedAtTodevuelve400con el mensajecreatedAtFrom must be earlier than or equal to createdAtTo.Ver Deudas.
Correcciones
PATCH /debts/{id}yPATCH /subscriptions/{id}: elPATCHya no reiniciaallowPartialPaymentsafalse, yamountPaidsale correcto (nonull). Ver Deudas.GET /debts/{id}yGET /debts:descriptionaparece en las lecturas. Ver Deudas.POST /v2/debtsyPOST /subscriptions:contact.contactIdviene con el prefijocon_también cuando el contacto se crea en línea. Ver Débito automático.GET /contacts:identifierfiltra, ycontactCodeacepta el prefijocon_. Ver Contactos.- Contactos: los contactos sin email creados en línea devuelven
email: null(antes el texto"null"), también al leer los ya existentes. Ver Contactos. GET /payment-links?externalPaymentLinkId=: deja de devolver500. Ver Ligas de pago.POST /payment-links: unexternalPaymentLinkIdrepetido devuelve409sin crear la deuda. Una liga con deudor ya no falla con500si la configuración del portal no responde. Ver Ligas de pago.PATCH /payment-links/{id}:expiresAtactualiza también el vencimiento de la deuda de la liga. Si esa deuda ya fue cancelada, se actualiza solo la liga (antes elPATCHfallaba). Ver Ligas de pago.- Respuesta de ligas de pago: siempre trae
externalPaymentLinkId,expiresAt,successUrl,metadata,identifierValue,contactyproduct, connullcuando no hay valor. Ver Ligas de pago. POST /products: devuelve lo que se guardó (timestamps,externalProductId,active) en lugar de repetir el request. Ver Productos.PATCH /products/{id}:active: falsedesactiva el producto; renombrar a un nombre ya usado, también por un producto inactivo, devuelve409(antes500); tipos inválidos devuelven400(antes500). Ver Productos.POST /subscriptions:paymentUrlya no esnull, yscheduling.billingDayse infiere destartDate(paramonthyyear). Ver Suscripciones.GET /debtsyGET /payment-links/{id}/payments:createdAtFrom/createdAtToaceptan date-time RFC 3339 además de fecha. Con la misma fecha en los dos devuelven las deudas de ese día (antes400), y uncreatedAtFromfuturo sincreatedAtTodevuelve una página vacía (antes400). Ver Deudas.PATCHde contactos, productos, ligas de pago, suscripciones y deudas:companyCodeen el cuerpo se toma como contexto y ya no se rechaza como campo no editable. Ver Convenciones de la API.POST /v2/debts(lote): cada error dedetails[]traefield. Ver Débito automático.PATCH /debts/{id}: las fechas imposibles (2026-02-30) devuelven400. Ver Deudas.POST /v2/debts,POST /payment-linksy suscripciones:additionalDataenviado como objeto se guarda en la deuda (antes se perdía en deudas y ligas). Ver Convenciones de la API.PATCH /subscriptions/{id}: si falla la actualización de alguna deuda de la suscripción, la respuesta es207conerror.code: PARTIAL_UPDATE(antes500 INTERNAL_ERROR). La suscripción queda actualizada. Ver Suscripciones.paymentUrlen deudas, suscripciones y ligas de pago: si tu compañía no tiene configurados los links privados,paymentUrlya no viene ennull: se devuelve la URL del portal de tu compañía. Trátala igual como una URL opaca. Ver Deudas.

