Skip to content
Back to skills

Rest Api Pagination Patterns

ASecurity

REST API pagination for inbound and outbound integrations: Salesforce QueryMore, cursor-based, offset-based, Link header, page-size tuning, rate limit interaction. NOT for REST CRUD or Composite — use integration/rest-api-patterns. NOT for GraphQL pagination — use integration/graphql-api-patterns.

  • 15 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
ai-agentsgospringgitapiperformancedocumentation

Works with

  • cursor
  • api

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add PranavNagrecha/AwesomeSalesforceSkills --skill rest-api-pagination-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rest Api Pagination Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rest Api Pagination Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pranavnagrecha-rest-api-pagination-patterns/badge)](https://www.skillsdirectory.com/skills/pranavnagrecha-rest-api-pagination-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rest-api-pagination-patterns
description: "REST API pagination for inbound and outbound integrations: Salesforce QueryMore, cursor-based, offset-based, Link header, page-size tuning, rate limit interaction. NOT for REST CRUD or Composite — use integration/rest-api-patterns. NOT for GraphQL pagination — use integration/graphql-api-patterns."
category: integration
salesforce-version: "Spring '25+"
well-architected-pillars:
  - Performance
  - Reliability
tags:
  - rest
  - pagination
  - querymore
  - cursor
  - offset
  - link-header
triggers:
  - "salesforce querymore nextrecordsurl pagination apex callout"
  - "rest api cursor based vs offset pagination"
  - "link header pagination github style rfc5988"
  - "rate limit interaction with pagination loop"
  - "offset pagination drift on insert delete"
  - "batch size tuning for inbound rest integration"
  - "we're having issues with link header"
inputs:
  - Integration direction (inbound to Salesforce, outbound from Salesforce)
  - API style (cursor, offset, Link header, custom)
  - Total result magnitude
  - Rate limit profile
outputs:
  - Pagination loop pattern
  - Termination condition
  - Retry / rate-limit interaction
  - Volume test plan
dependencies: []
version: 1.1.0
author: Pranav Nagrecha
updated: 2026-05-19
---

# REST API Pagination Patterns

Activate when integrating with a paginated REST API — either consuming an external API from Apex or serving a paginated endpoint from Salesforce. Pagination mistakes cause three classic failures: infinite loops, missed records, and duplicate records due to concurrent writes between page fetches.

## Before Starting

- **Identify pagination style.** Cursor / Next-link / Offset / Link-header / Token-based — all have different termination semantics.
- **Plan termination.** Every pagination loop needs a safety cap (max iterations) plus the documented termination signal.
- **Respect rate limits.** Back off on 429; implement exponential backoff.

## Core Concepts

### Salesforce QueryMore (outbound to external consumer)

```
/services/data/v60.0/query?q=SELECT+Id+FROM+Account
→ { "done": true, "nextRecordsUrl": "/services/data/v60.0/query/01g...", "records": [...] }
```

Loop: fetch `nextRecordsUrl` until `done == true`.

### Cursor-based (opaque token)

Response includes a cursor string; pass back as `?cursor=<value>` until the server returns an empty cursor or explicit end-of-stream flag.

### Offset / limit

Classic `?offset=0&limit=100`. Simple but vulnerable to drift: records inserted/deleted between pages cause missed or duplicate rows.

### Link header (RFC 5988)

```
Link: <https://api/x?page=2>; rel="next", <https://api/x?page=10>; rel="last"
```

Parse headers; loop until no `rel="next"` present.

### Rate limit headers

`X-RateLimit-Remaining`, `Retry-After` — consult before issuing the next page.

## Common Patterns

### Pattern: QueryMore loop in Apex

```
HttpResponse resp = http.send(req);
Map<String,Object> body = (Map<String,Object>) JSON.deserializeUntyped(resp.getBody());
List<Object> all = new List<Object>();
all.addAll((List<Object>) body.get('records'));
while (body.get('done') == false) {
    String nextUrl = (String) body.get('nextRecordsUrl');
    HttpRequest r2 = new HttpRequest();
    r2.setEndpoint(base + nextUrl);
    // auth ...
    resp = http.send(r2);
    body = (Map<String,Object>) JSON.deserializeUntyped(resp.getBody());
    all.addAll((List<Object>) body.get('records'));
}
```

### Pattern: Cursor loop with safety cap

```
String cursor = null;
Integer safetyCap = 1000; // max pages
for (Integer i = 0; i < safetyCap; i++) {
    // fetch with cursor
    if (cursor == null || cursor == '') break;
}
if (i == safetyCap) throw new IntegrationException('Pagination safety cap hit');
```

### Pattern: Rate-limit-aware pagination

Check `X-RateLimit-Remaining`; if < threshold, sleep per `Retry-After` before next page. In Apex: use Queueable chaining for long-running paginations (cannot `Thread.sleep`).

## Decision Guidance

| Situation | Pagination style |
|---|---|
| Salesforce inbound data | QueryMore |
| Large stable dataset | Cursor |
| Small dataset, admin UI | Offset/limit |
| Complex filter with stable ordering | Cursor |
| Lots of concurrent writes | Cursor with created-since filter |

## Recommended Workflow

1. Identify the source API's pagination style from documentation.
2. Implement the loop with an explicit termination signal AND a safety cap.
3. For offset/limit: either confirm dataset is stable or add resume tokens.
4. Parse rate-limit headers; back off on 429.
5. For long paginations in Apex, chain Queueables — each handles one page batch.
6. Persist intermediate results in case of mid-stream failure.
7. Write integration test that mocks 3+ pages including empty-tail.

## Review Checklist

- [ ] Termination signal matches API spec
- [ ] Safety cap on page count (avoid infinite loops)
- [ ] Rate-limit headers honored
- [ ] Apex: long paginations chained via Queueable (callout limit: 100/transaction)
- [ ] Resume/checkpoint on mid-stream failure
- [ ] Test mocks multi-page and empty-tail
- [ ] No blind offset pagination on mutable data

## Salesforce-Specific Gotchas

1. **Apex has a 100-callout-per-transaction limit.** Paginating over thousands of pages requires Queueable chaining.
2. **QueryMore cursor expires after ~15 minutes.** Long paginations need restart logic if they straddle the expiry.
3. **`Test.setMock` supports only one response per request.** Multi-page tests need a mock class tracking call count.

## Output Artifacts

| Artifact | Description |
|---|---|
| Pagination helper Apex class | Reusable loop with safety cap |
| Rate-limit-aware http wrapper | Backoff + retry |
| Integration test fixtures | Multi-page mocks |

## Related Skills

- `integration/bulk-api-patterns` — for large-volume data operations
- `integration/rate-limit-handling` — backoff strategies
- `apex/apex-queueable-patterns` — chaining for long-running callouts

Files in this skill

  • SKILL.md5.9 KB
  • references/examples.md9.6 KB
  • references/gotchas.md8.3 KB
  • references/llm-anti-patterns.md3.4 KB
  • references/well-architected.md7.6 KB
  • scripts/check_rest_api_pagination_patterns.py2.9 KB
  • templates/rest-api-pagination-patterns-template.md643 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…