Pagination

List endpoints return cursor pagination instead of page numbers, so reordering rows mid-pagination never skips or duplicates entries.

The page envelope

json
{
  "data": [ { "id": "file_…", "filename": "a.txt" }, { "id": "file_…", "filename": "b.txt" } ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "eyJpZCI6InRpbWVf…"
  }
}

Requesting the next page

Pass the opaque nextCursor as cursor:

http
GET /v1/files?limit=20&cursor=eyJpZCI6InRpbWVf…

When pagination.hasMore is false, the cursor is null and you're done.

Parameters

ParamTypeDefaultNotes
limitint201–100
cursorstringopaque; pass in as returned
sortBystringcreatedAtcreatedAt / updatedAt / filename / size
orderstringdescasc / desc

Cursors are tied to the sort order — change sortBy/order on page 2 and results may not align.

Raw

bash
PAGE_JSON=$(curl -s "https://api.apulodi.com/v1/files?limit=20" \
  -H "Authorization: Bearer $APULODI_API_KEY")

NEXT=$(echo "$PAGE_JSON" | jq -r '.pagination.nextCursor')

curl -s "https://api.apulodi.com/v1/files?limit=20&cursor=$NEXT" \
  -H "Authorization: Bearer $APULODI_API_KEY"

In the SDK

The SDK returns the same envelope:

ts
const page = await apulodi.files.list({ path: "users", limit: 50 });
if (page.pagination.hasMore) {
  const next = await apulodi.files.list({
    path: "users",
    limit: 50,
    cursor: page.pagination.nextCursor ?? undefined,
  });
}

Or let the SDK follow the cursors for you:

ts
for await (const file of apulodi.files.iterate({ path: "users" })) {
  console.log(file.filename, file.size);
}

The iterator requests one page at a time, buffering nothing between yields.

Next: SDK — Installation & configuration.