Paginación y filtros
Cómo paginar cada listado del API, qué filtros acepta cada recurso y cómo traer muchos recursos en una sola llamada.
La paginación es específica de cada recurso. No existe un contrato único para todos los listados. Antes de programar un listado, revisa el bloque meta que devuelve ese endpoint: ahí está la verdad.
Esta página describe el modelo de envíos, que es el más completo, y luego el modelo simple que usan los demás recursos.
Pagina envíos por página (modo por defecto)
GET /v1/shipments usa paginación por número de página.
GET /v1/shipments?page=1&limit=50
| Parámetro | Por defecto | Máximo | Descripción |
|---|---|---|---|
page |
1 | — | Número de página |
limit |
20 | 100 | Elementos por página |
{
"success": true,
"data": ["..."],
"meta": {
"pagination": {
"mode": "offset",
"page": 1,
"limit": 50,
"total": 1234,
"totalPages": 25,
"hasNextPage": true,
"hasPrevPage": false
}
}
}
Avanza mientras hasNextPage sea true.
Pagina por cursor cuando el volumen crece
En listados grandes, el conteo por página se vuelve caro. Activa el cursor con useCursor=true.
GET /v1/shipments?useCursor=true&limit=50
GET /v1/shipments?useCursor=true&limit=50&cursor=eyJjcmVhdGVkQXQiOi...
useCursor solo acepta true o false. Omítelo o mándalo en false para paginar por offset.
{
"success": true,
"data": ["..."],
"meta": {
"pagination": {
"mode": "cursor",
"limit": 50,
"hasNextPage": true,
"nextCursor": "eyJjcmVhdGVkQXQiOi..."
}
}
}
El nextCursor es opaco. Pásalo tal cual, sin decodificarlo ni construirlo tú. Detente cuando hasNextPage sea false.
let cursor;
do {
const url = new URL("https://api.sendit.mx/v1/shipments");
url.searchParams.set("useCursor", "true");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const { data, meta } = await fetch(url, {
headers: { "X-API-Key": process.env.SENDIT_API_KEY },
}).then((r) => r.json());
process(data);
cursor = meta.pagination.hasNextPage ? meta.pagination.nextCursor : null;
} while (cursor);
Pagina los demás recursos
El resto de los listados paginados usa un meta plano, sin el nivel pagination y sin cursor:
GET /v1/wallet/transactions?page=2&limit=50
{
"success": true,
"data": ["..."],
"meta": { "page": 2, "limit": 50, "total": 340, "totalPages": 7 }
}
Así funcionan monedero, órdenes, productos y facturas. Algunos recursos no paginan del todo. En todos los casos, el meta de la respuesta manda.
Filtra los resultados
Los filtros son parámetros con nombre. No hay operadores tipo campo[gte], ni sort=, ni fields=, ni expand[]. El conjunto exacto depende del recurso.
Para GET /v1/shipments:
| Parámetro | Descripción |
|---|---|
status |
Un solo estado |
statuses |
Varios estados, separados por coma. Tiene precedencia sobre status si mandas ambos |
carrierCode |
Paquetería |
trackingNumber |
Coincidencia parcial del número de guía |
externalId |
Coincidencia exacta |
search |
Texto libre sin distinguir mayúsculas, sobre número de guía, externalId y destino (nombre de contacto, ciudad, estado) |
createdFrom |
Creados en esa fecha o después (inclusivo) |
createdTo |
Creados antes de esa fecha (exclusivo) |
GET /v1/shipments?status=DELIVERED&carrierCode=DHL
GET /v1/shipments?statuses=DELIVERED,RETURNED
GET /v1/shipments?search=FEDMX123
GET /v1/shipments?createdFrom=2026-01-01&createdTo=2026-04-01
El rango de fechas es semiabierto: incluye createdFrom y excluye createdTo. Así puedes encadenar meses sin duplicar registros.
Ordena
El orden es fijo: createdAt descendente, con el id como desempate. No hay parámetro de ordenamiento personalizado en los listados de envíos.
Trae muchos recursos conocidos de una sola vez
Si ya tienes los IDs, evita paginar. Los endpoints bulk traen hasta 100 recursos en una llamada:
POST /v1/bulk/shipments/fetch
{ "ids": ["shp_aaa", "shp_bbb", "shp_ccc"] }
Los errores vienen por elemento. Un ID inexistente no tumba el lote completo. Los cuatro endpoints bulk (envíos, órdenes, rastreo y validación de direcciones) están documentados junto a lotes.