API đẩy chỉ số thống kê cấp người dùng (giáo viên, học sinh) lên hệ thống DTI. Xem Tổng quan tích hợp DTI để biết thông tin kết nối và cấu hình push.
Lưu ý: LMS cần aggregate dữ liệu per-user trước khi push. Hệ thống DTI không nhận raw events — chỉ nhận giá trị đã tổng hợp cho từng user.
1. Endpoint
- Method:
POST - Path:
/api/v1/lms/hub/push/users - Batch: 1 trường/request, tối đa 500 users
2. Request body
{
"provdoet_code": "01",
"school_code": "SCHOOL_001",
"school_level": "03",
"school_year_code": 2025,
"semester_code": 1,
"measured_at": "2026-04-14T23:00:00.000Z",
"users": [
{
"user_pin": "GV_001",
"metrics": [
{ "key": "total_lessons", "value": 5, "subject_code": "0101", "grade_code": "09", "dim_value": "video" },
{ "key": "total_tests", "value": 2, "subject_code": "0101", "grade_code": "09" },
{ "key": "total_shared_to_hub", "value": 3, "subject_code": "0101", "grade_code": "09", "dim_value": "document" },
{ "key": "teacher_online_duration", "value": 240, "subject_code": "0101" }
]
},
{
"user_pin": "HS_001",
"metrics": [
{ "key": "total_exercises_submitted", "value": 28, "subject_code": "0101", "grade_code": "09" },
{ "key": "student_online_duration", "value": 120, "subject_code": "0101" }
]
}
]
}json
3. Mô tả các fields
Top-level fields
| Field | Bắt buộc | Type | Mô tả |
|---|---|---|---|
provdoet_code | Có | string (max 10) | Mã Sở GD&ĐT |
school_code | Có | string (max 50) | Mã trường |
school_level | Có | string | 01-05 (Mầm non → GDTX) |
school_year_code | Có | integer | Năm học: 2025, 2026, ... |
semester_code | Có | integer | 1 hoặc 2 |
measured_at | Có | string (ISO 8601) | Thời điểm đo |
users | Có | array | Danh sách users (tối đa 500) |
User object
| Field | Bắt buộc | Type | Mô tả |
|---|---|---|---|
user_pin | Có | string (max 100) | Mã định danh người dùng trên LMS |
metrics | Có | array | Danh sách chỉ số |
Metric item
| Field | Bắt buộc | Type | Mô tả |
|---|---|---|---|
key | Có | string | Mã metric |
value | Có | number | Giá trị |
subject_code | Có * | string (tối đa 4 ký tự số) | Mã chương trình môn học. Bắt buộc cho metrics có requires_subject_code: true. Xem giải thích |
grade_code | Có * | string (2 ký tự số) | Mã khối/lớp. Bắt buộc cho metrics có requires_grade_code: true. VD: 09 = Khối 9 |
dim_value | Không | string | Loại nội dung (cho total_lessons, total_shared_to_hub): video, scorm, document, ... |
4. Danh sách chỉ số cấp user
| Key | Tên chỉ số | Đơn vị | subject_code | grade_code | dim_value | Đối tượng |
|---|---|---|---|---|---|---|
total_lessons | Số học liệu | lessons | Bắt buộc | Bắt buộc | Loại bài giảng | GV |
total_tests | Số bài kiểm tra | lessons | Bắt buộc | Bắt buộc | — | GV |
total_exercises_assigned | Số bài tập đã giao | lessons | Bắt buộc | Bắt buộc | — | GV |
total_questions_bank | Câu hỏi ngân hàng | questions | Bắt buộc | — | — | GV |
total_shared_to_hub | Học liệu GV chia sẻ lên Trục | lessons | Bắt buộc | Bắt buộc | Loại bài giảng | GV |
teacher_online_duration | Thời lượng GV dạy | minutes | Bắt buộc | — | — | GV |
total_exercises_submitted | Bài tập HS đã nộp | lessons | Bắt buộc | Bắt buộc | — | HS |
student_online_duration | Thời lượng HS học | minutes | Bắt buộc | — | — | HS |
* Kiểm tra
requires_subject_codevàrequires_grade_codetrong response của/hub/metrics/push-configđể biết chính xác metric nào bắt buộc field nào. Thiếu field bắt buộc sẽ bị reject với reasonmissing_subject_codehoặcmissing_grade_code.
5. Response
{
"data": {
"total": 12,
"accepted": 12,
"rejected": 0,
"rejected_details": []
},
"message": "OK"
}json
6. Ví dụ request đầy đủ
curl -X POST https://dtiapi.vstudy.edu.vn/api/v1/lms/hub/push/users \
-H "X-Api-Key: <api-key-don-vi-duoc-cap>" \
-H "Content-Type: application/json" \
-d '{
"provdoet_code": "01",
"school_code": "SCHOOL_001",
"school_level": "03",
"school_year_code": 2025,
"semester_code": 1,
"measured_at": "2026-04-14T23:00:00.000Z",
"users": [
{
"user_pin": "GV_001",
"metrics": [
{ "key": "total_lessons", "value": 5, "subject_code": "0101", "grade_code": "09", "dim_value": "video" },
{ "key": "total_lessons", "value": 2, "subject_code": "0101", "grade_code": "09", "dim_value": "scorm" },
{ "key": "total_lessons", "value": 3, "subject_code": "0201", "grade_code": "09", "dim_value": "document" },
{ "key": "total_tests", "value": 2, "subject_code": "0101", "grade_code": "09" },
{ "key": "total_tests", "value": 1, "subject_code": "0201", "grade_code": "09" },
{ "key": "total_exercises_assigned", "value": 15, "subject_code": "0101", "grade_code": "09" },
{ "key": "total_questions_bank", "value": 45, "subject_code": "0101" },
{ "key": "total_shared_to_hub", "value": 3, "subject_code": "0101", "grade_code": "09", "dim_value": "document" },
{ "key": "total_shared_to_hub", "value": 1, "subject_code": "0201", "grade_code": "09", "dim_value": "video" },
{ "key": "teacher_online_duration", "value": 240, "subject_code": "0101" }
]
},
{
"user_pin": "HS_001",
"metrics": [
{ "key": "total_exercises_submitted", "value": 28, "subject_code": "0101", "grade_code": "09" },
{ "key": "total_exercises_submitted", "value": 15, "subject_code": "0201", "grade_code": "09" },
{ "key": "student_online_duration", "value": 120, "subject_code": "0101" }
]
}
]
}'bash
