Pagination
Cursor-Based pagination explained, JSON:API Style.
Our API supports cursor-based pagination, inspired by the JSON:API pagination specification. This approach is efficient and scalable for large datasets.
Each paginated response contains a data array and links for navigating through pages.
📦 Response Format
{
"data": <...>,
"links": {
"self": "https://api.example.com/resources?cursor=abcdef",
"next": "https://api.example.com/resources?cursor=ghijkl"
}
}🔗 links.self
links.selfURL for the current page. Safe to cache or re-fetch.
🔗 links.next
links.nextURL for the next page. If absent or null, you've reached the end.
🧭 cursor
cursorA cursor is an opaque string provided by the server to mark a position in the dataset. You must use it exactly as returned. Do not attempt to decode or generate it manually.
🔐 Authentication Required
Before making any paginated requests, make sure your client is authenticated properly.
➡️ See the Authentication section for details on required headers.
🟦 TypeScript (e.g. in a React or Node.js app)
async function fetchPage(url: string) {
const res = await fetch(url, {
headers: {
'X-API-KEY': 'your-api-key',
'X-API-SECRET': 'your-api-secret',
},
});
const body = await res.json();
console.log('Current page:', body.data);
if (body.links?.next) {
console.log('Next page URL:', body.links.next);
// await fetchPage(body.links.next);
}
}
fetchPage('https://api.example.com/resources');🟠 Java (with HttpClient and Jackson)
HttpClient and Jackson)HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
void fetchPage(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("X-API-KEY", "your-api-key")
.header("X-API-SECRET", "your-api-secret")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode json = mapper.readTree(response.body());
System.out.println("Current page: " + json.get("data"));
JsonNode next = json.path("links").path("next");
if (!next.isMissingNode()) {
System.out.println("Next page URL: " + next.asText());
// fetchPage(next.asText());
}
}🟦 .NET (C# with HttpClient)
HttpClient)using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
async Task FetchPageAsync(string url)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "your-api-key");
client.DefaultRequestHeaders.Add("X-API-SECRET", "your-api-secret");
var response = await client.GetStringAsync(url);
using var doc = JsonDocument.Parse(response);
var root = doc.RootElement;
Console.WriteLine("Current page: " + root.GetProperty("data"));
if (root.TryGetProperty("links", out var links) &&
links.TryGetProperty("next", out var next))
{
Console.WriteLine("Next page URL: " + next.GetString());
// await FetchPageAsync(next.GetString());
}
}✅ Best Practices
Always use the
links.nextURL for pagination.Never parse or construct cursors manually.
Stop paginating when
links.nextis missing ornull.Ensure authentication headers are included — see the Authentication section.
Last updated
Was this helpful?