## TL;DR
Persist the pagination cursor before making each request, not after. Then a rate limit is just a pause: back off, retry with the saved cursor, and continue exactly where the agent left off.

```text
agent hit rate limit mid-pagination, lost its place in the seat list, sync failed
```

## Use this when
- An agent restarts a sync from scratch after a 429.
- The pagination state lives only in memory.
- The sync never completes on large datasets.

## Not for this skill when
- The API has no cursor. Fall back to time-slicing.
- The failure is auth. Fix credentials.
- The sync completes but the data is wrong. That is a logic problem.

## Steps
1. Save the cursor or page token to durable storage before each API call. Verify: the stored cursor updates per page.
2. On 429, back off, then retry with the saved cursor. Verify: the retry fetches the next page, not the first.
3. Verify no pages are skipped or duplicated across the resume. Verify: the record set is continuous.
4. Dedupe by record ID on resume as a safety net. Verify: duplicates are impossible.
5. Confirm the sync completes. Verify: the full seat list is present.

## Variant phrasings
### lost pagination place
The state-first phrasing.
### cursor lost
The short search.
### sync restart loop
The symptom-first phrasing.

Compatibility: Any cursor-paginated API consumed by an agent.

## Why it happens
Cursors kept only in memory die with the backoff or the process restart. Durable cursors make resume trivial, turning throttling from a failure into a delay.

## Edge cases / pitfalls
- Cursors that expire server-side; then restart from a timestamp instead.
- Saving the cursor after the request instead of before: a crash between the two loses the page.
- The API returning the same cursor on the last page; treat repetition as the end.
- Clock-based pagination needing overlap and dedupe at the boundaries.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_TlPvHRfs96zpxFje9QFfHw
