## TL;DR

Pass the after cursor back to Zendesk exactly as the API returned it, with no decoding, trimming, or re-encoding in between. The cursor is an opaque base64 string and even small changes (stripped padding, mangled plus signs) make it invalid. Return it verbatim.

```text
zendesk API error: after parameter is not valid base64 in cursor pagination
```

## Steps

1. Capture the cursor string straight from the API response and store it untouched. Expected: you have the raw cursor value with its padding intact.

2. Search your code for any place that decodes, trims, splits, or re-encodes the cursor before sending it back. Expected: you find the transformation that corrupts it, or confirm there is none.

3. Remove the transformation so the stored cursor goes back into the after parameter byte for byte. Expected: the sent value matches the received value exactly.

4. Check your HTTP client does not mangle the cursor in transit: some clients turn plus signs into spaces if the value is not properly encoded in the query string. Expected: the value arriving at Zendesk is the same string you sent.

5. Re-run the paginated request with the verbatim cursor. Expected: Zendesk accepts the cursor and returns the next page.

## Use this when

- Zendesk returns exactly "after parameter is not valid base64".
- Pagination worked once and broke after you added cursor caching or logging.
- The cursor passes through string processing before reuse.

## Not for this skill when

- Credentials are wrong (authentication fails before pagination runs).
- A filter or sort parameter is invalid (that error names the parameter).
- The base64 error comes from a different API with its own cursor format.

## Variant phrasings

- Zendesk after cursor not valid base64
- Zendesk cursor pagination base64 error
- Zendesk page after invalid base64

## Why it happens

Zendesk's after cursor is an opaque base64 blob that only Zendesk can read. Generated clients treat it like a meaningful string: they strip the trailing padding, run it through a URL decoder twice, or log it through a sanitizer that alters characters. The corrupted string is no longer valid base64, and the API rejects it.

## Edge cases

- Padding characters at the end of base64 are load-bearing; dropping them is the most common corruption.
- If you persist cursors in a database, use a plain text column; JSON or CSV serializers rarely harm base64, but custom sanitizers do.
- A cursor from one endpoint (say tickets) is not valid on another (say users); keep cursors scoped to the endpoint that issued them.

## Provenance

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