Skip to main content

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-stream to 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, and archive are 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

ScenarioContent-Type
JSON request / responseapplication/json
File uploadmultipart/form-data
Streaming AI responsetext/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

CodeHTTP StatusDescription
UNAUTHENTICATED401Missing or invalid bearer token.
FORBIDDEN403Authenticated but not authorized for this action.
NOT_FOUND404Resource does not exist or is not visible to the caller.
VALIDATION_ERROR422Request body or query params failed validation.
CONFLICT409Action conflicts with current resource state (e.g. duplicate title).
PRECONDITION_FAILED412A required precondition was not met (e.g. withdrawing after due date).
RATE_LIMITED429Too many requests; back off and retry.
PROCESSING_FAILED422Background processing of an uploaded asset failed.
STREAM_ABORTED499Client disconnected before the SSE stream completed.
INTERNAL_ERROR500Unexpected 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:

ParameterDefaultDescription
page11-based page number.
page_size20Items per page (max 100).

Role System

Global Roles

Every user has exactly one global role. Roles are ordered by ascending privilege:

RoleDescription
NO_ROLENewly registered user; cannot access the dashboard until assigned a role.
STUDENTCan enroll in classes, view published content, and use the AI assistant.
TEACHERCan create and manage classes, modules, lessons, materials, and assignments.
ADMINFull 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:

StatusDescription
PENDINGStudent has requested to join; awaiting teacher/admin approval.
APPROVEDMember has full access to the class.
REJECTEDJoin request was denied.
REMOVEDMember 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.