Business planREST v1Webhook HTTPS

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ể:

  1. 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.
  2. 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.

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 (required)
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).

Base URL (ví dụ trên trang này)
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ụconversationId ngoài scope key).
  • 400validation 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/json
  • User-Agent: ChatPilot-Webhook/1.0

Signature (nếu đặt secret)

Header:

HMAC-SHA256
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.

  1. Đọc rawBody từ request (chưa JSON.parse): Express dùng express.raw({ type: "application/json" }) hoặc middleware lưu raw; Next.js Route Handler: request.text().
  2. Lấy header X-Webhook-Signature — dạng sha256=<hex 64 ký tự>.
  3. Tính expected = HMAC-SHA256(secret, rawBody).digest('hex').
  4. 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.
  5. 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.

Node.js: verify (example)
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 envelope (JSON)
{
  "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:

Bảng tham số — API field reference
FieldRequiredDescription
conversationIdYesConversation ID nội bộ (per page).
senderIdYesCustomer / external sender id (PSID, v.v.).
sourceYesKênh: facebook, instagram, zalo, tiktok, web, api, …
roleYesuser = khách; assistant = bot.
contentYesNội dung text.
imageUrlsNoMả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.

Bảng tham số — API field reference
FieldRequiredDescription
conversationIdNoHội thoại (nếu biết), thường có khi đơn tạo từ hội thoại AI.
bookingIdYesId đơn trên ChatPilot.
typeYesservice (dịch/đặt lịch) hoặc product (sản phẩm, giao hàng).
itemIdYesID sản phẩm / dịch vụ (catalog page).
itemNameYesTên hiển thị (snapshot tại thời điểm tạo đơn).
senderIdYesSender theo cùng quy ước conversation (đồng bộ đa nguồn).
customerNameNoTên khách (nếu có).
customerPhoneNoSĐT.
customerAddressNoĐịa chỉ (vd. giao hàng).
quantityYesSố lượng (số nguyên ≥ 1).
unitPriceNoUnit price (snapshot) nếu sản phẩm khai giá.
noteNoGhi chú / thời gian đặt, v.v.
voucherCodeNoMã ưu đãi, nếu dùng.
statusYesMặc định thường pending; cập nhật xử lý trên ChatPilot theo thực tế sản phẩm.
createdAtYesThờ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)

Bảng tham số — API field reference
FieldRequiredDescription
senderIdYesExternal id, max 512 chars. Cùng senderId → cùng thread (source=api).
messageYesText, max 32k chars.
imageUrlsNo0–20 URL công khai (https, max 2048 chars/URL). Vision trước khi LLM, ảnh gắn message user.
senderInfoNoTù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 example
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

Bảng tham số — API field reference
FieldRequiredDescription
conversationIdYesHội thoại thuộc page của API key.

Request body (JSON)

Bảng tham số — API field reference
FieldRequiredDescription
contentYesNội dung (≤ 32k).
imageUrlsNoChỉ hỗ trợ khi conversation.source = api (0–20 URL, https).

200 OK (response)

message: lưu như trả lời từ assistant, kèm conversationIdsource (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 example (api + ảnh)
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 example (Zalo)
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

Bảng tham số — API field reference
FieldRequiredDescription
pageNoTrang, default 1, &gt; 0.
limitNoPage size 1–100, default 20.
sourceNoFilter: facebook, instagram, zalo, tiktok, web, api. Bỏ: tất cả (theo backend).

200 OK (shape)

conversations + meta total, page, limit, totalPages counts theo kênh.

Example: curl

cURL example
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

Bảng tham số — API field reference
FieldRequiredDescription
conversationIdYesPath param — từ POST /chat hoặc GET /conversations.
pageNoTrang, default 1, &gt; 0.
limitNoKí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 example
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

Bảng tham số — API field reference
FieldRequiredDescription
searchNoTìm tên / SĐT (case với tên: theo hành vi API).
sourceNoFilter: zalo, api, web, v.v.
tagNoFilter theo customer tag.
pageNoTrang, default 1.
limitNoPage size, default 20, &gt; 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 example
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 callbacksecret (HMAC) trên cùng một màn hình cấu hình.

Mở màn tích hợp