Tổng quan API
Mọi endpoint REST của RolChat tuân theo một hợp đồng chung: cùng base URL, cùng phong bì phản hồi, cùng cách phân trang, cùng cấu trúc lỗi. Học một lần, và mọi nhóm endpoint trong tài liệu endpoint đều đọc theo cùng một cách.
Base URL và phiên bản
Phần tiêu đề “Base URL và phiên bản”https://api.rolchat.com/api/v1/Phiên bản nằm trong đường dẫn. Thêm trường tùy chọn, endpoint mới hoặc tham số query mới có giá trị mặc định không phải là thay đổi phá vỡ tương thích và không tăng phiên bản. Thay đổi phá vỡ tương thích được phát hành dưới dạng v2, và các endpoint v1 bị ngừng hỗ trợ vẫn hoạt động ít nhất sáu tháng sau khi được thông báo (xem Ngừng hỗ trợ).
Xác thực
Phần tiêu đề “Xác thực”| Phương thức | Header | Dùng cho |
|---|---|---|
| JWT bearer | Authorization: Bearer <access_token> |
Phiên tương tác (ứng dụng web, ứng dụng di động) |
| Khóa API | Authorization: Bearer rcp_<secret> |
Lệnh gọi giữa các hệ thống, khóa API của plugin |
| Chữ ký HMAC | X-RolChat-Signature: sha256=… |
Webhook đến từ hệ thống của bạn, xem Webhook |
| Không có | - | Endpoint widget công khai (/widget/…, /forms/…), giới hạn theo site và origin |
Với các tích hợp, hãy dùng khóa API (token truy cập cá nhân). Khóa được tạo trong Cài đặt → Plugin → Khóa API RolChat, chỉ hiển thị một lần và chỉ được lưu dưới dạng hash. Một khóa không bao giờ làm được nhiều hơn thành viên đã tạo ra nó: scope của khóa được kiểm tra với quyền hiện tại của thành viên đó ở mỗi lệnh gọi. Xem Xác thực để biết thời hạn JWT, header X-Account-Id và phiên nhiều công ty.
Phong bì phản hồi
Phần tiêu đề “Phong bì phản hồi”Một tài nguyên đơn lẻ:
{ "data": { "id": "cnt_01HK…", "email": "ada@example.com" }, "meta": { "request_id": "req_01HK…" }}Một danh sách:
{ "data": [ { … }, { … } ], "meta": { "request_id": "req_01HK…", "count": 50, "next_cursor": "cur_01HK…", "prev_cursor": "cur_01HK…", "has_more": true }}Phản hồi không có body (204 No Content sau khi xóa) vẫn mang header X-Request-Id.
Một lỗi:
{ "errors": [ { "code": "validation_failed", "message": "Email must be valid.", "field": "email", "details": { "received": "not-an-email" } } ], "meta": { "request_id": "req_01HK…" }}code là giá trị snake_case mà máy đọc được và là giá trị để rẽ nhánh xử lý; message bằng tiếng Anh và dành cho log. field và details có mặt khi hữu ích và không bao giờ chứa dữ liệu cá nhân. API không bao giờ trả về 200 kèm mảng errors: nếu có lỗi, mã trạng thái là 400 trở lên. Danh sách mã đầy đủ có ở trang Lỗi.
Phân trang
Phần tiêu đề “Phân trang”Các endpoint danh sách có thể tăng kích thước dùng phân trang bằng con trỏ. Yêu cầu trang đầu tiên không có con trỏ, sau đó gửi lại nguyên văn next_cursor bạn nhận được:
GET /api/v1/contacts?limit=50GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…limitmặc định là 50 và tối đa là 200; giá trị lớn hơn bị từ chối với400 validation_failed.- Con trỏ là giá trị mờ và hết hạn sau 24 giờ (
400 validation_failedvớicode: cursor_expired). - Kết quả nhất quán theo ảnh chụp dữ liệu lấy ở trang đầu tiên: bản ghi bị xóa giữa các trang sẽ biến mất, bản ghi mới chỉ xuất hiện khi bạn bắt đầu lại mà không có con trỏ.
- Header
Linkvớirel="next"vàrel="prev"cũng được gửi cho các client ưa dùng cách này.
Idempotency
Phần tiêu đề “Idempotency”Gửi header Idempotency-Key (UUID hoặc ULID, tối đa 255 ký tự) với mọi POST, PATCH hoặc DELETE:
- Yêu cầu đầu tiên với một khóa được thực thi, trạng thái và body của nó được lưu trong 24 giờ.
- Yêu cầu lặp lại với cùng khóa và cùng body trả về phản hồi đã lưu mà không thực hiện lại các tác động phụ.
- Yêu cầu lặp lại với cùng khóa nhưng body khác bị từ chối với
409 idempotency_key_conflict.
Dùng nó cho mọi lệnh gọi tạo ra thứ gì đó có tác động phụ: gửi tin nhắn, email hoặc SMS, thực hiện cuộc gọi, bất cứ thứ gì bị tính phí. Yêu cầu GET luôn idempotent và bỏ qua header này.
Giới hạn tốc độ
Phần tiêu đề “Giới hạn tốc độ”Giới hạn được tính theo phút và gắn với tài khoản, khóa API hoặc người dùng (theo địa chỉ IP trên các route không cần đăng nhập). Mức trần mặc định:
| Nhóm | Giới hạn mặc định | Mỗi phút |
|---|---|---|
| Yêu cầu không đăng nhập (theo IP) | 60 | mỗi IP |
| Người dùng đã đăng nhập (dashboard) | 1 000 | mỗi người dùng |
| Khóa API | 1 000 | mỗi khóa |
| Endpoint widget công khai | 60 mỗi khách truy cập và 600 mỗi địa chỉ mạng | mỗi phút |
Đăng nhập (/auth/login) |
5 | mỗi IP |
| Webhook đến | 300 | mỗi phút |
| Máy chủ MCP | 600 | mỗi phút |
| Endpoint OAuth | 600 | mỗi phút |
Các mức trần là mặc định của nền tảng và nhà vận hành có thể thay đổi; gói của bạn không nhân chúng lên, và giới hạn Enterprise được thỏa thuận trong hợp đồng. Endpoint có giới hạn tốc độ trả về:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 543Khi bạn vượt giới hạn, phản hồi là 429 với code: rate_limited trong mảng errors và header Retry-After tính bằng giây. Hãy chờ khoảng thời gian đó trước lệnh gọi tiếp theo. Mười lần đăng nhập thất bại sẽ khóa tài khoản trong 30 phút.
Kích thước và thời gian chờ
Phần tiêu đề “Kích thước và thời gian chờ”| Nhóm | Body yêu cầu tối đa | Thời gian chờ của máy chủ |
|---|---|---|
| Mặc định | 1 MB | 30 giây |
| Tin nhắn có tệp đính kèm | 25 MB | 30 giây |
| Nhập CSV | 50 MB | trả về 202 và chạy nền |
| Hình ảnh cơ sở tri thức | 10 MB | 30 giây |
| Bulk API | 10 MB | 30 giây |
| Tìm kiếm | 1 MB | 10 giây |
| Yêu cầu AI | 1 MB | 60 giây |
| Endpoint widget | 100 KB | 30 giây |
Body quá lớn nhận 413 payload_too_large. Dịch vụ upstream bị quá thời gian trả về 504 với code: upstream_timeout và gợi ý retry_after khi thử lại có thể giúp ích.
Kiểu nội dung, ngày giờ và ID
Phần tiêu đề “Kiểu nội dung, ngày giờ và ID”- Yêu cầu và phản hồi dùng
application/json; charset=utf-8. Tải tệp lên dùngmultipart/form-data; xuất CSV trả vềtext/csv. UTF-8 không hợp lệ bị từ chối với400 validation_failed. - Dấu thời gian theo ISO-8601 ở múi giờ UTC với độ chính xác đến mili giây:
2026-04-20T14:23:45.123Z. Mọi độ lệch ISO-8601 đều được chấp nhận ở đầu vào và chuẩn hóa về UTC. - Mã định danh là ULID hoặc UUID mờ. Không có ID dạng số, và địa chỉ email hay số điện thoại không bao giờ xuất hiện trong URL.
Cô lập tenant và quyền
Phần tiêu đề “Cô lập tenant và quyền”Mọi yêu cầu đã xác thực đều chạy bên trong một tài khoản. Tài nguyên thuộc tài khoản khác, hoặc thuộc site mà vai trò của bên gọi không bao quát, trả về 404 not_found thay vì 403, để sự tồn tại của bản ghi không bao giờ bị lộ. Token hợp lệ nhưng thiếu quyền cần thiết (ví dụ contacts.delete) trả về 403 forbidden. Một số quyền mang hậu tố phạm vi (conversations.read:own, :team, :all) giới hạn những gì danh sách trả về.
PATCH chỉ chấp nhận các trường có thể ghi. id, account_id, created_at, updated_at và các trường trạng thái như resolved_at là chỉ đọc; gửi một trong số đó sẽ trả về 400 validation_failed với details.forbidden_fields. Thay đổi trạng thái được thực hiện qua các hành động riêng như POST /tickets/:id/resolve.
Mọi thao tác ghi đều được ghi vào nhật ký kiểm toán của tài khoản.
Header quan sát
Phần tiêu đề “Header quan sát”Mọi phản hồi đều mang:
X-Request-Id: req_01HK…Hãy ghi log X-Request-Id. Đó là thứ đầu tiên bộ phận hỗ trợ sẽ hỏi.
Origin của bảng điều khiển trên trình duyệt là https://app.rolchat.com. Endpoint widget công khai cho phép mọi origin, hoặc chỉ những origin bạn xác minh cho một site. Lệnh gọi giữa máy chủ với máy chủ bằng khóa API không chịu ràng buộc CORS.
Ngừng hỗ trợ
Phần tiêu đề “Ngừng hỗ trợ”- Thay đổi được thông báo trong nhật ký thay đổi và endpoint bị ảnh hưởng bắt đầu gửi
Deprecation: truecùng headerSunsetchứa ngày gỡ bỏ. - Endpoint công khai vẫn hoạt động ít nhất sáu tháng sau thông báo.
- Việc gỡ bỏ chỉ diễn ra ở phiên bản chính mới. Trong
v1, các thay đổi chỉ mang tính bổ sung.
Tình trạng hoạt động
Phần tiêu đề “Tình trạng hoạt động”Mọi dịch vụ đều cung cấp /healthz (liveness) và /readyz (readiness).