Pagination Guide
This API uses cursor-based pagination for list endpoints. This guide explains how to navigate through paginated results.
Response Structure
All paginated endpoints return responses in this format:
{
"data": [...],
"meta": {
"next": "https://api.example.com/v1/enrolments/?limit=100&after=obj-123",
"prev": "https://api.example.com/v1/enrolments/?limit=100&before=obj-100",
"count": 250
}
}
data: Array of items for the current pagemeta.next: Full URL to fetch the next page (null if on last page)meta.prev: Full URL to fetch the previous page (null if on first page)meta.count: Total number of items matching your filters
Query Parameters
limit
Controls the number of items per page. Different pages may have different default and maximum values. Generally, the default value should be safe for most use cases, and not tax your rate limits too heavily.
Example:
Navigating
Initial Request
Start by making a request without any cursor parameters:
Response:
{
"data": [
{"id": "enrol_001"},
{"id": "enrol_002"},
...
{"id": "enrol_100"}
],
"meta": {
"next": "https://api.example.com/v1/enrolments/?limit=100&after=enrol_100",
"prev": null,
"count": 250
}
}
Moving Forward
To fetch the next page, use the URL provided in meta.next:
Response:
{
"data": [
{"id": "enrol_101"},
{"id": "enrol_102"},
...
{"id": "enrol_200"}
],
"meta": {
"next": "https://api.example.com/v1/enrolments/?limit=100&after=enrol_200",
"prev": "https://api.example.com/v1/enrolments/?limit=100&before=enrol_101",
"count": 250
}
}
Moving Backward
To fetch the previous page, use the URL provided in meta.prev:
Reaching the End
When you reach the last page, meta.next will be null:
{
"data": [
{"id": "enrol_201"},
{"id": "enrol_202"},
...
{"id": "enrol_250"}
],
"meta": {
"next": null,
"prev": "https://api.example.com/v1/enrolments/?limit=100&before=enrol_201",
"count": 250
}
}
Combining with Filters
Pagination works seamlessly with other query parameters. The next and prev URLs will preserve your filters:
Response:
{
"data": [...],
"meta": {
"next": "https://api.example.com/v1/enrolments/?start_datetime=2025-01-01T00:00:00Z&limit=50&after=enrol_123",
"prev": null,
"count": 75
}
}
Error Responses
Invalid Cursor
If you provide an after or before cursor that doesn't exist:
Status: 422 Unprocessable Entity
Limit Too Large
If you request a limit exceeding the maximum allowed:
Status: 422 Unprocessable Entity
Tips
- Use the provided URLs: Always use
meta.nextandmeta.prevURLs exactly as provided. Don't construct cursor values manually. - Check for null: Before following
meta.nextormeta.prev, check that they are notnull. - Handle errors gracefully: Cursors can become invalid if the underlying data is deleted. Implement error handling for 422 responses.
Example
Here's a Python example that fetches all enrolments:
import httpx
def fetch_all_enrolments(api_key: str, base_url: str) -> list:
items = []
url = f"{base_url}/v1/enrolments/?limit=100"
headers = {"Authorization": f"Bearer {api_key}"}
with httpx.Client(headers=headers) as client:
while url:
response = client.get(url)
response.raise_for_status()
data = response.json()
items.extend(data["data"])
url = data["meta"]["next"]
return items