Guide

Polling for changes

Webhooks push events to you. When your tool can't receive them (a spreadsheet, a nightly job behind a firewall), poll this feed instead: one cheap call tells you what to read again.

How it works

Tools that can't take webhooks (Zapier, Google Sheets, a nightly job) can poll GET /changes. Call it once without since to get a cursor for now, keep the nextCursor of every answer and pass it back as since every few minutes (straight away again while hasMore is true). Each entry names a record that was added, changed or deleted since — students, families, vouchers, receipts, registers, applications and the school's structure, only those the key may read and on its campus — and you read the ones you care about with their GET endpoint. Changes are kept 30 days; a cursor older than that gets 409 cursor_expired: read the lists again, then poll from a new cursor.

A polling loop

Save the cursor only after you've handled a page, so a crash never skips a change.

curl "https://api.school360.cloud/v1/changes" -H "Authorization: Bearer $SCHOOL360_KEY"
# → { "data": [], "nextCursor": "eyJzIjo4MTIzNH0", "hasMore": false }   keep the cursor

curl "https://api.school360.cloud/v1/changes?since=eyJzIjo4MTIzNH0" -H "Authorization: Bearer $SCHOOL360_KEY"
# → { "data": [{ "entity": "students", "id": 412, "op": "changed", "at": "2026-10-08T07:41:12.000Z" }, …],
#     "nextCursor": "eyJzIjo4MTI5MH0", "hasMore": false }

What's in the feed

  • students, families (with their keys' permissions)
  • vouchers, receipts (fees:read)
  • registers: attendance registers (attendance:read; read them with GET /attendance)
  • applications (admissions:read)
  • campuses, years, classes, sections (every key)

Staff, exams, notices and the gate log aren't in the feed: use their lists (updatedSince on staff) or webhooks.

Expired cursors

Changes are kept 30 days. A cursor older than that answers 409 cursor_expired: read the lists you keep again, then call GET /changes without since for a fresh cursor.