Pagination
How methods that return long lists hand them over a page at a time, and how to walk every page.
On this page
Methods that list things return a fixed number of items per call. Each method's page says how many and which of the patterns below it uses. There are four.
Offset and count
Most lists take an offset, the number of items to skip, and answer with count, the total. Start at 0 and add the page size until you have collected count items.
curl -X POST https://api.modulify.ai/v1/list_sites \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"workspaceId":"WORKSPACE_ID","offset":8}'list_sites, list_templates and list_deployments work this way. A few, such as list_rows, list_workspace_members and get_publish_logs, also take a limit for the page size, up to a maximum their page states. Some answer with hasMore and the offset to send next instead of a total, such as list_workspace_credit_activity, so keep going while hasMore is true.
const ListAllSites = async (workspaceId) => {
const sites = []
while (true) {
const response = await fetch('https://api.modulify.ai/v1/list_sites', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.MODULIFY_TOKEN}` },
body: JSON.stringify({ workspaceId, offset: sites.length })
})
const result = await response.json()
if (!result.success) throw new Error(result.message)
sites.push(...result.data)
if (result.data.length === 0 || sites.length >= result.count) return sites
}
}Next cursor
Logs and histories that grow all the time answer with a nextCursor. Send it back as cursor for the next page, and stop when it comes back null. Keep every other argument the same between pages, since the cursor belongs to that exact query.
list_deploy_hook_calls, list_site_cron_runs, list_webhook_deliveries, list_site_email_sends, list_site_email_engagement and list_site_email_suppressions work this way.
curl -X POST https://api.modulify.ai/v1/list_site_cron_runs \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"projectId":"SITE_ID","cursor":"NEXT_CURSOR"}'list_storage_files follows the same idea with a different name: it answers with nextToken, which you send back as token to read the next page of the same folder.
Page numbers
The backup histories, list_code_backups, list_storage_backups and list_database_backups, take a page that starts at 1.
Reading backwards
Two methods page through something that only grows, from the newest end:
list_messagesreturns the newest chat messages withhasMoreandoldestCursor. SendoldestCursorback ascursorto get the page before, and stop whenhasMoreis false.get_jobreturns the events of a generation after a numericcursor. Send back thecursorfrom each answer to receive only new events. See Long-running work.
Tips
- Read
count, not the page length. The last page is usually shorter than the rest, and an empty page means you have read everything. - Expect change while you page. Items added or removed between two calls can shift an offset by one. For a stable copy of one collection,
export_collectionreturns its rows in a single call. - Pace yourself. Every page is one call against the token's per-minute budget. See Rate limits.
Next
- Requests and responses for where
countlives. - All methods to find a method's page size.