Students API

The Students module manages student profiles, enrollment, and related data.

Model

{
  "id": "uuid",
  "code": "STD001",
  "moet_id": "M12345678",
  "status": "active",
  "enrollment_date": "2024-09-01",
  "enrollment_year": 2024,

  "first_name": "John",
  "last_name": "Doe",
  "nickname": "Johnny",
  "name": "Doe John",
  "birthdate": "2010-05-15",
  "gender": "Male",
  "email": "john.doe@school.edu",
  "phone_mobile": "+84123456789",

  "avatar": "https://...",
  "personal_id_number": "123456789",
  "nationality": "Vietnam",
  "ethnicity": "Kinh",
  "religion": "None",

  "address": "123 Main Street",
  "district": "District 1",
  "province": "Ho Chi Minh City",
  "country": "Vietnam",

  "cur_address": "456 Current Street",
  "cur_district": "District 2",
  "cur_province": "Ho Chi Minh City",

  "current_class_id": "class-uuid",
  "current_class": { "id": "...", "name": "Class 10A" },

  "program_id": "program-uuid",
  "program": { "id": "...", "name": "Academic Program" },

  "lms_active": true,
  "lms_id": "canvas-123",
  "lms_user": "johndoe",

  "app_active": true,
  "app_user": "johndoe",

  "team_id": "team-uuid",
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-15T10:30:00Z"
}

Status Values

Status

Description

applicant

Application submitted, not yet enrolled (default)

active

Currently enrolled student

alumni

Graduated student

withdrawal

Withdrawn from school

Model Fields

The Student model embeds several interfaces for shared fields:

Base Fields (from BaseModel)

  • id - UUID primary key (auto-generated)

  • name - Display name (auto-generated from first/last name)

  • description - Optional description

  • team_id - Multi-tenant team/campus ID

  • created_at, updated_at, deleted_at - Timestamps

  • created_by_id, updated_by_id, deleted_by_id - Audit user IDs

  • assigned_to_id - Assigned staff member

Student-Specific Fields

  • code - Student code (auto-generated or manual)

  • moet_id - Ministry of Education ID (Vietnam)

  • status - Enrollment status (see above)

  • enrollment_date - Date of enrollment

  • enrollment_year - Year of enrollment

  • sace_regis_number - SACE registration number

  • source - Lead source (direct, other)

  • current_class_id - Current homeroom class

  • program_id - Academic program

  • user_id - Linked user account

  • need_canvas_sync - Flag for Canvas LMS sync

Person Fields (from Person interface)

  • avatar - Profile image URL

  • first_name, last_name - Name components

  • nickname - Optional nickname

  • full_name_first_last, full_name_last_first - Computed full names

  • birthdate - Date of birth

  • gender - None, Male, Female

  • email - Email address

  • phone_mobile - Mobile phone number

  • personal_id_number - National ID number

  • nationality, ethnicity, religion - Demographics

Address Fields (4 address types)

Permanent Address:

  • country, province, district, ward

  • address, address_ext

Current Address:

  • cur_country, cur_province, cur_district, cur_ward

  • cur_address, cur_address_ext

Birth Place Address:

  • birth_place_country, birth_place_province, birth_place_district, birth_place_ward

  • birth_place_address, birth_place_address_ext

Birth Registration Address:

  • birth_regis_country, birth_regis_province, birth_regis_district, birth_regis_ward

  • birth_regis_address, birth_regis_address_ext

Mobile App Integration

  • app_active - Mobile app account active

  • app_user - Mobile app username

  • app_pass - Mobile app password (write-only)

  • app_last_login - Last mobile app login

LMS Integration

  • lms_active - LMS account active

  • lms_id - Canvas LMS user ID

  • lms_user - LMS username

  • lms_pass - LMS password (write-only)

Endpoints

List Students

Endpoint: POST /api/students/list

Request:

{
  "page": 1,
  "limit": 20,
  "search": "john",
  "sort_field": "name",
  "sort_direction": "asc",
  "filter": {
    "group": "AND",
    "conditions": [
      {"field": "status", "operator": "=", "value": "active"},
      {"field": "current_class_id", "operator": "=", "value": "class-uuid"}
    ]
  },
  "preloads": ["CurrentClass", "Program"]
}

Response:

{
  "success": true,
  "message": "Records retrieved successfully",
  "data": {
    "list": [
      {
        "id": "student-uuid",
        "code": "STD001",
        "name": "Doe John",
        "status": "active",
        "current_class": { "id": "...", "name": "Class 10A" }
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 150
    }
  }
}

Get Student by ID

Endpoint: GET /api/students/:id

Response:

{
  "success": true,
  "message": "Record retrieved",
  "data": {
    "id": "student-uuid",
    "code": "STD001",
    "first_name": "John",
    "last_name": "Doe",
    "name": "Doe John",
    "email": "john.doe@school.edu",
    "status": "active",
    "current_class": { ... },
    "student_enroll_classes": [ ... ],
    "student_enroll_courses": [ ... ]
  }
}

Create Student

Endpoint: POST /api/students

Request:

{
  "first_name": "Jane",
  "last_name": "Smith",
  "email": "jane.smith@school.edu",
  "birthdate": "2010-05-15",
  "gender": "Female",
  "status": "applicant",
  "enrollment_date": "2024-09-01",
  "phone_mobile": "+84123456789",
  "address": "123 Main Street",
  "province": "Ho Chi Minh City",
  "current_class_id": "class-uuid",
  "program_id": "program-uuid"
}

Response:

{
  "success": true,
  "message": "Record created successfully",
  "data": {
    "id": "new-student-uuid",
    "code": "STD002",
    "first_name": "Jane",
    "last_name": "Smith",
    "status": "applicant"
  }
}

!!! note “Auto-generated Code” The code field is auto-generated if not provided. The format is defined in AutoCode settings.

Update Student

Endpoint: PUT /api/students/:id

Request:

{
  "status": "active",
  "current_class_id": "new-class-uuid",
  "phone_mobile": "+84987654321"
}

Delete Student

Endpoint: DELETE /api/students/:id

Soft-deletes the student record.

Bulk Create Students

Endpoint: POST /api/students/bulk

Request:

{
  "items": [
    { "first_name": "Student", "last_name": "One", ... },
    { "first_name": "Student", "last_name": "Two", ... }
  ]
}

Bulk Delete Students

Endpoint: DELETE /api/students/bulk

Request:

{
  "ids": ["student-uuid-1", "student-uuid-2"]
}

Export to Excel

Endpoint: POST /api/students/export

Request:

{
  "filter": {
    "group": "AND",
    "conditions": [
      {"field": "status", "operator": "=", "value": "active"}
    ]
  }
}

Response: Excel file download

Import from Excel

Endpoint: POST /api/students/import

Request: Multipart form data with Excel file

See Import System Guide for detailed import workflow.

Enrollment Endpoints

Get Student’s Class Enrollments

Endpoint: POST /api/students/list_relate/:student_id/student_enroll_classes/StudentEnrollClass

Lists all class enrollments for a student.

Enroll Student in Class

Endpoint: PUT /api/students/list_relate/:student_id/student_enroll_classes/StudentEnrollClass

Request:

{
  "ids": ["enrollment-uuid"]
}

Or create enrollment directly via the StudentEnrollClass endpoint.

Get Student’s Course Enrollments

Endpoint: POST /api/students/list_relate/:student_id/student_enroll_courses/StudentEnrollCourse

Special Endpoints

Force Canvas Sync

Trigger immediate sync of student data to Canvas LMS.

Endpoint: POST /api/students/:id/force-sync-canvas

Response:

{
  "success": true,
  "message": "Canvas sync triggered"
}

Searchable Fields

The search parameter queries these fields:

  • code - Student code

  • moet_id - Ministry of Education ID

  • full_name_first_last - Full name (First Last)

  • full_name_last_first - Full name (Last First)

  • nickname - Student nickname

  • email - Email address

Filterable Fields

Field

Type

Description

code

text

Student code

status

enum

Student status

gender

enum

Gender

enrollment_year

int

Year of enrollment

current_class_id

relate

Current homeroom class

program_id

relate

Academic program

team_id

relate

Campus/school

birthdate

date

Date of birth

lms_active

bool

LMS account active

Canvas LMS Integration

When Canvas sync is enabled:

  1. Student creation triggers Canvas user creation

  2. Student updates sync to Canvas profile

  3. Course enrollments sync to Canvas enrollments

  4. Assessment results sync from Canvas gradebook

Set need_canvas_sync: true to trigger sync on next job run.

Code Examples

JavaScript - List Active Students

const response = await fetch('/api/students/list', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'X-Team-ID': teamId,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    page: 1,
    limit: 50,
    filter: {
      group: 'AND',
      conditions: [
        { field: 'status', operator: '=', value: 'active' }
      ]
    },
    preloads: ['CurrentClass', 'Program']
  })
});

const data = await response.json();
console.log(data.data.list);

JavaScript - Create Student

const response = await fetch('/api/students', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'X-Team-ID': teamId,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    first_name: 'New',
    last_name: 'Student',
    email: 'new.student@school.edu',
    birthdate: '2010-01-15',
    gender: 'Male',
    status: 'applicant'
  })
});

const data = await response.json();
console.log('Created student:', data.data.code);

cURL - Search Students

curl -X POST http://localhost:8080/api/students/list \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Team-ID: $TEAM_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "search": "john",
    "page": 1,
    "limit": 20
  }'