API reference
Athenium exposes a REST-style API under /api. Every endpoint runs as a Next.js Route Handler, authenticated against the current Clerk session. This page covers the conventions; endpoint-specific shapes live with the routes themselves.
Authentication
Every protected route resolves the caller via getAuth(req) from @clerk/nextjs/server. The returned userId is also the primary key of the matching User row in Postgres — Athenium uses the Clerk identifier as its own, populated by the user-created webhook (see Webhooks).
From a logged-in browser session, no extra work is needed — the Clerk cookie is forwarded automatically. From outside the browser, use a Clerk-issued JWT in the Authorization header.
Authorization: Bearer <clerk-jwt>Endpoint groups
Routes are grouped by resource. The most common are:
/api/classrooms— list, create, update, delete classrooms; nested resources for assignments, resources, members, attendance, and submissions./api/assignments— assignment-level operations not tied to a single classroom listing./api/submissions/[id]/marks— patch a submission's score./api/notifications— list, mark-read, and read-all./api/user— current user's profile./api/extract-content— server-side text extraction for uploaded resources.
Conventions
- JSON in, JSON out. All routes consume and produce
application/json. - Status codes.
200on success,201on resource creation,401when unauthenticated,403when the caller lacks the role,404for missing resources, and400for malformed input. - cuid identifiers. Every resource ID is a
cuidstring. Don't assume integer IDs.
Example: list classrooms
GET /api/classrooms
Authorization: Bearer <clerk-jwt>
200 OK
{
"classrooms": [
{
"id": "ckl1abcd...",
"name": "Computer Networks",
"code": "ATH7K42",
"year": "3",
"division": "A",
"courseCode": "CSE3104",
"courseName": "Computer Networks",
"pendingAssignments": 2
}
]
}Example: create a classroom
POST /api/classrooms/create
Authorization: Bearer <clerk-jwt>
Content-Type: application/json
{
"year": "3",
"division": "A",
"courseCode": "CSE3104",
"courseName": "Computer Networks"
}
201 Created
{
"classroom": { "id": "ckl1...", "code": "ATH7K42", "inviteLink": "..." }
}Example: grade a submission
PATCH /api/submissions/ckl9.../marks
Authorization: Bearer <clerk-jwt>
Content-Type: application/json
{ "marks": 23 }
200 OK
{ "submission": { "id": "ckl9...", "marks": 23 } }Errors
Errors are JSON objects with a single error field containing a human-readable message. The status code is the contract; the message is for humans:
401 Unauthorized
{ "error": "Unauthorized" }Rate limits
There are no hard rate limits today — the platform is hosted on Vercel with their default protections. Bulk callers should still batch requests where possible (the attendance batch endpoint exists for this reason).