Schéma d'endpoint
https://[tenant].studeia.com/api/institution/[resource]
Pour les tenants avec domaine personnalisé :
https://api.escola.com.br/api/institution/[resource]
Authentification — double auth
La plupart des routes /api/institution/* acceptent 2 modes d'authentification. Les routes gérant les identifiants, OAuth, billing, SSO, fournisseurs de vidéo/avatar et vérification de domaine sont session-only pour des raisons de sécurité (n'acceptent pas de clé API).
Bearer API key
GET /api/institution/courses
Authorization: Bearer mia_abc123...
La clé API est résolue via le cache Redis (TTL 60s) + lookup par préfixe.
Cookie de session
GET /api/institution/courses
Cookie: sb-access-token=...; sb-refresh-token=...
Pour les appels depuis le frontend Studeia lui-même.
Scopes (granulaires)
Chaque route de ressource déclare requiredScopes ; la clé API doit posséder les scopes correspondants. Le backend reconnaît 35 scopes au total.
| Route | 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 |
Une clé API avec un scope vide ([]) = accès total (clés admin).
Rate limiting
| Niveau | Req/heure | Burst/min |
|---|---|---|
| standard | 1 000 | 100 |
| high | 5 000 | 300 |
| custom | configurable | custom/60 |
En-têtes de réponse :
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 }
Format de réponse
Succès
{
"data": [...],
"pagination": {
"page": 1,
"perPage": 50,
"total": 247,
"totalPages": 5
}
}
Erreur
{
"error": "validation_failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
Codes de statut :
- 200 OK
- 201 Created
- 204 No Content (DELETE)
- 400 Bad Request (validation)
- 401 Unauthorized (auth invalide)
- 403 Forbidden (scope ou rôle manquant)
- 404 Not Found
- 409 Conflict (incohérence d'état)
- 422 Unprocessable Entity (règle métier)
- 429 Rate limit
- 500 Server error
Pagination
Par défaut : basée sur curseur.
GET /api/institution/courses?page=1&perPage=50&search=mathematiques
perPage max 100 (plafonné côté serveur).
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
Le preflight (OPTIONS) répond 204.
i18n
Les erreurs sont localisées via l'en-tête Accept-Language: fr-FR (ou en-US, es-ES, pt-BR). Fallback pt-BR si la langue n'est pas supportée.
Démarrage rapide
# 1. Générez une clé API dans /institution/settings > API Keys
# 2. Listez les cours
curl https://[tenant].studeia.com/api/institution/courses \
-H "Authorization: Bearer mia_abc123..." \
-H "Accept-Language: fr-FR"
# 3. Créez un étudiant
curl -X POST https://[tenant].studeia.com/api/institution/users \
-H "Authorization: Bearer mia_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "Marie Dupont",
"email": "marie@example.com",
"role": "student",
"sendInvite": true
}'
Groupes d'endpoints (33 groupes)
Documentation détaillée par groupe sur /docs/api/[group] :
- Institution, Cours, Modules, Leçons, Utilisateurs, Inscriptions, Classes
- Médias, Notes, Rubriques, Banque de Questions, Cours en Direct, Fournisseurs Vidéo
- Webhooks, Invitations, Tags, LTI, Paramètres, Automations
- RAG, Rapports, Analyse IA, Gamification, E-mail, Drive, Calendrier