Back to Developer

Pagination

Cursor-based pagination for efficient, consistent list traversal.

How It Works

All list endpoints return a paginated response with a has_more field. When has_more is true, pass the last item's ID as starting_after to get the next page.

{
  "object": "list",
  "data": [ ... ],
  "has_more": true,
  "url": "/v1/stores/{storeId}/products"
}

Parameters

ParameterTypeDescription
limitintegerItems per page. Default 25, max 500.
starting_afterstringCursor for forward pagination. Pass the ID of the last item on the current page.
ending_beforestringCursor for backward pagination. Pass the ID of the first item on the current page.

Forward Pagination

Fetch the first page, then use starting_after with the last item's ID to get subsequent pages.

# First page
curl ".../products?limit=10"

# Next page (use last item's id)
curl ".../products?limit=10&starting_after=550e8400-..."

# Keep going until has_more is false

Backward Pagination

Use ending_before with the first item's ID on the current page to navigate backward.

# Previous page
curl ".../products?limit=10&ending_before=a1b2c3d4-..."

Auto-Paginate (TypeScript)

async function* paginate(url: string, apiKey: string) {
  let cursor: string | undefined;

  while (true) {
    const params = new URLSearchParams({ limit: '100' });
    if (cursor) params.set('starting_after', cursor);

    const res = await fetch(`${url}?${params}`, {
      headers: { 'x-api-key': apiKey },
    });
    const page = await res.json();

    for (const item of page.data) {
      yield item;
    }

    if (!page.has_more) break;
    cursor = page.data[page.data.length - 1].id;
  }
}

// Usage
for await (const product of paginate(baseUrl + '/products', key)) {
  console.log(product.name);
}