Authentication, rate limits, and errors
The integration surface is small and consistent. This page covers the conventions that apply across it: how machine-to-machine endpoints authenticate, the rate limits, and the error shapes to expect.
Authentication
The server-to-server endpoints you'll integrate with — chiefly
SIS sync — authenticate with a bearer
token: a shared secret issued per institution, sent in the Authorization
header.
POST /api/sis/sync
Authorization: Bearer <your-institution-secret>
Content-Type: application/jsonTokens are verified with a timing-safe comparison, so a wrong secret leaks no information about how wrong it was. Treat the secret like any production credential: store it in your secrets manager, never in source control, and rotate it if it may have been exposed.
End-user surfaces (the student app and staff console) authenticate with an HttpOnly session cookie established at sign-in, not a bearer token — see the OIDC flow. You won't call those as an integrator; the machine endpoints are the integration surface.
Rate limits
Endpoints are rate-limited per client. The limits are sized for legitimate use, so a well-behaved integration won't hit them:
| Endpoint | Limit |
|---|---|
SIS sync (/api/sis/sync) | 20 requests / minute |
Exceed a limit and you get 429 Too Many Requests with a Retry-After header
(seconds). Back off for that long and retry — don't hammer.
Sizes and idempotency
- SIS sync accepts up to 5,000 students per request; a larger batch returns 413. Page your roster into batches under that cap.
- SIS sync is idempotent. Re-sending the same students reconciles in place rather than duplicating, so retries after a network blip are safe.
Error shape
Errors return a JSON body with a stable, snake-case error code and sometimes a
human-readable detail:
{ "error": "batch_too_large", "max": 5000 }Common status codes across the surface:
| Code | Meaning |
|---|---|
200 | Success |
400 | Malformed JSON or a missing required field |
401 | Missing or incorrect bearer token |
413 | Payload too large (e.g. over the batch cap) |
429 | Rate limited — honour Retry-After |
500 | Server-side failure |
503 | Endpoint not configured (a required secret isn't set) |
The error codes are stable; the human-readable messages may be reworded. Write
your integration to switch on the code (and the HTTP status), and log the message
for humans.
Common questions
Is there a sandbox environment?
Integration happens against your institution's tenant. There's no separate public sandbox; coordinate test runs (for example a small SIS batch to a test cohort) during onboarding.
Do you offer outbound webhooks?
No — there are no outbound webhooks. See webhooks for what to do instead.
How do I rotate the secret?
Coordinate a new secret during onboarding or support; update it in your secrets manager and switch over. Rotate promptly if exposure is suspected.
Related
The fastest answer is usually one question away.