Skip to main content

Pagination

All list endpoints in Semaswift use cursor-based pagination for efficient and consistent results.

Basic Usage

GET /api/v1/users?page_size=20

Response:

{
"users": [
{"id": "usr_1", "name": "Alice"},
{"id": "usr_2", "name": "Bob"}
],
"next_page_token": "eyJsYXN0X2lkIjoiMjAifQ==",
"total_count": 150
}

To get the next page:

GET /api/v1/users?page_size=20&page_token=eyJsYXN0X2lkIjoiMjAifQ==

Parameters

ParameterTypeDefaultMaxDescription
page_sizeinteger20100Number of items per page
page_tokenstring--Cursor for next page

Response Fields

FieldTypeDescription
{resource}arrayList of items
next_page_tokenstringToken for next page (empty if last page)
total_countintegerTotal number of items (optional)

Why Cursor-Based?

Cursor-based pagination offers advantages over offset-based:

  1. Consistent results - No skipped/duplicated items when data changes
  2. Better performance - No OFFSET queries that scan all rows
  3. Works with real-time data - Safe for frequently changing lists

Iterating All Pages

async function getAllUsers() {
const users = [];
let pageToken = null;

do {
const params = new URLSearchParams({ page_size: '100' });
if (pageToken) params.set('page_token', pageToken);

const response = await fetch(`/api/v1/users?${params}`, {
headers: { 'Authorization': `Bearer ${token}` }
});

const data = await response.json();
users.push(...data.users);
pageToken = data.next_page_token;
} while (pageToken);

return users;
}
def get_all_users():
users = []
page_token = None

while True:
params = {'page_size': 100}
if page_token:
params['page_token'] = page_token

response = requests.get('/api/v1/users', params=params, headers=headers)
data = response.json()

users.extend(data['users'])
page_token = data.get('next_page_token')

if not page_token:
break

return users

Filtering with Pagination

Filters are applied before pagination:

GET /api/v1/tickets?status=open&priority=high&page_size=50

The total_count reflects filtered results, not all records.

Sorting with Pagination

Sorting determines the order of paginated results:

GET /api/v1/tickets?sort=created_at:desc&page_size=20

Important: Keep the same sort order when paginating through results.

Best Practices

  1. Use reasonable page sizes - 20-50 for UI, up to 100 for batch operations
  2. Don't store page tokens long-term - They may expire or become invalid
  3. Handle empty pages - Empty next_page_token means last page
  4. Maintain consistent parameters - Keep filters/sort the same across pages