Developer documentation
API & Webhook
Kết nối hệ thống ngoài (POS, CRM, hóa đơn…) với ChatPilot — bạn có thể:
- Nhận event qua HTTPS webhook: tin nhắn (khách / bot), đơn hàng (
order.created) — server ChatPilot POST về URL bạn cấu hình, có thể ký HMAC. - Gửi, nhận tin và lấy thông tin hội thoại qua REST (header
X-API-Key):- Gửi tin để AI trả lời đồng bộ —
POST /v1/chat/messages. - Gửi tin trực tiếp tới khách theo hội thoại (hóa đơn, thanh toán) —
POST /v1/conversations/:id/messages. - Đọc dữ liệu: danh sách hội thoại, lịch sử tin, customers —
GET /v1/conversations,GET …/conversations/:id/messages,GET /v1/customers.
- Gửi tin để AI trả lời đồng bộ —
Tạo API key trong Dashboard; cần gói Business (Doanh nghiệp). Bên dưới là cách dùng endpoint, bảo mật, ví dụ curl và mục lục.
Overview
Kết nối & API key
Mô hình: server-to-server — backend bạn gọi REST với API key bí mật (không đưa key lên trình duyệt / mobile). Chiều ngược lại, outbound webhooks để ChatPilot POST sự kiện tới URL HTTPS bạn cấu hình.
Prerequisites
- Chủ trang (owner) phải ở gói Business / Doanh nghiệp mới tạo được key.
- Tạo tại Dashboard → Tích hợp API. Mỗi page có tập key riêng, scope theo conversations & customers của trang.
REST: header bắt buộc
X-API-Key: <cpk_... full token>
Ví dụ fetch (Node): thêm key vào header; có JSON body thì dùng Content-Type: application/json.
Infra
Base URL, errors & rate limit
Base URL
Toàn bộ endpoint trong tài liệu này dùng chung một base URL — prefix cho mọi request (ví dụ POST /v1/chat/messages nghĩa là <base URL>/v1/chat/messages). Dưới đây là base URL dùng trong các ví dụ trên trang này; khi tích hợp thực tế, hãy thay bằng base URL API mà ChatPilot gửi cho bạn (hoặc URL do đội kỹ thuật cung cấp).
https://api.chatpilot.vn
Rate limit
Mặc định: 60 requests / phút / API key (có thể cấu hình). Vượt hạn: HTTP 429 Too Many Requests.
Mã lỗi thường gặp
- 401 — thiếu, sai, hoặc revoke key.
- 403 — page/tenant hoặc gói tài khoản không hợp lệ; không dùng được API.
- 404 — resource không tồn tại (ví dụ
conversationIdngoài scope key). - 400 — validation body/query, hết credit AI, AI tắt trên session — thường kèm message từ server.
Outbound
Webhooks: messages & orders
Cùng cấu hình với mỗi key: bạn thêm HTTPS callback URL và tùy chọn webhook secret. Phía ChatPilot POST JSON — endpoint của bạn không cần X-API-Key. Có secret thì verify bằng HMAC (bên dưới) trước khi xử lý (tránh spoofing).
Request từ ChatPilot tới bạn
POST,Content-Type: application/jsonUser-Agent: ChatPilot-Webhook/1.0
Signature (nếu đặt secret)
Header:
X-Webhook-Signature: sha256=<hex digest>
HMAC-SHA256( secret, rawRequestBody ) với raw body UTF-8 (đúng byte bạn parse JSON), kết quả dạng hex. Luôn verify trước khi accept payload.
Cách verify signature tại server
Quy tắc: Phía ChatPilot ký trên chuỗi JSON gửi đi (cùng thứ tự key/biểu diễn số mà JSON.stringify tạo khi gửi). Bạn phải dùng raw request body (string/Buffer trước JSON.parse) để tính HMAC — nếu parse rồiJSON.stringify lại, chuỗi có thể khác (thứ tự key) → chữ ký fail.
- Đọc
rawBodytừ request (chưaJSON.parse): Express dùngexpress.raw({ type: "application/json" })hoặc middleware lưu raw; Next.js Route Handler:request.text(). - Lấy header
X-Webhook-Signature— dạngsha256=<hex 64 ký tự>. - Tính
expected = HMAC-SHA256(secret, rawBody).digest('hex'). - So sánh với
sha256=bằng hàm constant-time (tránh timing attack), ví dụcrypto.timingSafeEqual(Node) trên hai buffer hex. - Chỉ parse
JSON.parse(rawBody)sau khi verify thành công.
Tương tự tài liệu Stripe/Shopify: luôn verify bằng body gốc, không tin tưởng nội dung đã parse sớm từ framework.
import { createHmac, timingSafeEqual } from "node:crypto";
// Trùng secret bạn cấp trong Dashboard (API key → webhook secret)
const secret = process.env.CHATPILOT_WEBHOOK_SECRET!;
/** rawBody: đúng chuỗi gửi tới endpoint (trước JSON.parse) */
export function verifyChatPilotSignature(
rawBody: string,
header: string | null | undefined
): boolean {
if (!header?.startsWith("sha256=")) return false;
const receivedHex = header.slice(7).trim();
const expectedHex = createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
if (receivedHex.length !== expectedHex.length) return false;
try {
return timingSafeEqual(
Buffer.from(receivedHex, "hex"),
Buffer.from(expectedHex, "hex")
);
} catch {
return false;
}
}Envelope mọi event
{
"event": "message.received" | "message.sent" | "order.created",
"timestamp": "2026-01-15T10:00:00.000Z",
"data": { ... }
}timestamp: thời điểm emit (ISO-8601, UTC). data: tùy event.
Events: message.received / message.sent
Đồng bộ tin — các field trong data:
| Field | Required | Description |
|---|---|---|
| conversationId | Yes | Conversation ID nội bộ (per page). |
| senderId | Yes | Customer / external sender id (PSID, v.v.). |
| source | Yes | Kênh: facebook, instagram, zalo, tiktok, web, api, … |
| role | Yes | user = khách; assistant = bot. |
| content | Yes | Nội dung text. |
| imageUrls | No | Mảng URL hình, nếu có. |
Event: order.created
Khi tạo booking/đơn hàng. Dùng bookingId làm khóa idempotency (cùng bookingId = cùng đơn, an toàn nếu webhook được gọi lại). URL nhận webhook: trả sớm mã 2xx khi đã ghi nhận; xử lý nặng hãy chuyển sang nền (hàng đợi, job) để tránh timeout — nếu lỗi/timeout, phía ChatPilot có thể gửi lại payload.
| Field | Required | Description |
|---|---|---|
| conversationId | No | Hội thoại (nếu biết), thường có khi đơn tạo từ hội thoại AI. |
| bookingId | Yes | Id đơn trên ChatPilot. |
| type | Yes | service (dịch/đặt lịch) hoặc product (sản phẩm, giao hàng). |
| itemId | Yes | ID sản phẩm / dịch vụ (catalog page). |
| itemName | Yes | Tên hiển thị (snapshot tại thời điểm tạo đơn). |
| senderId | Yes | Sender theo cùng quy ước conversation (đồng bộ đa nguồn). |
| customerName | No | Tên khách (nếu có). |
| customerPhone | No | SĐT. |
| customerAddress | No | Địa chỉ (vd. giao hàng). |
| quantity | Yes | Số lượng (số nguyên ≥ 1). |
| unitPrice | No | Unit price (snapshot) nếu sản phẩm khai giá. |
| note | No | Ghi chú / thời gian đặt, v.v. |
| voucherCode | No | Mã ưu đãi, nếu dùng. |
| status | Yes | Mặc định thường pending; cập nhật xử lý trên ChatPilot theo thực tế sản phẩm. |
| createdAt | Yes | Thời điểm tạo, ISO-8601 UTC (string JSON). |
POST
POST /v1/chat/messages
Gửi tin thay phía user (API) — AI xử lý và response đồng bộ (có thể nhiều "part" nếu model gửi từng bước hoặc kèm ảnh).
Full path: https://api.chatpilot.vn/v1/chat/messages
Request body (JSON)
| Field | Required | Description |
|---|---|---|
| senderId | Yes | External id, max 512 chars. Cùng senderId → cùng thread (source=api). |
| message | Yes | Text, max 32k chars. |
| imageUrls | No | 0–20 URL công khai (https, max 2048 chars/URL). Vision trước khi LLM, ảnh gắn message user. |
| senderInfo | No | Tùy chọn: { name, phone, email } — cập nhật profile theo senderId nếu gửi. |
200 OK (response)
conversationId — id thread. messages — các phần trả lời: content, role: assistant, tùy có imageUrls.
Example: curl
curl -X POST "https://api.chatpilot.vn/v1/chat/messages" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"senderId": "customer-123",
"message": "Bạn có sản phẩm gì?",
"imageUrls": ["https://cdn.example.com/photo.jpg"],
"senderInfo": {
"name": "Nguyễn Văn A",
"phone": "0901234567",
"email": "[email protected]"
}
}'POST
POST /v1/conversations/:conversationId/messages
Staff / backend gửi tin tới khách (không gọi LLM): hóa đơn, thanh toán, trạng thái đơn, v.v. Cùng conversationId từ GET conversations hoặc order.created / message.received webhook.
Full path: https://api.chatpilot.vn/v1/conversations/<conversationId>/messages
Không yêu cầu tắt aiEnabled cho hội thoại (khác hành vi gửi từ dashboard nội bộ).
Path
| Field | Required | Description |
|---|---|---|
| conversationId | Yes | Hội thoại thuộc page của API key. |
Request body (JSON)
| Field | Required | Description |
|---|---|---|
| content | Yes | Nội dung (≤ 32k). |
| imageUrls | No | Chỉ hỗ trợ khi conversation.source = api (0–20 URL, https). |
200 OK (response)
message: lưu như trả lời từ assistant, kèm conversationId và source (facebook, zalo, web, api, …). Webhook message.sent tới URL cấu hình (nếu URL đã cấp).
Example: curl (source=api, kèm imageUrls)
curl -X POST "https://api.chatpilot.vn/v1/conversations/64f0a1b2c3d4e5f678901234/messages" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "QR thanh toán: ...",
"imageUrls": ["https://cdn.example.com/qr-bill.png"]
}'Example: zalo (chỉ text)
curl -X POST "https://api.chatpilot.vn/v1/conversations/64f0a1b2c3d4e5f678901234/messages" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "Đơn đã giao — cảm ơn bạn."
}'GET
GET /v1/conversations
Paginate conversations của page gắn key, kèm tổng theo nguồn (counts).
Path: https://api.chatpilot.vn/v1/conversations
Query string
| Field | Required | Description |
|---|---|---|
| page | No | Trang, default 1, > 0. |
| limit | No | Page size 1–100, default 20. |
| source | No | Filter: facebook, instagram, zalo, tiktok, web, api. Bỏ: tất cả (theo backend). |
200 OK (shape)
conversations + meta total, page, limit, totalPages vàcounts theo kênh.
Example: curl
curl "https://api.chatpilot.vn/v1/conversations?page=1&limit=20&source=api" \ -H "X-API-Key: YOUR_API_KEY"
GET
GET /v1/conversations/:conversationId/messages
Lịch sử message trong conversation (cùng scope với key), phân trang giống GET /v1/conversations. Trang đầu (page=1): tin mới nhất; trong mỗi trang sắp theo thời gian giảm dần.
Path + query
| Field | Required | Description |
|---|---|---|
| conversationId | Yes | Path param — từ POST /chat hoặc GET /conversations. |
| page | No | Trang, default 1, > 0. |
| limit | No | Kích thước trang 1–100, default 50 nếu omit. |
200 OK (shape)
conversation tóm tắt, messages[] ( id, role user|assistant, content, imageUrls, createdAt ), kèm meta total, page, limit, totalPages (cùng ý nghĩa với list hội thoại).
Example: curl
curl "https://api.chatpilot.vn/v1/conversations/64f0a1b2c3d4e5f678901234/messages?page=1&limit=50" \ -H "X-API-Key: YOUR_API_KEY"
GET
GET /v1/customers
Danh sách customers của page, filter + pagination.
Query string
| Field | Required | Description |
|---|---|---|
| search | No | Tìm tên / SĐT (case với tên: theo hành vi API). |
| source | No | Filter: zalo, api, web, v.v. |
| tag | No | Filter theo customer tag. |
| page | No | Trang, default 1. |
| limit | No | Page size, default 20, > 0. |
200 OK (shape)
Mỗi item: senderId, source, thông tin liên hệ, tags, thống kê booking, firstContactAt / lastContactAt + tổng (pagination meta).
Example: curl
curl "https://api.chatpilot.vn/v1/customers?search=Nguyễn&source=api&tag=VIP&page=1&limit=20" \ -H "X-API-Key: YOUR_API_KEY"
Tạo API key & webhook
Trong Dashboard — tạo key, gắn HTTPS callback và secret (HMAC) trên cùng một màn hình cấu hình.