Endpoint pattern
https://[tenant].studeia.com/api/institution/[resource]
Para tenants com dominio custom:
https://api.escola.com.br/api/institution/[resource]
Autenticacao — dual auth
Toda rota /api/institution/* aceita 2 modos:
Bearer API key
GET /api/institution/courses
Authorization: Bearer mia_abc123...
API key resolvida via cache Redis (60s TTL) + lookup por prefix.
Session cookie
GET /api/institution/courses
Cookie: sb-access-token=...; sb-refresh-token=...
Para chamadas do proprio frontend Studeia.
Scopes (granulares)
Cada rota declara requiredScopes. API key precisa ter os scopes correspondentes.
| Rota | Scopes |
|---|---|
| courses | courses:read |
| users | users:read |
| enrollments | enrollments:read |
| classes | classes:read |
| media | media:read |
| gradebook | grades:read |
| rubrics | rubrics:read |
| question-banks | question-banks:read |
| live-classes | live-classes:read |
| tags | tags:read |
| invites | invites:read |
| lti-tools | lti:read |
| drive | drive:read |
| settings, themes, api-keys, profile-config | settings:read |
| automations | automations:read |
| prompts, ai-limits | ai:read |
| ai-analytics | reports:read |
| reports | reports:read |
| video-provider | settings:read |
API key com scope vazio ([]) = acesso total (chaves admin).
Rate limiting
| Tier | Req/hora | Burst/min |
|---|---|---|
| standard | 1.000 | 100 |
| high | 5.000 | 300 |
| custom | configuravel | custom/60 |
Headers de resposta:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 947
X-RateLimit-Reset: 1716480000
Rate exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 120
{ "error": "rate_limit_exceeded", "retryAfter": 120 }
Padrao de resposta
Sucesso
{
"data": [...],
"pagination": {
"page": 1,
"perPage": 50,
"total": 247,
"totalPages": 5
}
}
Erro
{
"error": "validation_failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
Status codes:
- 200 OK
- 201 Created
- 204 No Content (DELETE)
- 400 Bad Request (validation)
- 401 Unauthorized (auth invalid)
- 403 Forbidden (sem scope ou role)
- 404 Not Found
- 409 Conflict (state inconsistency)
- 422 Unprocessable Entity (business rule)
- 429 Rate limit
- 500 Server error
Paginacao
Default: cursor-based.
GET /api/institution/courses?page=1&perPage=50&search=matematica
perPage max 100 (cap server-side).
CORS
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Accept-Language
Access-Control-Max-Age: 86400
Preflight (OPTIONS) responde 204.
i18n
Erros sao localizados via header Accept-Language: pt-BR (ou en-US, es-ES, fr-FR). Fallback pt-BR se idioma nao suportado.
Quickstart
# 1. Gere API key em /institution/settings > API Keys
# 2. Liste cursos
curl https://[tenant].studeia.com/api/institution/courses \
-H "Authorization: Bearer mia_abc123..." \
-H "Accept-Language: pt-BR"
# 3. Crie aluno
curl -X POST https://[tenant].studeia.com/api/institution/users \
-H "Authorization: Bearer mia_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "Maria Silva",
"email": "maria@example.com",
"role": "student",
"sendInvite": true
}'
Endpoint groups (~31 grupos)
Documentacao detalhada por grupo em /docs/api/[group]:
- Instituicao, Cursos, Modulos, Aulas, Usuarios, Matriculas, Turmas
- Midia, Notas, Rubricas, Banco de Questoes, Aulas ao Vivo, Video Providers
- Webhooks, Convites, Tags, LTI, Configuracoes, Automacoes
- RAG, Relatorios, Analise IA, Gamificacao, Email, Drive, Calendar