Công việc
Tổng quan
| Method + path | Dùng để |
|---|---|
GET /task-boards | Danh sách board kèm cột, nhãn, thành viên |
GET /tasks | Liệt kê công việc để đồng bộ (keyset), gồm cả công việc đã xoá |
GET /tasks/:id | Một công việc |
POST /tasks | Tạo công việc |
PATCH /tasks/:id | Sửa tiêu đề, mô tả, ưu tiên, người, hạn, nhãn |
POST /tasks/:id/status | Chuyển cột hoặc trạng thái |
POST /tasks/:id/complete · /reopen · /cancel | Hoàn thành, mở lại, huỷ |
Mọi endpoint cần scope tasks_manage.
Key chỉ thấy board mà người tạo key là thành viên
Board công việc là không gian riêng: key đứng tên người tạo key, nên chỉ thấy các board người đó là thành viên, và chỉ ghi được khi người đó có vai trò Chỉnh sửa trở lên. Muốn tích hợp đọc / ghi một board, hãy thêm tài khoản tạo key vào board đó. Board hay công việc không xem được trả 404 như không tồn tại.
| Vai trò của người tạo key trên board | Qua API làm được |
|---|---|
| Xem / Bình luận | Đọc board và công việc |
| Chỉnh sửa | Đọc + tạo, sửa, đổi trạng thái, hoàn thành |
| Quản trị / Chủ sở hữu | như trên, và không bị chặn bởi cột cần duyệt |
Chuẩn bị dữ liệu để tạo công việc
| Cần | Lấy ở |
|---|---|
boardId, status (key cột), labelIds | GET /task-boards |
assigneeId, watcherIds | members của board — người phụ trách phải có vai trò editor trở lên |
| Khách hàng / đơn hàng để liên kết | GET /customers, GET /orders |
Board
GET /api/open/v1/task-boards
{
"data": [
{
"id": "1c3e5a7b-9d2f-4b6a-8c0e-2f4a6c8e0b1d",
"name": "Chăm sóc sau bán",
"description": null,
"status": "active",
"columns": [
{ "key": "todo", "label": "Cần làm", "systemStatus": "todo", "requiresApproval": false },
{ "key": "in_progress", "label": "Đang làm", "systemStatus": "in_progress", "requiresApproval": false },
{ "key": "review", "label": "Chờ duyệt", "systemStatus": "review", "requiresApproval": true },
{ "key": "done", "label": "Xong", "systemStatus": "done", "requiresApproval": false }
],
"labels": [{ "id": "6a1f…", "name": "Gọi lại", "color": "#2563EB" }],
"members": [
{ "userId": "7a1e…", "role": "owner" },
{ "userId": "9e90…", "role": "editor" }
],
"myRole": "editor"
}
]
}
- Trả tối đa 100 board.
myRolelà vai trò của người tạo key. columns[].keylà giá trịstatuscủa công việc.systemStatuslà trạng thái chuẩn mà cột gắn (todo·in_progress·review·done·cancelled);null= cột chỉ để phân loại, công việc tự giữ trạng thái.requiresApproval: công việc phải được duyệt ở cột này mới đi tiếp được.
Đối tượng công việc
{
"id": "8b0d2f4a-6c1e-4a3b-9d5f-7e9a1c3b5d7f",
"externalId": "CRM-TASK-881",
"boardId": "1c3e5a7b-9d2f-4b6a-8c0e-2f4a6c8e0b1d",
"parentTaskId": null,
"title": "Gọi lại xác nhận đơn DH-1001",
"description": null,
"status": "in_progress",
"systemStatus": "in_progress",
"priority": "high",
"labelIds": ["6a1f…"],
"assigneeId": "9e90…",
"watcherIds": [],
"startDate": null,
"dueAt": "2026-10-25T00:00:00.000Z",
"dueHasTime": false,
"startedAt": "2026-10-23T03:00:00.000Z",
"completedAt": null,
"approvedAt": null,
"approvedById": null,
"links": [
{ "targetType": "customer", "targetId": "1f0c6a7e-5d1b-4a8e-9a63-2c1f0f6b9d10" },
{ "targetType": "order", "targetId": "b7c2…" }
],
"createdById": "9e90…",
"source": "api:CRM Sync",
"createdAt": "2026-10-23T02:55:00.000Z",
"updatedAt": "2026-10-23T03:00:00.000Z",
"deletedAt": null
}
| Trường | Ghi chú |
|---|---|
status | key của cột trong board |
systemStatus | todo · in_progress · review · done · cancelled |
priority | urgent · high · medium · low |
dueAt + dueHasTime | dueHasTime: false ⇒ hạn chỉ có ngày, dueAt là 00:00 UTC của ngày đó |
links | Khách hàng / đơn hàng / cơ hội / hội thoại được liên kết (targetType: customer · order · opportunity · conversation) |
parentTaskId | Có giá trị ⇒ đây là việc con |
source | Nguồn lần ghi cuối: ui hoặc api:<tên key> |
deletedAt | Có giá trị ⇒ công việc đã bị xoá |
Đọc công việc
GET /api/open/v1/tasks?updatedSince=2026-10-01T00:00:00Z&limit=50&boardId=1c3e…&excludeSource=api:CRM%20Sync
GET /api/open/v1/tasks/8b0d…
- Liệt kê theo keyset: tối đa 50 công việc / lần, cửa sổ tối đa 30 ngày. Trả cả công việc đã xoá (
deletedAtcó giá trị) để bạn xoá bên mình. - Bộ lọc thêm:
boardId,systemStatus,assigneeId,customerId,orderId(công việc liên kết với khách / đơn đó). - Gồm công việc trên các board người tạo key là thành viên, và công việc người đó được giao / theo dõi.
GET /tasks/:idtrả{ "data": công việc }, hoặc404 OPEN_API_TASK_NOT_FOUND.
Tạo công việc
POST /api/open/v1/tasks
- Request Body
- Response
{
"externalId": "CRM-TASK-881",
"boardId": "1c3e5a7b-9d2f-4b6a-8c0e-2f4a6c8e0b1d",
"title": "Gọi lại xác nhận đơn DH-1001",
"status": "todo",
"priority": "high",
"assigneeId": "9e90…",
"dueAt": "2026-10-25T00:00:00Z",
"dueHasTime": false,
"labelIds": ["6a1f…"],
"checklistItems": ["Xác nhận địa chỉ", "Xác nhận giờ giao"],
"links": [
{ "targetType": "customer", "targetId": "1f0c6a7e-5d1b-4a8e-9a63-2c1f0f6b9d10" },
{ "targetType": "order", "targetId": "b7c2…" }
]
}
{ "data": { "id": "8b0d…", "externalId": "CRM-TASK-881", "status": "todo", "…": "…" }, "created": true }
| Trường | Kiểu | Ghi chú |
|---|---|---|
boardId | uuid | Bắt buộc |
title | chuỗi ≤ 500 | Bắt buộc |
externalId | chuỗi ≤ 100 | Nên gửi — gửi lại cùng mã ⇒ trả công việc đã có (200, "created": false) |
status | chuỗi | key cột; không gửi ⇒ cột đầu tiên |
parentTaskId | uuid | Tạo việc con của công việc này (phải cùng board) |
description | chuỗi ≤ 10000 | |
priority | chuỗi | urgent · high · medium (mặc định) · low |
assigneeId | uuid | Thành viên board vai trò editor trở lên |
watcherIds | mảng uuid | Thành viên board |
startDate | YYYY-MM-DD | |
dueAt, dueHasTime | ISO 8601, boolean | Xem đối tượng |
labelIds | mảng uuid | Nhãn của board |
checklistItems | mảng chuỗi ≤ 50 | Các mục checklist tạo cùng công việc |
links | mảng ≤ 20 | { "targetType", "targetId" } — id khách hàng / đơn hàng / cơ hội / hội thoại của MiniAI SCRM |
Tạo mới trả 201. Người phụ trách nhận thông báo như khi tạo trên giao diện.
Sửa công việc
PATCH /api/open/v1/tasks/8b0d…
{ "title": "Gọi lại lần 2", "priority": "urgent", "assigneeId": null, "dueAt": "2026-10-26T09:00:00+07:00", "dueHasTime": true }
Gửi trường nào sửa trường đó: title, description, priority, assigneeId (null = bỏ giao), watcherIds (thay toàn bộ), startDate, dueAt, dueHasTime, labelIds. Trả { "data": công việc }. Đổi cột không đi qua PATCH — dùng các endpoint bên dưới.
Đổi cột, hoàn thành, mở lại, huỷ
POST /api/open/v1/tasks/8b0d…/status { "status": "in_progress" }
POST /api/open/v1/tasks/8b0d…/status { "systemStatus": "review" }
POST /api/open/v1/tasks/8b0d…/complete
POST /api/open/v1/tasks/8b0d…/reopen
POST /api/open/v1/tasks/8b0d…/cancel
status: chuyển sang cột cókeynày; trạng thái đi theo cột nếu cột có gắn.systemStatus: đặt trạng thái — công việc sang cột gắn trạng thái đó (nếu có). Gửi cả hai thì cột thắng.complete= đặt trạng tháidone;reopenđưa về trạng thái và cột trước khi xong / huỷ;cancel=cancelled.- Đều trả
{ "data": công việc }sau khi đổi, và tuân theo quy tắc của board: cột cần duyệt chặn đi tiếp khi chưa được duyệt (trừ Quản trị / Chủ sở hữu).
Lỗi thường gặp
| Code | HTTP | Khi nào |
|---|---|---|
OPEN_API_TASK_NOT_FOUND | 404 | Công việc (hoặc việc cha) không tồn tại, hoặc người tạo key không xem được |
OPEN_API_TASK_BOARD_NOT_FOUND | 404 | Board không tồn tại, hoặc người tạo key không phải thành viên |
TASK_BOARD_ROLE_INSUFFICIENT | 403 | Người tạo key là thành viên nhưng vai trò không đủ (VD chỉ Xem mà gọi API ghi) |
TASK_ASSIGNEE_ROLE_INVALID | 400 | Người phụ trách không phải thành viên vai trò editor trở lên |
TASK_WATCHER_NOT_MEMBER | 400 | Người theo dõi không phải thành viên board |
TASK_ASSIGNEE_INVALID | 400 | Người phụ trách không thuộc cửa hàng |
TASK_LABEL_INVALID | 400 | Nhãn không thuộc board |
TASK_LINK_TARGET_NOT_FOUND | 404 | Khách / đơn / cơ hội / hội thoại trong links không tồn tại |
TASK_APPROVAL_REQUIRED | 400 | Công việc đang ở cột cần duyệt và chưa được duyệt (params.column) |
TASK_APPROVAL_SKIP | 400 | Chuyển vượt qua một cột cần duyệt (params.column) |
Các mã chung (xác thực, giới hạn, keyset) xem Tổng quan → Lỗi.