API Pagination Debugging Guide

Link headers, page size, cursor pagination, offsets, missing results and duplicate rows. Last updated August 31, 2026.

Pagination bugs usually appear as missing rows, duplicate rows, incomplete exports or unstable API clients. GitHub's REST API pagination guide explains that paginated responses may include a link header with URLs for next, previous, first and last pages, and that some endpoints support a per_page query parameter. See GitHub Docs. This page generalizes the debugging workflow for APIs that use page, offset or cursor pagination.

Find the pagination style

StyleTypical parametersCommon failure
Page-basedpage, per_pageClient stops too early or assumes the wrong page size.
Offset-basedoffset, limitRows shift while data changes during export.
Cursor-basedafter, before, cursorClient treats opaque cursors like sortable IDs.
Time-basedsince, updated_afterBoundary timestamps create duplicates or gaps.

Inspect headers and body

curl -i "https://api.example.com/items?page=1&per_page=50"
curl -sS -D page1.headers -o page1.json "https://api.example.com/items?page=1&per_page=50"
curl -sS -D page2.headers -o page2.json "https://api.example.com/items?page=2&per_page=50"

Missing results checklist

Duplicate result checklist

page 1 last id:
page 2 first id:
sort field:
sort direction:
created/updated during export:
cursor reused:
retry duplicated page:
client de-dup key:

Client loop pattern

next_url = first_url
while next_url:
    response = fetch(next_url)
    save response.items
    next_url = response.links.next or response.body.next_cursor
    stop if next_url was already visited

Treat pagination cursors as opaque. A cursor is a server-provided bookmark, not a number the client should invent, sort or edit unless the API documentation explicitly says so.

Related: curl API Debugging Cheatsheet, API Rate Limit Debugging, OpenAPI Contract Checklist, JSON Diff.