TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Read API Pagination URLs Without Losing Query Parameters

Practical insights, clear explanations, and useful ideas for understanding the web.

October 28, 20266 min read6 topics
How to Read API Pagination URLs Without Losing Query Parameters
Explore the details
#API pagination#URLs#HTTP#JavaScript#API integration#Security
October 28, 20266 min read

Pagination URLs can contain more than a page number: they may include filters, cursors, signatures, or other state the API needs to return the next results. This guide shows how to inspect those URLs, resolve relative links, and follow pagination without assuming every API uses the same parameter names.

Key Takeaways

  • Treat a server-provided next-page URL as an instruction to follow, not a template to rebuild.
  • Use a URL parser to inspect the path and query parameters; parameter names and pagination schemes vary by API.
  • Resolve relative links against the URL of the response that supplied them.
  • Avoid logging or sharing full pagination URLs: cursors and tokens may be sensitive.
  • Before sending credentials to a URL supplied by a response, check that its origin is trusted.

Recognize the pagination pattern

APIs commonly expose pagination in a few ways. These examples are illustrative; the parameter names and response formats are not universal.

Page numbers or offsets

A request might look like this:

https://api.example.test/v1/orders?page=3&per_page=25&status=open

Another API might use offset and limit, or nested names such as page[number]. Do not assume that page is the right parameter to increment—or that the API expects you to calculate the next value yourself.

Cursors

A cursor-based request might look like this:

https://api.example.test/v1/orders?limit=25&after=eyJvcmRlciI6IjEyMyJ9

The cursor is usually an opaque value. It may encode a position or other server-side state. Preserve it exactly and let the API tell you what cursor comes next; do not decode it, edit it, or substitute an incremented page number unless that API's documentation explicitly requires it.

A complete next-page URL

A response may include a URL in its body, for example under a field such as next, next_url, or links.next. A server-provided URL may already include filters and pagination state. Rebuilding it from selected parameters can drop information the API needs.

A Link response header

An API can instead return links in an HTTP Link header, for example:

Link: </v1/orders?cursor=abc&status=open>; rel="next", </v1/orders?cursor=xyz&status=open>; rel="last"

The link marked rel="next" identifies the next page. A header may contain multiple link values, and targets can be relative references. Do not parse a complex Link header by splitting blindly on commas: commas can occur inside quoted parameter values. Use a parser that supports the HTTP Link header syntax and the API's documented behavior.

Inspect a URL without assuming parameter names

JavaScript's URL and URLSearchParams let you examine the path and query without hard-coding a pagination scheme:

const url = new URL(
  "https://api.example.test/v1/orders?limit=25&status=open&after=abc123"
);

console.log(url.pathname); // /v1/orders

for (const [name, value] of url.searchParams) {
  console.log(name, value);
}

console.log(url.searchParams.getAll("status")); // ["open"]

getAll() matters because a query key can appear more than once. If your integration needs a particular value, follow the API's rules for repeated parameters rather than assuming there is only one.

Parsing is useful for inspection; it does not mean you should reconstruct a server-provided next link. Editing and serializing a URL can change its textual encoding or ordering even when the parameter values remain equivalent. If you must add an API-documented parameter, modify the parsed URL and avoid replacing unrelated parameters.

Resolve and follow a next URL

Relative references need a base URL. For a link returned with a response, use that response's URL as the base so paths such as ?cursor=next and ../orders?cursor=next resolve in the response's context.

The following example assumes the API returns a JSON object with a links.next field. Change that field access to match the API's actual response schema:

const response = await fetch("https://api.example.test/v1/orders?limit=25");

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const body = await response.json();
const nextReference = body.links?.next;

if (nextReference) {
  const nextUrl = new URL(nextReference, response.url);
  console.log(nextUrl.pathname);
  // Follow nextUrl according to the API's pagination and authentication rules.
}

Before following a returned URL with credentials, confirm it belongs to an origin you trust. Some APIs intentionally use more than one host, so build an allowlist from that API's documentation rather than assuming every next link must use the original host. Do not forward authorization headers to an untrusted origin.

Preserve parameters when you need to change one

If the API explicitly tells you to set a parameter, changing that parameter on a parsed URL retains the other query entries:

const url = new URL(
  "https://api.example.test/v1/orders?status=open&limit=25"
);

url.searchParams.set("limit", "50");

console.log(url.toString());
// https://api.example.test/v1/orders?status=open&limit=50

Use this for documented request construction—not as a substitute for following an API-provided cursor or next URL. Also note that set() replaces existing values for that key, so check the API's rules if repeated keys are meaningful.

Common Mistakes

  • Assuming every API uses page. APIs may use cursors, offsets, nested query names, response-body links, or HTTP headers.
  • Keeping only the cursor. A next URL may also carry filters or other state. Dropping them can change the result set or make the request fail.
  • Appending a new page number to a next URL. This can conflict with an existing cursor or pagination value.
  • Resolving a relative URL against the API origin by guesswork. Resolve it against the URL associated with the response that supplied it.
  • Splitting a Link header on commas. Use a parser that understands the header's syntax.
  • Printing full URLs in logs or support tickets. Query strings can contain bearer-like cursors, signed values, or other sensitive data. Redact them, restrict log access, and avoid sharing raw URLs publicly.
  • Trusting every returned host. A next link is data from a response, not proof that it is safe to send credentials there.

Best Practices

  1. Read the API's official pagination documentation before implementing a client. Follow its parameter names, response fields, header rules, and authentication guidance.
  2. Preserve the full next URL when the API supplies one; treat opaque cursor values as opaque.
  3. Use a URL parser to inspect path and query components, and check repeated parameters where relevant.
  4. Resolve relative references using the response URL. For Link headers, use a standards-aware parser.
  5. Validate destinations against the API's documented host or origin policy before attaching credentials.
  6. Redact sensitive query values in logs, screenshots, traces, and shared examples. Log the endpoint and request outcome instead when that is sufficient.

Documentation note: No web-retrieval capability was available while preparing this article, so I could not retrieve and verify a specific API's official documentation or the HTTP specifications. The examples are generic and should not be treated as documentation for a particular API. In particular, check the API's current guidance and the relevant HTTP Link and URI-reference specifications before relying on header parsing or relative-link behavior in a production client.

Conclusion

To read API pagination URLs safely, inspect their components without assuming a naming convention, and preserve the complete next link when the API provides one. Resolve relative references correctly, protect sensitive query values, and verify the destination before sending credentials.