Concepts
Pagination
How lists are paged with a cursor, how to walk them, and how to keep a copy in sync.
Every list operation returns one page of objects at a time. You move from page to page with a cursor: the id of an object you already have.
The list object
A list answers a list object:
{
"object": "list",
"url": "/v1/registrations",
"has_more": true,
"data": [
{
"id": "SUB-8c3e2a71-0f4b-4d6a-b5e9-27c1d9a4e612",
"object": "registration",
"event": "EVT-5a1f0c2e-3b7d-4e91-9c2a-1d6e8f4b7a30",
"status": "validated",
"role": "attendee",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada.lovelace@example.com",
"ticket": {
"name": "Full pass"
},
"checkin": {
"checked_in": true,
"last_checked_in_at": 1810119600
},
"created": 1795521600,
"updated": 1810119600
}
]
}data: the objects of the page,[]when there are none.has_more:truewhen more objects follow this page.url: the path of the list.
Objects always come newest first: by created descending, then by id descending.
Page size
limit sets how many objects a page holds: from 1 to 100, 10 by default. With any expand[] in the request, limit is at most 20; above that, the request answers 400 parameter_invalid on limit.
curl
JavaScript
Python
The next page
Send starting_after with the id of the last object of the page you have. The answer holds the objects that follow it.
curl
JavaScript
Python
To walk a whole list:
- Ask for the first page.
- Process its
data. - While
has_moreistrue, ask again withstarting_afterset to theidof the last object ofdata.
The previous page
Send ending_before with the id of the first object of the page you have. The page holds the objects that precede it, in the same newest-first order. starting_after and ending_before never go together: sending both answers parameter_invalid.
The total count
include[]=total_count adds total_count, the number of objects of the whole list. It is absent unless you ask for it.
curl
JavaScript
Python
Valid cursors
A cursor must be an object of the same list: of your organization and of the list’s parent. That is the event of a list of registrations, the call_for_papers of a list of papers, and the event filter of a list of calls for papers, when you give one. Any other id, unknown or removed, answers parameter_invalid on its parameter. The API never silently starts again from the top.
A cursor object that no longer matches the list’s filters still works. If a registration you used as a cursor changes status while you walk status=require_admin_validation, the next page starts from where it was.
Keeping a copy in sync
To pick up the objects created since your last run, walk the list from the newest and stop at the first id you already have.
Objects created while you walk sit before your cursor, so they never shift the pages that follow. They appear at the top on your next run.
This finds new objects only. A change to an object you already have, such as a new status, does not move it in the list: read it again with its retrieve operation, or walk the whole list. v1 has no filter on updated.
What costs more
The cheapest call is the page that follows the one you just read. Keep walking forward with starting_after.
- A cursor far down a long list, that you did not get from a recent page, costs the API more reads to place. The call is slower.
- Many objects created in the same second, as an import does, are slower to page through.
A known limit
An object can enter a filtered list with an old created date, for example an older registration whose status changes to the one you filter on. If that happens at the very moment of one of your calls, that call can miss it. Your next full walk will see it.