Paginación

limit, offset y total — y cómo recorrer una lista sin perder filas.

Todos los endpoints de listado paginan igual, con limit y offset en la query string.

curl "https://api.trama.so/v1/customers?limit=50&offset=100" \
  -H "Authorization: Bearer $TRAMA_API_KEY"
ParámetroDefaultMáximo
limit25100
offset0

Pedir más de 100 no se recorta en silencio: da un 400 con VALIDATION_FAILED. Es a propósito — un request que devuelve menos filas de las que pediste sin decírtelo es la forma en que una integración pierde datos sin que nadie se entere.

La forma de la respuesta

{
  "data": [ /* … */ ],
  "pagination": { "limit": 50, "offset": 100, "total": 1284 }
}

total es el conteo de los filtros que mandaste, no de la organización entera. Es lo que te deja saber si hay otra página que pedir, sin tener que pedirla y recibir un array vacío.

async function traerTodo(path) {
  const items = [];
  let offset = 0;
  for (;;) {
    const res = await fetch(`https://api.trama.so${path}?limit=100&offset=${offset}`, {
      headers: { Authorization: `Bearer ${process.env.TRAMA_API_KEY}` },
    });
    const { data, pagination } = await res.json();
    items.push(...data);
    offset += pagination.limit;
    if (offset >= pagination.total) return items;
  }
}

Los offsets se te mueven abajo de los pies. Una lista es una consulta viva, no una foto: si mientras la recorrés se crean o reordenan filas —y en el catálogo, editar un producto lo reordena— una fila puede saltar de página y la vas a ver dos veces o ninguna.

Si estás sincronizando en vez de mirando, no cuentes con haber recorrido todas las páginas limpiamente. Indexá por el id del recurso y volvé a recorrer cada tanto, en vez de asumir que una pasada quedó completa.

No hay paginación por cursor, y es una decisión y no un olvido: un cursor estable necesita un orden que hoy no podemos prometer en todas las listas. Si tu catálogo o tu base de clientes crece hasta que esto duele, contanos: es de las cosas que se versionan, no que se parchan.

En esta página