All list endpoints in the Toktra API use cursor-based pagination. Unlike page-number pagination, cursors remain stable as records are added or removed, so you never miss records or see duplicates when iterating through a large result set.
How it works
Cursors are opaque strings — you should not attempt to parse or construct them. Pass the cursor you received in the previous response to advance to the next page.
First page
Omit the cursor parameter entirely to fetch the first page:
curl "https://api.toktra.io/v1/users?limit=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Subsequent pages
Take next_cursor from the response and pass it as cursor on the next request:
curl "https://api.toktra.io/v1/users?limit=10&cursor=eyJpZCI6IjAxOTQ1YjM2LTQ1NjctNzAwMC04MDAwLTAwMDAwMDAwMDAwMCJ9" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
End of results
When you reach the last page, next_cursor is null and has_more is false. Stop paginating.
Opaque cursor for pagination. Pass the next_cursor value from the previous response to fetch the next page. Omit for the first page.
Maximum number of items to return per page. Must be between 1 and 100.
Response envelope
Every list endpoint wraps its results in this envelope:
Opaque cursor to pass as cursor on the next request. null when this is the last page.
true if there are more results beyond this page.
Total number of matching items. May be approximate for very large datasets.
Example: paginating through users
The following example shows a full pagination cycle using GET /v1/users.
Request — page 1
curl "https://api.toktra.io/v1/users?limit=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response — page 1
{
"items": [
{
"id": "a1b2c3d4-0000-0000-0000-000000000001",
"email": "alice@acme.com",
"name": "Alice Chen",
"department": "Engineering",
"role": "member",
"status": "active"
},
{
"id": "a1b2c3d4-0000-0000-0000-000000000002",
"email": "bob@acme.com",
"name": "Bob Patel",
"department": "Marketing",
"role": "member",
"status": "active"
}
],
"next_cursor": "eyJpZCI6ImExYjJjM2Q0LTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMiJ9",
"has_more": true,
"total_count": 47
}
Request — page 2
curl "https://api.toktra.io/v1/users?limit=2&cursor=eyJpZCI6ImExYjJjM2Q0LTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMiJ9" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response — last page
{
"items": [
{
"id": "a1b2c3d4-0000-0000-0000-000000000046",
"email": "zara@acme.com",
"name": "Zara Okonkwo",
"department": "Legal",
"role": "admin",
"status": "active"
}
],
"next_cursor": null,
"has_more": false,
"total_count": 47
}
next_cursor is null — you have fetched all records.
Iterating all pages in code
import requests
token = "YOUR_ACCESS_TOKEN"
headers = {"Authorization": f"Bearer {token}"}
url = "https://api.toktra.io/v1/users"
cursor = None
while True:
params = {"limit": 100}
if cursor:
params["cursor"] = cursor
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
for user in data["items"]:
print(user["email"])
if not data["has_more"]:
break
cursor = data["next_cursor"]
const fetch = require('node-fetch');
async function fetchAllUsers(token) {
const headers = { Authorization: `Bearer ${token}` };
let cursor = null;
const users = [];
do {
const url = new URL('https://api.toktra.io/v1/users');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url.toString(), { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
users.push(...data.items);
cursor = data.next_cursor;
} while (cursor);
return users;
}
Cursors are not permanent. Do not store a cursor and attempt to resume pagination days later — use the cursor immediately within the same session.