> ## Documentation Index
> Fetch the complete documentation index at: https://docs-agents.fpt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Phụ lục kỹ thuật

> Bảng mã lỗi, bảng giới hạn hệ thống và danh mục kiểm tra trước khi lên Production cho Live Chat và kênh API

Trang này gom các bảng tra cứu dùng chung cho [Kênh Live Chat](/kenh-live-chat), [SDK di động](/sdk-di-dong) và [Tích hợp API](/tich-hop-api).

## Bảng mã lỗi

Mọi lỗi trên Visitor API và API đọc lịch sử đều trả về cùng một cấu trúc. `code` là một chuỗi, không phải số; hãy rẽ nhánh theo nó, đừng rẽ nhánh theo `message`.

Mã trạng thái HTTP nằm ở dòng trạng thái và không lặp lại trong phần thân. Với lỗi 5xx, `message` luôn là một câu cố định; nguyên nhân thật được ghi vào log của nền tảng. Với lỗi 4xx, `message` được soạn cho bạn đọc và đáng hiển thị.

### Kênh API - Webhook nhận tin nhắn

| Status | Ý nghĩa | Có nên gửi lại? |
| - | - | - |
| 200 | Đã tiếp nhận | Không |
| 400 | Phần thân không hợp lệ hoặc vượt giới hạn | Không, hãy sửa yêu cầu |
| 401 | Chữ ký hoặc timestamp không hợp lệ | Không, kiểm tra khóa và đồng hồ |
| 405 | Sai phương thức HTTP | Không |
| 503 | Phía nền tảng chưa tiếp nhận được | Có, chờ tăng dần |

### Live Chat - Visitor API

| Mã lỗi | HTTP | Ý nghĩa |
| - | - | - |
| `INVALID_ARGUMENT` | 400 | Thiếu tham số bắt buộc, hoặc một giá trị vượt giới hạn độ dài |
| `INVALID_REQUEST_BODY` | 400 | Phần thân không giải mã được, hoặc vượt quá kích thước cho phép |
| `WORKSPACE_ID_NOT_ACCEPTED` | 400 | Phần thân chứa định danh tổ chức, phiên hoặc kết nối. Các giá trị này luôn lấy từ token |
| `ORIGIN_NOT_ALLOWED` | 403 | Origin không nằm trong danh sách cho phép, hoặc yêu cầu tạo phiên không kèm header `Origin` |
| `CONVERSATION_UNAVAILABLE` | 403 | Khách hàng này đã bị chặn |
| `SESSION_FORBIDDEN` | 403 | Token không thuộc về phiên được yêu cầu |
| `AGENT_FORBIDDEN` | 403 | Token không thuộc về Agent được yêu cầu |
| `HISTORY_FORBIDDEN` | 403 | Bên gọi không được phép đọc lịch sử |
| `USAGE_FORBIDDEN` | 403 | Xem hạn mức chỉ dành cho khóa API |
| `UPLOAD_FORBIDDEN` | 403 | Tải tệp lên chỉ dành cho `visitorToken` |
| `FEEDBACK_FORBIDDEN` | 403 | Gửi đánh giá chỉ dành cho `visitorToken` |
| `CONNECTION_NOT_FOUND` | 404 | `connectionKey` không tồn tại, kênh chưa kết nối, chưa gắn Agent, hoặc kênh đã bị xóa |
| `CONVERSATION_NOT_FOUND` | 404 | Hội thoại không tồn tại, thuộc tổ chức khác, hoặc là hội thoại nội bộ |
| `AGENT_NOT_FOUND` | 404 | Agent không tồn tại hoặc không thuộc phạm vi token |
| `ARTIFACT_NOT_FOUND` | 404 | Tệp không tồn tại hoặc không thuộc quyền của bên gọi |
| `FILE_TOO_LARGE` | 413 | Tệp vượt quá 30 MiB |
| `UNSUPPORTED_TYPE` | 415 | Phần mở rộng ngoài danh sách, hoặc nội dung tệp không khớp phần mở rộng |
| `RATE_LIMITED` | 429 | Vượt hạn mức. Đọc header `Retry-After` để biết thời điểm thử lại |
| `STORAGE_DISABLED` | 503 | Hệ thống chưa bật lưu trữ tệp. Chat vẫn hoạt động bình thường |
| `HISTORY_UNAVAILABLE` | 503 | Dịch vụ lịch sử tạm thời gián đoạn |

<Note>
  Nhiều mã 404 cố ý gộp chung nhiều nguyên nhân. Ví dụ `CONNECTION_NOT_FOUND` dùng chung cho bốn trường hợp, và `ARTIFACT_NOT_FOUND` dùng chung cho tệp không tồn tại lẫn tệp không thuộc quyền. Đây là chủ ý, để không ai dò được tài nguyên nào đang tồn tại.
</Note>

### Console - Cấu hình kênh

| Mã lỗi | HTTP | Ý nghĩa |
| - | - | - |
| `CHANNEL_CONFIG_INVALID` | 400 | Cấu hình sai: `callback_url` không phải https, `idle_window_hours` ngoài khoảng 1 đến 720, hoặc có trường lạ |
| `CHANNEL_NOT_FOUND` | 404 | Kênh không tồn tại hoặc thuộc tổ chức khác |
| `CHANNEL_NO_AGENT` | 409 | Kênh chưa gắn Agent nên chưa kết nối được |
| `CHANNEL_SECRET_NOT_MINTABLE` | 409 | Loại kênh này không dùng khóa bí mật do nền tảng sinh |
| `API_KEY_ALREADY_REVOKED` | 409 | Khóa API đã được thu hồi trước đó |
| `CALLBACK_TEST_RATE_LIMITED` | 429 | Vượt 10 lần kiểm tra callback mỗi phút |

## Bảng giới hạn hệ thống

### Kênh API - Chiều gửi lên

| Hạng mục | Giới hạn |
| - | - |
| `integrationKey`, `messageId`, `user.id` | 256 ký tự |
| `user.name`, `user.locale` | 256 ký tự |
| `user.avatar`, `attachments[].url` | 2048 ký tự |
| `text` | 16 384 ký tự (không phải byte) |
| `postback` | 1024 ký tự |
| `metadata` | 32 khóa, 8192 byte sau khi mã hóa JSON |
| `attachments` | 5 mục |
| Toàn bộ phần thân | 1 MiB |
| Độ lệch timestamp cho phép | ±5 phút |
| Cửa sổ chống trùng theo `messageId` | 5 phút |

### Kênh API - Chiều callback

| Hạng mục | Giới hạn |
| - | - |
| Thời gian chờ mỗi lần gọi | 10 giây |
| Số lần thử | 3 |
| Khoảng chờ giữa các lần | Khoảng 1s, 3s, 9s |
| `Retry-After` tối đa được tôn trọng | 30 giây |
| Đi theo chuyển hướng | Không bao giờ |
| `callback_url` | 2048 ký tự, bắt buộc https, địa chỉ công khai |
| Kiểm tra callback trên Console | 10 lần mỗi phút cho mỗi tổ chức |

### Live Chat

| Hạng mục | Giới hạn |
| - | - |
| Thời hạn `visitorToken` | 1 giờ |
| Phần thân `POST /v1/runs` | 256 KiB; tối đa 5 tệp đính kèm trên một lượt |
| Phần thân `POST /v1/visitor/session` | 16 KiB |
| Kích thước tệp đính kèm | 30 MiB, mỗi lần một tệp |
| Phần mở rộng được phép | pdf, doc, docx, ppt, pptx, jpg, jpeg, png, gif, svg, webp, heic, jfif, xlsx, xls, csv |
| `visitorName` | 256 byte khi gửi, cắt còn 64 ký tự khi lưu |
| `metadata.postback` | 1024 byte |
| `comment` khi đánh giá | Cắt còn 2000 ký tự |
| Câu hỏi gợi ý | 6 câu, mỗi câu 120 ký tự |
| Danh sách tên miền cho phép | 20 mục, mỗi mục 253 ký tự |
| Thời hạn đường dẫn tải tệp | 300 giây |

### Hạn mức chung của tổ chức

| Hạng mục | Giới hạn mặc định | Ghi chú |
| - | - | - |
| Lượt chạy mỗi ngày | 2000 | Tính chung cho cả tổ chức, đặt lại vào 00:00 UTC |
| Lượt gọi mỗi phút | 20 | Tính cho mỗi bên gọi |
| Đọc lịch sử mỗi phút | 120 | Hạn mức riêng cho mỗi khóa API, không tính vào hạn mức ngày |
| Độ trễ khi thu hồi khóa API | 30 giây | Do khóa được lưu đệm |

## Danh mục kiểm tra trước khi lên Production

### Kênh Live Chat

* Đã lưu cấu hình kênh ít nhất một lần và đã có đoạn mã nhúng.
* Đoạn mã đặt trước thẻ đóng `</body>`, `data-connection-key` đúng, `data-app-origin` giữ nguyên phần đường dẫn `/chat-widget/`.
* Đã thử trên điện thoại, không chỉ trên máy tính.
* Nếu dùng ứng dụng di động: đã truyền `locale` của thiết bị, vì SDK không đọc ngôn ngữ mặc định trên Console.
* Nếu tự dựng giao diện: đã thêm tên miền của bạn vào danh sách cho phép, và không gọi với `credentials: "include"`.

### Kênh API

* Đã gửi tin nhắn tới đúng host webhook lấy từ Console (`https://console-agents.fpt.ai/webhooks/api`), không phải host ứng dụng.
* Khóa bí mật đã lưu vào kho bí mật, không nằm trong mã nguồn hay tệp cấu hình đưa lên Git.
* Máy chủ đã đồng bộ giờ bằng NTP. Lệch quá 5 phút là mọi gói tin bị từ chối.
* Hàm ký dùng chuỗi byte nguyên bản của phần thân, không phải bản đã tuần tự hóa lại.
* So sánh chữ ký bằng hàm thời gian hằng số.
* `messageId` là mã ổn định của bạn và giữ nguyên qua các lần gửi lại.
* Webhook trả 200 ngay rồi mới xử lý bất đồng bộ. Mỗi lần gọi chỉ có 10 giây.
* Webhook đã xử lý nhánh `type == "verification"` và lặp lại `challenge`.
* Đã bấm **Kiểm tra callback** trên Console và nhận kết quả đạt.
* Đã chống trùng theo `eventId`.
* Đã lưu `conversationId` từ mọi callback, kể cả callback nhận thành công.
* Đã có vòng lặp đồng bộ qua API đọc lịch sử để bù cho callback thất bại.
* Đã tạo khóa API riêng cho việc đọc lịch sử và cất an toàn.
* Đã xử lý mã 429 bằng cách đọc header `Retry-After`.
* Đã xử lý mã 503 bằng cách gửi lại với thời gian chờ tăng dần, và không coi nó là tin nhắn bị từ chối.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.