---
title: "Manage Classes & Rosters"
url: https://docs.growamal.com/en/guides/classes-and-rosters/
language: en
---

# Manage Classes & Rosters

## Create a class

`POST /api/classes` with `{ schoolId, name, grade, academicYear }` (needs `MANAGE_SCHOOLS`). `grade`
is 1–4; `academicYear` matches `^\d{4}-\d{4}$`.

```bash
curl -X POST https://localhost:3000/api/classes \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{
    "schoolId": "clx4z2k0u0000xyz1234abcde",
    "name": "صف ثاني — أ",
    "grade": 2,
    "academicYear": "2026-2027"
  }'
```

## List and read

- `GET /api/classes`: classes in your scope (a teacher sees their ClassTeacher classes; a manager
  sees their scoped schools' classes).
- `GET /api/classes/{id}`: one class.

## Assign a teacher (the ClassTeacher junction)

A class has no teacher FK. Teachers attach through the **ClassTeacher** junction, with a role:

```bash
curl -X POST https://localhost:3000/api/classes/{classId}/teachers \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{ "teacherUserId": 1, "role": "PRIMARY" }'
```

`role` is `PRIMARY` (default), `SECONDARY`, or `SUPPORT`. The call returns `201`
`ClassTeacherRowResponse`; assigning an already-assigned teacher returns `409`. Remove an assignment
with `DELETE /api/classes/{classId}/teachers/{teacherUserId}` (a soft unassign).

## List a class's teachers and students

- `GET /api/classes/{classId}/teachers` → `ClassTeacherListResponse`.
- `GET /api/classes/{classId}/students` → `StudentListResponse`.

## Enrollment model

Students are wired to classes through the **ClassStudent** junction. A student is in one active
instance of a class at a time; historical rows are retained.

> **Note:** **There is no standalone enroll endpoint in `1.0.0-phase0`.** Enroll a student by setting
> `classId` on the student's body when you create the user (see
> [Provision Users](https://docs.growamal.com/en/guides/provision-users/)); the student then shows up in
> `GET /api/classes/{classId}/students`.

## Regenerate a student's quickCode

`POST /api/students/{id}/quickcode/regen` issues a new 2-digit code (01–99) for the student's class login. Student codes never expire; they
change only when you regenerate one. The class's own login code is separate: it is valid for one year
(365 days) and is renewed with `POST /api/classes/{classId}/login-code/rotate` (the class-link panel on the
teacher's assessments and login-cards pages). The student-side login flow itself lives in
[Authentication → Student quickCode login](https://docs.growamal.com/en/authentication/).

## Delete a class

`DELETE /api/classes/{id}`. A class that still has students returns `409`; remove or reassign the
roster first.
