Endpoint pattern
https://[tenant].studeia.com/api/institution/[resource]
Authentication — dual auth
Most /api/institution/* routes accept 2 modes. Routes that manage credentials, OAuth, billing, SSO, video/avatar providers and domain verification are session-only for security (they do not accept API keys):
Bearer API key
GET /api/institution/courses
Authorization: Bearer mia_abc123...
Session cookie
GET /api/institution/courses
Cookie: sb-access-token=...
Scopes (granular)
Each resource route declares requiredScopes; the API key needs the corresponding scopes. The backend recognizes 35 scopes total.
Common: courses:read|write, users:read|write, enrollments:read|write, classes:read|write, media:read|write, grades:read|write, question-banks:read|write, live-classes:read|write, lti:read|write, drive:read|write, automations:read|write, gamification:read|write, reports:read.
API key with empty scopes ([]) = total access (admin keys).
Rate limiting
| Tier | Req/hour | Burst/min |
|---|---|---|
| standard | 1,000 | 100 |
| high | 5,000 | 300 |
| custom | configurable | custom/60 |
Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Exceeded: 429 with Retry-After.
Response pattern
Success:
{
"data": [...],
"pagination": { "page": 1, "perPage": 50, "total": 247 }
}
Error:
{
"error": "validation_failed",
"details": [{ "field": "email", "message": "Invalid format" }]
}
i18n
Errors localized via header Accept-Language: en-US (or pt-BR, es-ES, fr-FR).
Quickstart
# List courses
curl https://[tenant].studeia.com/api/institution/courses \
-H "Authorization: Bearer mia_abc123..." \
-H "Accept-Language: en-US"