Vas a lograr leer correctamente una lista paginada, interpretar el formato de error de la API y entender los límites de uso de tu clave.

Paginación por cursor

Todo endpoint de lista (GET /v1/portfolios, /debtors, /debts, /calls, /payments, /promises, /campaigns) devuelve la misma forma:
  • limit: cuántos ítems pediste (o el default). Acepta de 1 a 100: 0 o un valor negativo vuelve al default (50) y uno mayor a 100 se recorta a 100, sin error. Uno que no sea numérico (limit=abc) sí rechaza el request, con 400 y validation_error. El default es 50.
  • pagination.hasMore: si true, hay más páginas.
  • pagination.nextCursor: un cursor opaco — no intentes interpretar su contenido ni construirlo a mano. Para la próxima página, mandalo tal cual como el parámetro cursor. Un cursor está atado al endpoint que lo emitió: usarlo contra otro recurso no devuelve un error, sino una página sin sentido.
Cuando hasMore es false, nextCursor es null y ya recorriste todo.

Orden de las listas

El orden no es configurable en v1 (no hay parámetro sort), y cada recurso usa un criterio estable para que avanzar con cursor nunca te salte ni te repita un ítem:

Filtros y valores por defecto

Cada lista acepta filtros propios (están en la pestaña Referencia), pero hay comportamientos que no se deducen del nombre del parámetro:

status: un valor o varios

  • Un solo valor: debts. Una lista separada por comas responde 400 validation_error.
  • Uno o varios separados por coma: debtors, calls, promises, campaigns (status=pending,partial). calls también acepta direction con dos valores (inbound, outbound).
Un valor que no existe responde 400 validation_error y el mensaje nombra el parámetro y los valores permitidos. Nunca devuelve una lista vacía.

from y to

Los dos recursos con rango de fechas los interpretan distinto, porque sus fechas se guardan distinto:
  • Llamadas: from/to se interpretan como fecha o fecha y hora ISO 8601. Si to viene sin hora (to=2026-01-31), se toma hasta el final de ese día en UTC.
  • Pagos: from/to se comparan como texto contra paymentDate, que puede venir como fecha (2026-01-31) o como fecha y hora (2026-01-31T14:45:00Z) según cómo se registró el pago. from=2026-01-01 incluye todo ese día; to=2026-01-31 deja afuera los pagos de ese día que tengan hora. Para incluirlos, mandá to=2026-01-31T23:59:59Z.
Un from o to que no sea una fecha ISO 8601 parseable (from=ayer) responde 400 con el código validation_error, en los dos recursos.
Lo mismo aplica a los campos de fecha en las respuestas: createdAt, updatedAt, connectedAt y demás timestamps reales siempre son fecha y hora (date-time). En cambio dueDate, issueDate, paymentDate, promiseDate y fulfillmentDate son columnas de texto que reflejan lo que se cargó: pueden ser solo fecha (YYYY-MM-DD) o fecha y hora. No asumas hora en esos campos; la Referencia describe, para cada uno, qué puede llegar a contener.

Formato de error

Cualquier error —4xx o 5xx— responde con el mismo sobre:
La API devuelve message en inglés, siempre: es para una persona leyendo logs, no para tu código. Ramificá la lógica de tu integración por code, nunca por message.
requestId identifica el request — incluilo si le escribís a soporte sobre un error puntual. Los errores de validación (validation_error) además pueden traer un array issues con el detalle de qué campo falló.

Códigos de error

Un GET /v1/debtors/:id sobre un deudor de otra organización responde 404 not_found, igual que si no existiera: la API pública nunca confirma que un recurso ajeno existe.

Tope de lotes de escritura

Los endpoints que aceptan varios ítems en un solo request tienen su propio tope, distinto del rate limit: POST /v1/portfolios/:id/debtors acepta hasta 500 deudores por lote y 5 MB de cuerpo. Superar cualquiera de los dos responde 413 payload_too_large. Un cuerpo de más de 6 MB cruza el límite general de Lambda y responde igual 413, pero con el sobre crudo de la plataforma, no el de la API (ver el detalle en Deudores).

Límite de uso (rate limit)

Cada clave tiene un límite de 300 unidades por minuto. Para casi toda la API, cada request cuesta 1 unidad: el límite es, en la práctica, de 300 requests por minuto. Cada respuesta trae dos headers con tu consumo:
La excepción es POST /v1/portfolios/:id/debtors, el endpoint de escritura masiva de deudores: ahí una sola request puede mover hasta 500 deudores con sus deudas, así que cobrarla como una unidad fija no acotaba nada. Ese endpoint cuesta 1 unidad cada 50 deudores del lote, con un mínimo de 1 unidad. Un lote de 500 deudores cuesta 10 unidades; un lote de 20 sigue costando 1. X-RateLimit-Remaining en la respuesta de ese endpoint ya refleja el cobro del lote entero, no de una unidad fija. Si superás el límite, la respuesta es 429 rate_limited con un header adicional:
Retry-After son los segundos que faltan para que se abra la próxima ventana. La ventana es fija (por minuto de reloj), no una ventana deslizante. En POST /v1/portfolios/:id/debtors, un lote que cruza el límite responde 429 después de haber sido cobrado: ese lote no se procesa, pero las unidades que consumió ya están descontadas de la ventana.

Cómo manejarlo

  • Mirá X-RateLimit-Remaining para frenar antes de pegar contra el límite, en vez de esperar al 429.
  • Ante un 429, esperá los segundos de Retry-After antes de reintentar — no hagas backoff exponencial sobre una ventana fija, sólo generás más espera de la necesaria.
  • Si tu integración necesita más de 300 req/min de forma sostenida, hablalo con tu contacto en Mozart antes de paralelizar requests para esquivar el límite.

Siguiente paso

Con paginación y errores cubiertos, andá a las guías de integración para los flujos de carga de cartera y pagos, o directo a la pestaña Referencia para el detalle de cada endpoint.