?cursor= set to nextCursor. Stop when nextCursor is null.
Rules
limitis 1 to 200. The default is 50. Use 200 to make fewer requests.- Pass the cursor back unchanged. It is not a page number. Do not read it, build it or change it. Its format can change at any time.
- Keep the same filters and limit. A cursor belongs to one query. If you change
statusorsectionIdbetween pages, the pages you get are not reliable. To change a filter, start again without a cursor. - A cursor you changed gets
400. The message tells you to start again without one. - Spell parameters exactly. The API rejects a parameter it does not know with
400 invalid_request, so a typo fails loudly instead of being ignored.
A loop that reads every page
Sync only what changed
A sync that runs every day does not need every record every time.GET /members, /events and /badges take updatedSince. With it, the walk returns only the records that changed at or after that time, and one more field on every page:
- The first time, send
updatedSince=2000-01-01T00:00:00Z. You get every record, and a starting mark. Keep each record by itsid. - From the last page, keep
nextUpdatedSince. - Next time, send
updatedSinceset to that value. Walk every page, as above. - Put each record in
dataover the copy you hold with the sameid. - Keep the new
nextUpdatedSincefor the next run. - At least once a week, do a full read: send
updatedSince=2000-01-01T00:00:00Zagain, and replace your copy with what comes back. A record you hold that is not in it was deleted or left the list.
- Use
nextUpdatedSince, not your own clock. It is a little before your walk began. A record that changed while you were paging comes back next time, so no change is lost. You can get the same record twice; step 4 makes that harmless. - Removals are not in a sync. A record that was deleted, or no longer matches your query (a member who was archived, transferred or moved out of
sectionId, an event that was archived or withdrawn from, a badge record set back to not required), simply stops coming back. The weekly full read in step 6 finds it. - The weekly full read also catches these, which do not mark a record as changed:
- a parent or carer linked to a member, or unlinked (a change to the parent’s own name or email does mark the member);
- a change to an event’s
attendeeCountbecause a child was transferred to another group, or because a register mark was changed in place; - a section or patrol renamed. For section names, you can also read
GET /sections.
- These do mark a record as changed: a change to the member, their membership in your group, or a linked parent’s own record; a change to the event, your group’s place on it, or a new RSVP; a change to a badge record, its requirement progress, its member or its badge.
- Keep the same filters on every run. A cursor and a mark belong to one query.