PJT AI REST API
Một REST API chuẩn để tích hợp dữ liệu PJT AI với các hệ thống bên ngoài. Mọi yêu cầu và phản hồi đều ở định dạng JSON, và URL cơ sở là https://api.pjt.ai/api/external/v1.
- Xác thực — header X-API-Key (API key tài khoản, tiền tố pjt_)
- Phạm vi khóa — read (chỉ đọc, mặc định) / write. POST·PUT·DELETE cần khóa có phạm vi write — nếu không sẽ trả về 403 SCOPE_FORBIDDEN
- Giới hạn — 60 req/phút + 10.000 req/tháng mỗi khóa (Enterprise thỏa thuận)
- Mã phản hồi — 2xx thành công, 4xx lỗi máy khách, 5xx lỗi máy chủ
- Ngày tháng — mọi dấu thời gian đều ở định dạng ISO 8601 (UTC)
Xác thực
Mọi yêu cầu đều cần header X-API-Key: <API_KEY> . Cấp khóa tại Cài đặt tài khoản > API key (chỉ hiển thị một lần khi tạo).
/meAPI key của tôi (kiểm tra kết nối)
Trả về tính hợp lệ và năng lực (scope) của API key. Vì là GET nên không cần scope write — kể cả key chỉ đọc cũng xem được năng lực của chính nó. Key thiếu/không hợp lệ/hết hạn trả về 401, và đó chính là kết quả kiểm tra kết nối. Dùng canProvision/canWrite/canRead trong phản hồi để kiểm tra khả năng trước (vd: nếu canProvision=false, cảnh báo trước khi gọi cấp phát → tránh báo xanh sai). Khác với liveness hạ tầng (máy chủ có sống không).
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn — chính 401 này là tín hiệu 'chưa kết nối' (200 = đã kết nối).{
"timestamp": "2026-07-14T09:00:00Z",
"message": "API key is missing, invalid, or expired."
}/provisioning/workspacesChỉ EnterpriseCấp phát workspace (idempotent)
Cấp phát tenant và workspace trong một lần gọi bằng API key phạm vi provisioning. Gửi tenantId để dùng tenant đó (tài khoản của key phải là OWNER/ADMIN); nếu không, tenantExternalRef sẽ tìm/tạo tenant một cách idempotent trong không gian tên tài khoản (400 nếu không có cả hai). workspaceExternalRef là khóa idempotent bắt buộc — gọi lại trả về tài nguyên hiện có (200) thay vì tạo mới (201); createdTenant/createdWorkspace để phân biệt. Phân cấp phạm vi: provisioning ⊃ write (không cần write riêng). ⚠️ businessType hiện chưa ảnh hưởng kết quả (chỉ audit); defaultLocale/accentHue/template kiểm tra lỏng (gửi đúng giá trị; template lạ bị bỏ qua); tenant.myRole trong phản hồi có thể null — đừng dùng để phân quyền.
Endpoint này chỉ khả dụng ở gói Enterprise. Việc phát hành và sử dụng key phạm vi cấp phát được bao gồm trong hợp đồng Enterprise.
| Tên | Kiểu | Mô tả |
|---|---|---|
| tenantId | integer | ID tenant hiện có (Long, tùy chọn). Nếu có, tenant·tenantExternalRef bị bỏ qua. Tài khoản của key phải là OWNER/ADMIN của tenant đó |
| tenantExternalRef | string | Khóa idempotent của tenant mới (≤100, khi không có tenantId). Cùng (tài khoản, giá trị) sẽ dùng lại tenant hiện có |
| tenant.name | string | Tên tenant mới (≤100, dùng workspace.name nếu bỏ trống) |
| tenant.slug | string | Slug tenant mới (≤50, duy nhất toàn cục·tự sinh nếu bỏ trống) |
| tenant.description | string | Mô tả tenant mới (≤500) |
| workspaceExternalRefBẮT BUỘC | string | Khóa idempotent của workspace (≤100, bắt buộc). Cùng (tenantId, giá trị) sẽ dùng lại workspace hiện có |
| workspace.nameBẮT BUỘC | string | Tên workspace (≤100, bắt buộc) |
| workspace.slug | string | Slug workspace (≤50, duy nhất trong tenant·suy ra từ tên nếu bỏ trống) |
| workspace.description | string | Mô tả workspace (≤500) |
| workspace.defaultLocale | string | Locale mặc định — ko|en|ja|zh|zh-TW|es|vi|th (không kiểm tra; gửi đúng giá trị) |
| workspace.accentHue | integer | Sắc màu nhấn (0–360, không kiểm tra) |
| workspace.template | string | Preset — BLANK|DEV|AGENCY|OPS (giá trị lạ bị bỏ qua) |
| workspace.businessType | string | Loại hình kinh doanh (định hướng tương lai) — chỉ audit; không phản ánh vào workspace đã tạo |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
SCOPE_FORBIDDENGhi bằng key chỉ đọc (không có scope write) — bị bộ lọc gateway chặn{
"error": "SCOPE_FORBIDDEN",
"message": "This API key is read-only. A 'write' scope is required for this operation."
}FORBIDDENKey không có scope provisioning — endpoint này yêu cầu provisioning (chỉ write là không đủ){
"timestamp": "2026-07-14T09:00:00Z",
"message": "The 'provisioning' scope is required."
}FORBIDDENKhi cung cấp tenantId hiện có, tài khoản gọi không phải OWNER/ADMIN (hoặc không phải thành viên) của tenant đó{
"timestamp": "2026-07-14T09:00:00Z",
"message": "OWNER or ADMIN role on the tenant is required."
}BAD_REQUESTKhông gửi cả tenantId lẫn tenantExternalRef{
"timestamp": "2026-07-14T09:00:00Z",
"message": "One of tenantId or tenantExternalRef is required."
}VALIDATION_ERRORXác thực thất bại (bắt buộc/độ dài, v.v.) — chi tiết từng trường trong errors[]{
"timestamp": "2026-07-14T09:00:00Z",
"code": "VALIDATION_ERROR",
"message": "workspaceExternalRef: must not be blank",
"errors": [
{ "field": "workspaceExternalRef", "code": "NotBlank", "message": "must not be blank" }
]
}UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn (chung cho mọi endpoint External){
"timestamp": "2026-07-14T09:00:00Z",
"message": "API key is missing, invalid, or expired."
}/tenantsTenant của tôi
Trả về mọi tenant mà tài khoản của API key thuộc về (thành viên trực tiếp của tenant + tổ chức chỉ tiếp cận được qua một workspace = MEMBER). Vì là GET nên scope read là đủ. Xét quyền theo myRole của từng mục (OWNER|ADMIN|MEMBER) — tạo workspace (POST /workspaces) chỉ khả dụng trên tenant có myRole ∈ [OWNER, ADMIN], nên client SI chọn id của một mục OWNER/ADMIN ở đây và dùng làm tenantId.
| Tên | Kiểu | Mô tả |
|---|---|---|
| id | Long | ID tenant — dùng làm tenantId trong POST /workspaces |
| myRole | String (enum) | OWNER | ADMIN | MEMBER (null nếu không phải thành viên). Chỉ có thể tạo workspace (POST /workspaces) trên tenant mà bạn là OWNER hoặc ADMIN |
| status | String (enum) | Trạng thái tenant — ACTIVE | ARCHIVED | DELETE (Tenant.Status) |
| slug | String | Slug của tổ chức (dùng để định tuyến) |
| mfaSetupRequired | boolean | true nếu tổ chức bắt buộc 2FA và chưa thiết lập |
| slugSet | boolean | Người dùng có tự đặt slug hay không (org-xxxx tự tạo là false) |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn (chung cho mọi endpoint External){
"timestamp": "2026-07-14T20:00:00Z",
"message": "API key is missing, invalid, or expired."
}/tenants/{tenantId}Một tenant
Trả về một tenant với cùng shape như danh sách. Nếu bạn không thuộc về nó, kiểm tra truy cập thất bại (403); tenant không tồn tại trả về 400 tenant.not_found. Scope read là đủ.
| Tên | Kiểu | Mô tả |
|---|---|---|
| tenantIdBẮT BUỘC | integer | ID tenant cần lấy (Long, bắt buộc) |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
FORBIDDENTài khoản gọi không phải thành viên của tenant đó (kiểm tra truy cập tenant thất bại){
"timestamp": "2026-07-14T20:00:00Z",
"message": "테넌트 멤버가 아닙니다"
}BAD_REQUESTTenant không tồn tại (tenant.not_found){
"timestamp": "2026-07-14T20:00:00Z",
"message": "테넌트를 찾을 수 없습니다"
}UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn (chung cho mọi endpoint External){
"timestamp": "2026-07-14T20:00:00Z",
"message": "API key is missing, invalid, or expired."
}/workspacesTạo workspace (tenant hiện có)
Một đường đi nhẹ, tách biệt với cấp phát — KHÔNG tạo tenant; chỉ tạo workspace dưới một tenant hiện có (tenantId). Scope write là đủ (không cần provisioning; key chỉ đọc nhận 403 SCOPE_FORBIDDEN). Tài khoản của key phải là OWNER/ADMIN của tenant đó. Nếu truyền externalRef thì idempotent — gọi lại với cùng (tenantId, externalRef) trả về workspace hiện có với 200 thay vì tạo mới (201); nếu bỏ trống, mỗi lần gọi đều tạo workspace mới (khuyến nghị truyền để thử lại an toàn). Workspace được tạo là workspace nhóm (không phải cá nhân). ⚠️ defaultLocale/accentHue/template kiểm tra lỏng (giá trị đi qua nguyên vẹn; template lạ bị bỏ qua). Nếu cần tenant tự tạo, dùng cấp phát (POST /provisioning/workspaces).
| Tên | Kiểu | Mô tả |
|---|---|---|
| tenantIdBẮT BUỘC | integer | Tạo dưới tenant này (Long, bắt buộc). Tài khoản của key phải là OWNER/ADMIN của nó |
| externalRef | string | Khóa idempotent (≤100, tùy chọn). Gọi lại với cùng (tenantId, giá trị) trả về workspace hiện có. Bỏ trống → mỗi lần gọi một workspace mới |
| nameBẮT BUỘC | string | Tên workspace (≤100, bắt buộc) |
| slug | string | Slug workspace (≤50, duy nhất trong tenant·suy ra từ tên nếu bỏ trống) |
| description | string | Mô tả workspace (≤500) |
| defaultLocale | string | Locale mặc định — ko|en|ja|zh|zh-TW|es|vi|th (đi qua không kiểm tra; gửi đúng giá trị) |
| accentHue | integer | Sắc màu nhấn (0–360, đi qua không kiểm tra) |
| template | string | Preset — BLANK|DEV|AGENCY|OPS (giá trị lạ bị bỏ qua âm thầm) |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
SCOPE_FORBIDDENGhi bằng key chỉ đọc (không có scope write) — bị bộ lọc gateway chặn{
"error": "SCOPE_FORBIDDEN",
"message": "This API key is read-only. A 'write' scope is required for this operation."
}FORBIDDENTài khoản gọi không phải OWNER/ADMIN của tenant tenantId (tenant.admin_required){
"timestamp": "2026-07-14T20:00:00Z",
"message": "관리자 권한이 필요합니다"
}FORBIDDENTài khoản gọi không phải thành viên của tenant đó (kể cả tenant không tồn tại) (tenant.not_member){
"timestamp": "2026-07-14T20:00:00Z",
"message": "테넌트 멤버가 아닙니다"
}VALIDATION_ERRORXác thực thất bại (thiếu tenantId/name, v.v.) — chi tiết từng trường trong errors[]{
"timestamp": "2026-07-14T20:00:00Z",
"code": "VALIDATION_ERROR",
"message": "tenantId: must not be null",
"errors": [
{ "field": "tenantId", "code": "NotNull", "message": "must not be null" }
]
}UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn (chung cho mọi endpoint External){
"timestamp": "2026-07-14T20:00:00Z",
"message": "API key is missing, invalid, or expired."
}/workspaces/slug/availableKiểm tra trùng slug workspace
Kiểm tra xem một slug workspace có khả dụng (chưa bị dùng) trong một tenant hay không. Vì slug là duy nhất theo (tenantId, slug) nên cần tenantId giống như khi tạo workspace. Slug được chuẩn hóa giống quy tắc khi lưu (cắt khoảng trắng, chuyển chữ thường) trước khi so sánh, và giá trị rỗng hoặc trùng trả về available:false. Phân quyền dùng cùng cổng kiểm tra như khi tạo workspace — người gọi phải là OWNER/ADMIN của tenant đó (requireTenantAdmin); người không phải thành viên và không phải quản trị nhận 403, và không tiết lộ tenant có tồn tại hay không. Vì là GET nên chỉ cần scope read. Hãy dùng API này để kiểm tra trước tính khả dụng của slug trước khi tạo workspace (POST /workspaces).
| Tên | Kiểu | Mô tả |
|---|---|---|
| tenantIdBẮT BUỘC | integer | Phạm vi tenant để kiểm tra tính duy nhất (Long, query bắt buộc). Phạm vi duy nhất của slug. Người gọi phải là OWNER/ADMIN của tenant này |
| slugBẮT BUỘC | string | Slug workspace cần kiểm tra (query, bắt buộc). So sánh sau khi chuẩn hóa (trim, chữ thường) |
| Tên | Kiểu | Mô tả |
|---|---|---|
| available | boolean | true = khả dụng (chưa bị dùng), false = đã được dùng hoặc slug rỗng |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
FORBIDDENNgười gọi không phải OWNER/ADMIN của tenant tenantId (bao gồm cả người không phải thành viên) — bị chặn bởi requireTenantAdmin (không tiết lộ tenant có tồn tại hay không){
"timestamp": "2026-07-14T20:00:00Z",
"message": "관리자 권한이 필요합니다"
}UNAUTHORIZEDThiếu, không hợp lệ hoặc hết hạn X-API-Key (chung cho External API){
"timestamp": "2026-07-14T20:00:00Z",
"message": "API key is missing, invalid, or expired."
}/workspacesDanh sách workspace
Trả về các workspace mà tài khoản API key có thể truy cập.
/workspaces/{workspaceId}Xem workspace
Trả về một workspace.
| Tên | Kiểu | Mô tả |
|---|---|---|
| workspaceIdBẮT BUỘC | integer | ID workspace |
/projectsDanh sách dự án theo tenant & workspace
Trả về danh sách dự án của tenant và workspace được chỉ định, phân trang. tenantId và workspaceId là bắt buộc; status để lọc thêm.
| Tên | Kiểu | Mô tả |
|---|---|---|
| tenantIdBẮT BUỘC | integer | ID tenant (bắt buộc) |
| workspaceIdBẮT BUỘC | integer | ID workspace (bắt buộc) |
| status | enum | Khớp chính xác trạng thái dự án (PLANNING, ESTIMATING, WAITING, IN_PROGRESS, ON_HOLD, COMPLETED, CANCELLED). Khi chỉ định, bao gồm cả đã hủy/lưu trữ. |
| page | integer | Số trang (bắt đầu từ 0) |
| size | integer | Kích thước trang (mặc định 20, tối đa 100) |
Trường message được trả về theo locale của yêu cầu (?lang hoặc Accept-Language) cho 8 ngôn ngữ.
BAD_REQUESTWorkspace không tồn tại hoặc không thuộc tenant (cross-tenant trả về not_found mà không tiết lộ sự tồn tại).{
"timestamp": "2026-07-14T09:00:00Z",
"message": "워크스페이스를 찾을 수 없습니다"
}BAD_REQUESTGiá trị status không được hỗ trợ.{
"timestamp": "2026-07-14T09:00:00Z",
"message": "유효하지 않은 프로젝트 상태 값입니다"
}FORBIDDENKhông có quyền truy cập workspace này (không phải thành viên ACTIVE hay client/partner đã được chấp nhận — không fallback theo thành viên tenant).{
"timestamp": "2026-07-14T09:00:00Z",
"message": "워크스페이스 접근 권한이 없습니다"
}UNAUTHORIZEDX-API-Key thiếu, không hợp lệ hoặc hết hạn.{
"timestamp": "2026-07-14T09:00:00Z",
"message": "API key is missing, invalid, or expired."
}/workspaces/{workspaceId}/projectsDanh sách dự án
Trả về các dự án đang hoạt động của workspace (loại trừ đã hủy/lưu trữ).
| Tên | Kiểu | Mô tả |
|---|---|---|
| workspaceIdBẮT BUỘC | integer | ID workspace |
/projectsTạo dự án (idempotent)
Tạo dự án. Khi gửi kèm externalRef, lời gọi là idempotent — lặp lại cùng (workspaceId, externalRef) sẽ trả về dự án hiện có với 200 thay vì tạo mới (201 khi tạo lần đầu).
| Tên | Kiểu | Mô tả |
|---|---|---|
| workspaceIdBẮT BUỘC | integer | ID workspace |
| nameBẮT BUỘC | string | Tên dự án |
| externalRef | string | Khóa idempotency — gửi lại cùng giá trị sẽ trả về dự án hiện có với 200 thay vì tạo mới |
| code | string | Mã dự án (tiền tố khóa công việc). Tự động tạo từ tên nếu bỏ trống |
| description | string | Mô tả |
| clientIds | array | Mảng ID khách hàng |
| managerId | integer | ID tài khoản quản lý |
| startDate | date | Ngày bắt đầu — ISO 8601 (YYYY-MM-DD) |
| endDate | date | Ngày kết thúc — ISO 8601 (YYYY-MM-DD) |
| budget | integer | Ngân sách |
/projects/{projectId}Chi tiết / tiến độ dự án
Trả về chi tiết dự án gồm trạng thái, tiến độ (%), lịch kế hoạch/thực tế và thời điểm sửa cuối.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
/projects/{projectId}Cập nhật dự án
Chỉ cập nhật các trường được gửi (cập nhật một phần).
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
| Tên | Kiểu | Mô tả |
|---|---|---|
| name | string | Tên dự án |
| status | enum | Trạng thái — PLANNING·ESTIMATING·WAITING·IN_PROGRESS·ON_HOLD·COMPLETED·CANCELLED |
| progressRate | integer | Tiến độ (%) 0–100 |
| startDate | date | Ngày bắt đầu — ISO 8601 (YYYY-MM-DD) |
| endDate | date | Ngày kết thúc — ISO 8601 (YYYY-MM-DD) |
/projects/{projectId}Xóa dự án
Xóa dự án. Thành công trả về 204 No Content (không có nội dung).
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
/projects/{projectId}/timelineTimeline (milestone)
Danh sách milestone của dự án — tên, trạng thái (PLANNED/IN_PROGRESS/COMPLETED), hạn chót, ngày hoàn thành và tiến độ. Sắp xếp theo sortOrder.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
/projects/{projectId}/activitiesHoạt động
Các sự kiện thay đổi công việc của dự án, mới nhất trước — loại, thông điệp, người thực hiện và thời gian.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
| Tên | Kiểu | Mô tả |
|---|---|---|
| page | integer | Số trang (bắt đầu từ 0, mặc định 0) |
| size | integer | Kích thước trang (mặc định 50, tối đa 200) |
/projects/{projectId}/filesDanh sách tệp
Gộp tệp đính kèm của công việc và bình luận trong dự án, mới nhất trước. fileUrl là URL tĩnh không hết hạn.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
| Tên | Kiểu | Mô tả |
|---|---|---|
| limit | integer | Số lượng tối đa (mặc định 100, tối đa 500) |
/projects/{projectId}/tasksDanh sách công việc
Trả về các công việc của dự án. Dùng /tasks/paged nếu cần phân trang.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
| Tên | Kiểu | Mô tả |
|---|---|---|
| sortBy | string | Trường sắp xếp (mặc định createdAt) |
/tasksTạo công việc
Tạo công việc.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | integer | ID dự án (số) |
| titleBẮT BUỘC | string | Tiêu đề |
| description | string | Mô tả |
| assigneeId | integer | ID tài khoản người phụ trách |
| status | enum | Trạng thái — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED |
| priority | enum | Độ ưu tiên — URGENT·HIGH·MEDIUM·LOW |
| dueDate | date | Hạn chót — ISO 8601 |
| milestoneId | integer | ID milestone cần liên kết |
/tasks/{taskId}Xem công việc
Trả về một công việc.
| Tên | Kiểu | Mô tả |
|---|---|---|
| taskIdBẮT BUỘC | integer | ID công việc |
/tasks/{taskId}Cập nhật công việc
Chỉ cập nhật các trường được gửi.
| Tên | Kiểu | Mô tả |
|---|---|---|
| taskIdBẮT BUỘC | integer | ID công việc |
| Tên | Kiểu | Mô tả |
|---|---|---|
| title | string | Tiêu đề |
| status | enum | Trạng thái — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED |
| priority | enum | Độ ưu tiên — URGENT·HIGH·MEDIUM·LOW |
| dueDate | date | Hạn chót — ISO 8601 |
/tasks/{taskId}Xóa công việc
Xóa công việc. Thành công trả về 204 No Content.
| Tên | Kiểu | Mô tả |
|---|---|---|
| taskIdBẮT BUỘC | integer | ID công việc |
/tasks/assignedCông việc được giao cho tôi
Trả về các công việc được giao cho tài khoản API key.
/projects/{projectId}/documentsDanh sách tài liệu
Trả về các tài liệu của dự án. Dùng /documents/paged nếu cần phân trang.
| Tên | Kiểu | Mô tả |
|---|---|---|
| projectIdBẮT BUỘC | string | ID dự án — ID số hoặc publicId bắt đầu bằng p_ |
/documents/{documentId}Xem tài liệu
Trả về một tài liệu (gồm nội dung).
| Tên | Kiểu | Mô tả |
|---|---|---|
| documentIdBẮT BUỘC | integer | ID tài liệu |
/documentsTạo tài liệu
Tạo tài liệu.
| Tên | Kiểu | Mô tả |
|---|---|---|
| workspaceIdBẮT BUỘC | integer | ID workspace |
| titleBẮT BUỘC | string | Tiêu đề |
| documentTypeBẮT BUỘC | enum | Loại tài liệu (vd: REQUIREMENT, MEETING_NOTE) |
| projectId | integer | ID dự án (số) |
| content | string | Nội dung tài liệu |
| visibility | enum | Phạm vi hiển thị — PUBLIC·TEAM·PRIVATE |
/documents/{documentId}Cập nhật tài liệu
Chỉ cập nhật các trường được gửi.
| Tên | Kiểu | Mô tả |
|---|---|---|
| documentIdBẮT BUỘC | integer | ID tài liệu |
| Tên | Kiểu | Mô tả |
|---|---|---|
| title | string | Tiêu đề |
| content | string | Nội dung tài liệu |
| visibility | enum | Phạm vi hiển thị — PUBLIC·TEAM·PRIVATE |
/documents/{documentId}Xóa tài liệu
Xóa tài liệu. Thành công trả về 204 No Content.
| Tên | Kiểu | Mô tả |
|---|---|---|
| documentIdBẮT BUỘC | integer | ID tài liệu |
Mã lỗi
Mọi phản hồi lỗi đều bao gồm error.code và error.message.
| Mã | Tên | Mô tả | Hành động |
|---|---|---|---|
| 400 | Bad Request | Body của yêu cầu không hợp lệ. | Xác thực body của yêu cầu |
| 401 | Unauthorized | Khóa API không hợp lệ hoặc thiếu. | Kiểm tra lại khóa API |
| 403 | Forbidden | Bạn không có quyền truy cập tài nguyên này. Yêu cầu ghi bằng khóa chỉ đọc sẽ trả về SCOPE_FORBIDDEN. | Kiểm tra vai trò/phạm vi |
| 404 | Not Found | Không tìm thấy tài nguyên được yêu cầu. | Kiểm tra lại ID |
| 429 | Rate Limited | Bạn đã vượt quá giới hạn tốc độ. | Xem header Retry-After và giảm tốc |
| 500 | Server Error | Đã xảy ra lỗi khi máy chủ xử lý yêu cầu. | Thử lại sau 5 phút, kiểm tra status.pjt.ai |