Skip to main content
Every list endpoint returns one page at a time:
To get the next page, send the same request again with ?cursor= set to nextCursor. Stop when nextCursor is null.

Rules

  • limit is 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 status or sectionId between 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:
  1. The first time, send updatedSince=2000-01-01T00:00:00Z. You get every record, and a starting mark. Keep each record by its id.
  2. From the last page, keep nextUpdatedSince.
  3. Next time, send updatedSince set to that value. Walk every page, as above.
  4. Put each record in data over the copy you hold with the same id.
  5. Keep the new nextUpdatedSince for the next run.
  6. At least once a week, do a full read: send updatedSince=2000-01-01T00:00:00Z again, and replace your copy with what comes back. A record you hold that is not in it was deleted or left the list.
Rules:
  • 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 attendeeCount because 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.