Пагинация
Курсорная пагинация списков — устойчива к новым записям, без номеров страниц.
GET /v1/orders возвращает заказы от новых к старым, по одной странице:
200 OK
{
"items": [ { "id": "0192f1b2-…", "external_id": "SHOP-100245", "status": "to_dropoff" } ],
"next_cursor": "YzF8MDE5MmYxYjItNmQ0ZS03YTEwLWIzYzItOGUxZjBkOWE0YzU3"
}| Параметр | Что это |
|---|---|
limit | размер страницы, 1–200, по умолчанию 50 |
cursor | next_cursor предыдущей страницы; для первой не передавайте |
status, from, to, point_id | фильтры — одинаковые на всех страницах |
На последней странице next_cursor равен null. Курсор непрозрачен: не разбирайте и не собирайте его сами —
изменённый курсор даёт 400 invalid_cursor. Новые заказы, созданные во время обхода, не сдвигают страницы
(keyset-пагинация).
async function* allOrders(params = {}) {
let cursor;
do {
const q = new URLSearchParams({ ...params, limit: "200", ...(cursor ? { cursor } : {}) });
const page = await fetch(`https://partner.sapamoto.kz/v1/orders?${q}`, {
headers: { Authorization: `Bearer ${process.env.SAPA_KEY}` },
}).then((r) => r.json());
yield* page.items;
cursor = page.next_cursor;
} while (cursor);
}
for await (const order of allOrders({ from: "2026-10-24T00:00:00+05:00" })) console.log(order.external_id);def all_orders(**filters):
cursor = None
while True:
params = {**filters, "limit": 200, **({"cursor": cursor} if cursor else {})}
page = requests.get("https://partner.sapamoto.kz/v1/orders", params=params,
headers={"Authorization": f"Bearer {KEY}"}, timeout=10).json()
yield from page["items"]
cursor = page["next_cursor"]
if not cursor:
return