API Overview
The Orbit Classroom API is a REST/JSON API for all CRUD operations, with Server-Sent Events (SSE) for AI chat streaming.
Design Principles
- REST + JSON for CRUD — standard HTTP verbs (
GET,POST,PATCH,DELETE) on noun-based resource routes. - SSE for streaming — AI chat responses are delivered as
text/event-streamto support token-by-token streaming. - Noun-based routes — resources are addressed by stable, opaque IDs (UUID/ULID format).
- Explicit lifecycle actions — state transitions such as
publish,unpublish, andarchiveare expressed as named sub-resource actions rather than bare field patches. - Stable IDs — resource IDs never change after creation; callers should store and reference them.
- Server authority for calculated fields — aggregates such as overall grades and progress percentages are always computed server-side and never accepted as client input.
Base Path
All endpoints are prefixed with:
/api/v1
Content Types
| Scenario | Content-Type |
|---|---|
| JSON request / response | application/json |
| File upload | multipart/form-data |
| Streaming AI response | text/event-stream |
Time Format
All timestamps are ISO 8601 UTC, e.g.:
2026-03-14T09:30:00Z
ID Format
All resource IDs are opaque strings (UUID or ULID). Do not parse or compare IDs as integers.
Authentication
Every request must carry a valid Supabase access token in the Authorization header:
Authorization: Bearer <token>
See Authentication for details on obtaining and refreshing tokens.
Response Envelope
Success
All successful responses wrap the payload in a consistent envelope:
{
"data": {},
"meta": {}
}
List responses include pagination metadata in meta (see Pagination below).
Error
All error responses share a common structure:
{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "req_abc123"
}
}
Standard Error Codes
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid bearer token. |
FORBIDDEN | 403 | Authenticated but not authorized for this action. |
NOT_FOUND | 404 | Resource does not exist or is not visible to the caller. |
VALIDATION_ERROR | 422 | Request body or query params failed validation. |
CONFLICT | 409 | Action conflicts with current resource state (e.g. duplicate title). |
PRECONDITION_FAILED | 412 | A required precondition was not met (e.g. withdrawing after due date). |
RATE_LIMITED | 429 | Too many requests; back off and retry. |
PROCESSING_FAILED | 422 | Background processing of an uploaded asset failed. |
STREAM_ABORTED | 499 | Client disconnected before the SSE stream completed. |
INTERNAL_ERROR | 500 | Unexpected server-side error. |
Pagination
List endpoints that return potentially large collections support cursor-free page/offset pagination. The meta object contains:
{
"data": [],
"meta": {
"page": 1,
"page_size": 20,
"total": 154,
"has_next": true
}
}
Query parameters:
| Parameter | Default | Description |
|---|---|---|
page | 1 | 1-based page number. |
page_size | 20 | Items per page (max 100). |
Role System
Global Roles
Every user has exactly one global role. Roles are ordered by ascending privilege:
| Role | Description |
|---|---|
NO_ROLE | Newly registered user; cannot access the dashboard until assigned a role. |
STUDENT | Can enroll in classes, view published content, and use the AI assistant. |
TEACHER | Can create and manage classes, modules, lessons, materials, and assignments. |
ADMIN | Full access including system administration and user management. |
Class Membership
In addition to their global role, users have a per-class membership record with a role and status.
Membership roles: STUDENT, TEACHER, ADMIN
Membership statuses:
| Status | Description |
|---|---|
PENDING | Student has requested to join; awaiting teacher/admin approval. |
APPROVED | Member has full access to the class. |
REJECTED | Join request was denied. |
REMOVED | Member was removed from the class after approval. |
Visibility Rules
- Students only see content with
visibility_state: "PUBLISHED". - Teachers and Admins can see and edit draft content.
- Student chat sessions are private — only the student and class teachers/admins can access them.