Pagination

List endpoints in the Rekall API use cursor-based pagination to efficiently traverse large result sets. This approach provides consistent performance regardless of collection size.

Cursor-Based Pagination

Cursor-based pagination uses an opaque cursor string to mark your position in the result set. Each response includes a next_cursor value that you pass in the next request to fetch the following page.

This approach is preferred over offset-based pagination because it handles data changes gracefully -- new items added or removed between requests will not cause duplicates or skipped records.

First Request
curl https://api.rekall.ai/v1/memories?page_size=10 \
-H "Authorization: Bearer rk_live_abc123"
Response with Pagination
{
"data": [
{ "id": "mem_001", "type": "episodic", "content": "..." },
{ "id": "mem_002", "type": "semantic", "content": "..." },
...
],
"pagination": {
"next_cursor": "eyJpZCI6Im1lbV8wMTAiLCJjcmVhdGVkX2F0IjoiMjAyNS0wMS0xNSJ9",
"has_more": true,
"total_count": 142
}
}
Next Page Request
curl "https://api.rekall.ai/v1/memories?page_size=10&cursor=eyJpZCI6Im1lbV8wMTAiLCJjcmVhdGVkX2F0IjoiMjAyNS0wMS0xNSJ9" \
-H "Authorization: Bearer rk_live_abc123"

Pagination Parameters

The following query parameters control pagination on list endpoints.

ParameterTypeDefaultDescription
page_sizeinteger20Number of items per page (1-100)
cursorstringnullCursor from previous response to get the next page
sortstringcreated_atField to sort by (created_at, updated_at, relevance)
orderstringdescSort order (asc, desc)

Response Metadata

Every list response includes a pagination object with the following fields.

FieldTypeDescription
next_cursorstring | nullCursor for the next page, null if no more results
has_morebooleanWhether there are more results after this page
total_countintegerTotal number of items in the collection

Iterating Through Pages

Here are complete examples of iterating through all pages of a paginated endpoint.

Pagination Iteration
async function getAllMemories(apiKey: string) {
const memories = [];
let cursor: string | null = null;
do {
const params = new URLSearchParams({ page_size: '50' });
if (cursor) params.set('cursor', cursor);
const response = await fetch(
`https://api.rekall.ai/v1/memories?${params}`,
{
headers: { 'Authorization': `Bearer ${apiKey}` },
}
);
const { data, pagination } = await response.json();
memories.push(...data);
cursor = pagination.has_more ? pagination.next_cursor : null;
} while (cursor);
return memories;
}

Offset Pagination Fallback

For backward compatibility, some endpoints also support offset-based pagination using the offset and limit query parameters. Offset pagination is less efficient for large datasets and may produce inconsistent results if data changes between requests.

Offset Pagination
# First page
curl "https://api.rekall.ai/v1/memories?limit=20&offset=0" \
-H "Authorization: Bearer rk_live_abc123"
# Second page
curl "https://api.rekall.ai/v1/memories?limit=20&offset=20" \
-H "Authorization: Bearer rk_live_abc123"

Prefer cursor-based pagination

Offset pagination is provided as a fallback. Cursor-based pagination is recommended for all production use cases as it provides better performance and consistency.

Best Practices

Use reasonable page sizes

A page size of 20-50 items is optimal for most use cases. Larger pages increase response time and memory usage.

Do not cache cursors long-term

Cursors are transient and may become invalid after data changes. Always start from the first page for fresh data.

Check has_more before iterating

Always check the has_more flag rather than checking if next_cursor is null, as this is the most reliable indicator.

Use search for filtered queries

If you need to filter results, use the search endpoints instead of fetching all records and filtering client-side. Search endpoints support pagination too.

Rekall
rekall