Tài liệu này dành cho partner triển khai theo nhánh Tổ chức với endpoint:
POST /api/lms-base/learning-resources/organizations
Môi trường endpoint:
- Môi trường Production (
PROD):https://partner.hanoi.edu.vn/ - Môi trường Development (
DEV):https://lmsbpartnerapi.vstudy.edu.vn/
Lưu ý: các ví dụ curl trong tài liệu này đang dùng endpoint môi trường Development (DEV). Khi triển khai thật, đổi sang môi trường Production (PROD).
Nếu bạn tích hợp theo nhánh trường, chuyển sang Tích hợp cho Nhà trường.
1. Luồng tích hợp nhanh (happy path)
- Upload file qua
POST /api/lms-base/attachments. - Nhận
id+pathcủa từng file upload. - Replace URL trong HTML (
src/href/poster) bằngpathđã upload. - Gọi
POST /api/lms-base/learning-resources/organizations(upsert theopartnerId + sourceId). - Poll duyệt bằng
GET /api/lms-base/learning-resources/organizationsvớiapprovalStatus.
2. Checklist trước khi gọi API
- Đã có
X-Api-Keyhợp lệ. sourceIdlà mã do partner quản lý và dùng ổn định trong scopepartnerId; chỉ chấp nhận văn bản thuần, không chứa HTML.gradeCode/subjectCode/knowledgeUnitCodemap đúng danh mục dùng chung: knowledge-units.authorPinCode/authorName/creatorPinCode/creatorNamecó thể để trống, hệ thống có thể tự điền mặc định theo thông tin tổ chức.- Ở endpoint
/learning-resources/organizations, hệ thống tự gán ngữ cảnh cố định:doetCode = "01",divisionCode = "",schoolCode = ""(giá trị gửi lên trong request không dùng để xử lý nghiệp vụ). title,authorName,creatorName,contents[].namechỉ chấp nhận văn bản thuần, không chứa HTML (các trường để trống thì không kiểm tra).description(nếu truyền) cho phép văn bản hoặc HTML an toàn, tối đa 1024 ký tự.thumbnailUrllà bắt buộc và phải là URL tuyệt đối hợp lệ (ảnh đã upload hoặc URL ảnh ngoài đúng định dạng hỗ trợ).contentslà bắt buộc và phải có ít nhất 1 phần tử.- Giới hạn request upload của API là
<= 1073741824bytes (1 GB); từng định dạng tệp vẫn có thể bị giới hạn thấp hơn theo cấu hình hệ thống. - Nếu có
fileIds, tất cả id phải được dùng thực sự trongthumbnailUrlhoặccontents. contentskiểuTEXTkhông chứa thành phần HTML cấm (iframe,object,embed, script/CSS không an toàn...).contentskiểuYOUTUBEchỉ nhận URL dạnghttps://youtube.com/watch?v=...(bao gồmwww.youtube.com/watch?v=...) hoặchttps://youtu.be/..., không gửi iframe/embed.contentskiểuIFRAMEchỉ nhận URL tuyệt đối (http/https) có domain/subdomain thuộc danh sách cho phép (mặc địnhyoutube.com,olm.vn,sgk.olm.vn); truyền URL, không gửi thẻ<iframe>.
3. Ví dụ end-to-end
3.1. HTML ban đầu
<p>Bài giảng video:</p>
<video controls poster="https://partner.example.com/media/thumb-hinh-hoc.png">
<source src="https://partner.example.com/media/video-hinh-hoc.mp4" type="video/mp4" />
</video>3.2. Upload attachments
curl --location 'https://lmsbpartnerapi.vstudy.edu.vn/api/lms-base/attachments' \
--header 'X-Api-Key: <api-key-don-vi-duoc-cap>' \
--form 'doetCode="01"' \
--form 'divisionCode=""' \
--form 'schoolCode=""' \
--form 'educationLevelCode="02"' \
--form 'file=@"/path/to/thumb-hinh-hoc.png"'Scope tổ chức cho phép để trống schoolCode ("") khi upload attachments.
Ví dụ kết quả upload:
- Thumbnail:
id=01JQ2S96MKZ8E8GHW8EXB4VPA7,path=https://<cdn-or-storage>/partner-code/thumb-hinh-hoc.png - Video:
id=01JQ2SAXA9QXRVQ8S9QPA4J2AN,path=https://<cdn-or-storage>/partner-code/video-hinh-hoc.mp4
3.3. HTML sau replace URL
<p>Bài giảng video:</p>
<video controls poster="https://<cdn-or-storage>/partner-code/thumb-hinh-hoc.png">
<source src="https://<cdn-or-storage>/partner-code/video-hinh-hoc.mp4" type="video/mp4" />
</video>3.4. Gọi create/update học liệu (scope tổ chức)
curl --location 'https://lmsbpartnerapi.vstudy.edu.vn/api/lms-base/learning-resources/organizations' \
--header 'X-Api-Key: <api-key-don-vi-duoc-cap>' \
--header 'Content-Type: application/json' \
--data '{
"sourceId": "LR-ORG-000001",
"title": "Bài học: Hình học cơ bản",
"description": "Nội dung giới thiệu hình học cơ bản cho học sinh trung học cơ sở.",
"thumbnailUrl": "https://<cdn-or-storage>/partner-code/thumb-hinh-hoc.png",
"authorPinCode": "",
"authorName": "",
"creatorPinCode": "",
"creatorName": "",
"fileIds": [
"01JQ2S96MKZ8E8GHW8EXB4VPA7",
"01JQ2SAXA9QXRVQ8S9QPA4J2AN"
],
"contents": [
{
"name": "Video tải lên",
"displayOrder": 1,
"type": "VIDEO",
"content": "https://<cdn-or-storage>/partner-code/video-hinh-hoc.mp4",
"description": "Video chính"
},
{
"name": "Video YouTube tham khảo",
"displayOrder": 2,
"type": "YOUTUBE",
"content": "https://www.youtube.com/watch?v=d3bn7DVrZOw",
"description": "Video tham khảo"
}
],
"gradeCode": "06",
"subjectCode": "0601",
"knowledgeUnitCode": "201100101",
"doetCode": "",
"divisionCode": "",
"schoolCode": "",
"yearCode": 2025,
"educationLevelCode": "02",
"semesterCode": 1
}'Response thành công:
{
"success": true,
"message": "Tạo mới học liệu số thành công.",
"data": {
"sourceId": "LR-ORG-000001",
"id": "01JQ2T5W11Z9J6AEX4Q6F90HME",
"approvalStatus": 0,
"operation": "created"
}
}operation:
created: tạo mới.updated: cập nhật bản ghi cùngpartnerId + sourceIdkhi bản ghi cũ đangPendinghoặcRejected.
4. Theo dõi duyệt
Khuyến nghị dùng webhook learning-resource.status-changed: Trục LMS chủ động gọi về WebhookUrl của partner khi học liệu đổi trạng thái (Approved/Rejected/Hidden/Removed). Chi tiết payload, headers, xác minh chữ ký HMAC và retry xem Tổng quan tích hợp – mục 7.6.
Ngoài ra có thể dùng polling API danh sách để đối soát/dự phòng:
curl --location --get 'https://lmsbpartnerapi.vstudy.edu.vn/api/lms-base/learning-resources/organizations' \
--header 'X-Api-Key: <api-key-don-vi-duoc-cap>' \
--data-urlencode 'approvalStatus=0' \
--data-urlencode 'sourceId=LR-ORG-000001' \
--data-urlencode 'skip=0' \
--data-urlencode 'take=20'Response thành công:
{
"success": true,
"message": "Lấy danh sách học liệu thành công.",
"data": [
{
"id": "01JQ2T5W11Z9J6AEX4Q6F90HME",
"sourceId": "LR-ORG-000001",
"title": "Bài học: Hình học cơ bản",
"status": "Pending",
"reason": null,
"occurredAt": "2026-04-12T07:12:44.0000000Z",
"canDelete": true,
"createdAt": "2026-04-12T07:12:44.0000000Z",
"updatedAt": "2026-04-12T07:12:44.0000000Z"
}
]
}status: trạng thái hiện tại dạng chuỗi (xem bên dưới).reason: lý do theo trạng thái hiện tại (có khiRejected/Removed).occurredAt: thời điểm UTC trạng thái hiện tại được ghi nhận.
Giá trị status (chi tiết trường response ở Tổng quan tích hợp – mục 7.1):
Pending: chờ duyệtApproved: đã duyệtRejected: từ chối (kèmreason)Hidden: tạm ẩnRemoved: gỡ bỏ (kèmreason)
Query param approvalStatus để lọc vẫn dùng số (0=Pending, 1=Approved, 2=Rejected).
5. Xóa học liệu pending
Chỉ xóa được bản ghi do partner tạo và còn Pending:
5.1. Dữ liệu đầu vào
- Request body:
string[](danh sách id ULID học liệu cần xóa). - Ràng buộc: mảng không rỗng, không trùng id, tối đa
200id/lần.
5.2. Mô hình phản hồi
- API trả về envelope:
success,message,data. data[]gồm:sourceId,id,deleted,message,processedAt.- Có thể xảy ra thành công một phần: HTTP
200nhưng một số phần tử códeleted = false.
5.3. Ví dụ request
curl --location --request DELETE 'https://lmsbpartnerapi.vstudy.edu.vn/api/lms-base/learning-resources/organizations' \
--header 'X-Api-Key: <api-key-don-vi-duoc-cap>' \
--header 'Content-Type: application/json' \
--data '[
"01JQ2T5W11Z9J6AEX4Q6F90HME"
]'5.4. Ví dụ response
Response thành công:
{
"success": true,
"message": "Xử lý xóa 1 học liệu, xóa thành công 1, thất bại 0.",
"data": [
{
"sourceId": "LR-ORG-000001",
"id": "01JQ2T5W11Z9J6AEX4Q6F90HME",
"deleted": true,
"message": "Xóa học liệu thành công.",
"processedAt": "2026-04-14T02:00:00.0000000Z"
}
]
}6. Reference dùng chung
- Tài liệu tổng quan + rule validate đầy đủ: Hướng dẫn tích hợp API Chia sẻ học liệu
- Hướng dẫn API tải học liệu đã duyệt: Tải học liệu đã duyệt
- Danh mục mapping mã dùng chung: knowledge-units
