Nền tảng

Quy ước

Phiên bản, mã định danh, phân trang, lỗi, giới hạn.

Địa chỉ và phiên bản

https://api.ctas.vn/api/developer/oauth/…        xác thực
https://api.ctas.vn/api/developer/v1/…           token ứng dụng: /app, /connections, /webhooks, /events
https://api.ctas.vn/api/developer/v1/work/…      token kết nối: dữ liệu tổ chức

Mỗi ứng dụng ghim một ngày phiên bản, ví dụ 2026-09-01, lúc tạo. Mọi response mang X-CTAS-Api-Version.

  • Thêm trường, giá trị hay endpoint mới: không đổi ngày. Hãy bỏ qua trường bạn không biết.
  • Xoá trường hoặc đổi nghĩa: ra ngày mới. Ứng dụng của bạn giữ hành vi cũ cho đến khi bạn đổi ngày trong console. Ngày sắp ngừng được báo trước ít nhất 90 ngày qua header Deprecation và Sunset.

Mã CTAS — thứ người dùng gõ

Mọi mã một người phải đọc hoặc gõ đều có một trong hai hình dạng, khác nhau đúng ở chỗ ngẫu nhiên nhiều hay ít:

LoạiHình dạngVí dụDùng ở đâu
Định danh3 nhóm × 3 ký tựADT-JWT-ORWmã ứng dụng
Bí mật3 nhóm × 4 ký tựK7M2-QD4X-RN8Pmã kết nối, mã mời tổ chức

Bảng chữ là Crockford base 32 viết hoa: 0123456789ABCDEFGHJKMNPQRSTVWXYZ. Điểm mấu chốt không phải là không có ký tự dễ nhầm, mà là nhầm thì được tha: O gõ thay 0, I hay L thay 1, U thay V đều được quy về đúng. Khoảng trắng, gạch nối và chữ thường đều bỏ qua — adt jwt orw và ADT-JWT-ORW là cùng một mã.

Mã ứng dụng là công khai: nó nằm trong danh mục, trên trang cài đặt của bạn, trong tài liệu của bạn. Mã kết nối và mã mời là chìa khoá — đừng ghi vào log, đừng đưa vào URL.

Ứng dụng tạo trước 16/09/2026 còn một mã cũ dạng app_7k2m…. Mã đó vẫn tra cứu được ở mọi nơi nhận mã ứng dụng, và được trả về trong legacy_id. Mã mới nằm ở id; hãy dùng mã mới ở mọi chỗ bạn in ra cho khách.

Mã nội bộ

Tiền tốĐối tượng
con_kết nối
org_tổ chức
dep_, pos_phòng ban, chức danh
mem_nhân sự, một người trong một tổ chức
idr_yêu cầu xác nhận bằng QR
whk_, dlv_, evt_webhook, lần gửi, sự kiện

mem_ là mã theo tổ chức: cùng một người ở hai tổ chức có hai mã khác nhau, và không suy ra được tài khoản CTAS của họ. Đây là mã bạn nên lưu.

Định dạng

LoạiĐịnh dạng
ngàyYYYY-MM-DD
ngày giờISO 8601 có múi giờ
giờ trong caHH:mm
tiềnsố nguyên theo currency_code của tổ chức
ngày công, ngày phépsố thực một chữ số lẻ

Body là application/json, tối đa 1 MB. Trường không có trong tài liệu, cả trong body lẫn query, trả 422 UNKNOWN_FIELD kèm details.unknown_fields. Nhờ vậy gõ nhầm deparment= không lặng lẽ trả về danh sách chưa lọc.

Phân trang

GET /members?limit=50            → { "data": [...], "meta": { "next_cursor": "…", "has_more": true } }
GET /members?limit=50&cursor=…

limit từ 1 đến 100, mặc định 50. next_cursor là null khi hết. Con trỏ sống 24 giờ.

Lỗi

{ "error": { "code": "INSUFFICIENT_SCOPE", "message": "…", "retryable": false,
             "details": { "required_scope": "members:write" }, "request_id": "req_…" } }
HTTPcodeÝ nghĩaThử lại?
401INVALID_TOKENtoken sai hoặc đã thu hồikhông
401TOKEN_EXPIREDhết hạn, hãy làm mớisau khi làm mới
403INSUFFICIENT_SCOPEthiếu quyềnkhông
403CONNECTION_REQUIREDdùng token ứng dụng cho endpoint dữ liệu tổ chứckhông
403CONNECTION_REVOKEDtổ chức đã ngắt kết nốikhông
403PLAN_REQUIREDgói hiện tại của tổ chức không có API, kết nối vẫn được giữkhi họ dùng lại gói
404NOT_FOUNDkhông có, hoặc thuộc tổ chức kháckhông
409CONFLICT, IDEMPOTENCY_IN_FLIGHTtrùng hoặc đang xử lýtuỳ
422VALIDATION_FAILED, UNKNOWN_FIELDdữ liệu saikhông
429RATE_LIMITEDxem Retry-Aftercó
5xxINTERNALlỗi phía CTAScó, giãn dần

Kèm request_id khi liên hệ hỗ trợ.

Gửi lại an toàn

Gửi Idempotency-Key: <uuid> với mọi POST, PATCH, DELETE. Cùng key trên cùng kết nối trong 24 giờ thì nhận lại response cũ, kèm header Idempotent-Replay: true.

Giới hạn tần suất

Hai tầng, theo ứng dụng và theo kết nối. Header phản ánh tầng chặt hơn:

X-RateLimit-Scope: connection
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 1757127660

/oauth/token giới hạn 10 lần mỗi phút mỗi ứng dụng. Vượt thì nhận 429 và Retry-After.