Reference

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>
No service tokens (yet)
There's no service-to-service token type. For now, machine callers should provision a dedicated user and use that account's 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. 200 on success, 201 on resource creation, 401 when unauthenticated, 403 when the caller lacks the role, 404 for missing resources, and 400 for malformed input.
  • cuid identifiers. Every resource ID is a cuid string. 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).