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 |
|---|---|
|
Application submitted, not yet enrolled (default) |
|
Currently enrolled student |
|
Graduated student |
|
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 descriptionteam_id- Multi-tenant team/campus IDcreated_at,updated_at,deleted_at- Timestampscreated_by_id,updated_by_id,deleted_by_id- Audit user IDsassigned_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 enrollmentenrollment_year- Year of enrollmentsace_regis_number- SACE registration numbersource- Lead source (direct,other)current_class_id- Current homeroom classprogram_id- Academic programuser_id- Linked user accountneed_canvas_sync- Flag for Canvas LMS sync
Person Fields (from Person interface)
avatar- Profile image URLfirst_name,last_name- Name componentsnickname- Optional nicknamefull_name_first_last,full_name_last_first- Computed full namesbirthdate- Date of birthgender-None,Male,Femaleemail- Email addressphone_mobile- Mobile phone numberpersonal_id_number- National ID numbernationality,ethnicity,religion- Demographics
Address Fields (4 address types)
Permanent Address:
country,province,district,wardaddress,address_ext
Current Address:
cur_country,cur_province,cur_district,cur_wardcur_address,cur_address_ext
Birth Place Address:
birth_place_country,birth_place_province,birth_place_district,birth_place_wardbirth_place_address,birth_place_address_ext
Birth Registration Address:
birth_regis_country,birth_regis_province,birth_regis_district,birth_regis_wardbirth_regis_address,birth_regis_address_ext
Mobile App Integration
app_active- Mobile app account activeapp_user- Mobile app usernameapp_pass- Mobile app password (write-only)app_last_login- Last mobile app login
LMS Integration
lms_active- LMS account activelms_id- Canvas LMS user IDlms_user- LMS usernamelms_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 codemoet_id- Ministry of Education IDfull_name_first_last- Full name (First Last)full_name_last_first- Full name (Last First)nickname- Student nicknameemail- Email address
Filterable Fields
Field |
Type |
Description |
|---|---|---|
|
text |
Student code |
|
enum |
Student status |
|
enum |
Gender |
|
int |
Year of enrollment |
|
relate |
Current homeroom class |
|
relate |
Academic program |
|
relate |
Campus/school |
|
date |
Date of birth |
|
bool |
LMS account active |
Canvas LMS Integration
When Canvas sync is enabled:
Student creation triggers Canvas user creation
Student updates sync to Canvas profile
Course enrollments sync to Canvas enrollments
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
}'