Tạo API client
Trong CRM, tạo client, chọn RunAs user và cấp đúng scopes. Lưu client_id và client_secret.
Tài liệu tích hợp chính thức
Kết nối hệ thống ngoài với dữ liệu khách hàng, liên hệ, tiềm năng và cơ hội của CRMTop qua OAuth 2.0 Client Credentials.
Cấu hình môi trường một lần, lấy access token rồi gọi endpoint cần dùng.
/ ở cuối.
Trong CRM, tạo client, chọn RunAs user và cấp đúng scopes. Lưu client_id và client_secret.
Gọi POST /connect/token bằng Client Credentials. Có thể dùng form thử nhanh bên dưới.
Gửi header Authorization: Bearer <token>. Chọn endpoint và bấm “Thử trong Console”.
Token endpoint nhận dữ liệu dạng application/x-www-form-urlencoded. Nếu bỏ trống scope, server cấp toàn bộ scope đã cấu hình cho client.
curl.exe -X POST "https://public.crmtop.vn/connect/token" ` -H "Content-Type: application/x-www-form-urlencoded" ` --data-urlencode "grant_type=client_credentials" ` --data-urlencode "client_id=YOUR_CLIENT_ID" ` --data-urlencode "client_secret=YOUR_CLIENT_SECRET" ` --data-urlencode "scope=customers.read"
Token chỉ truy cập được các thao tác đã cấp cho API client và RunAs user cũng phải có quyền tương ứng trong CRM.
*.write dùng chung cho tạo mới và cập nhật. Xóa cần scope *.delete riêng.Authorization: Bearer <access_token> Content-Type: application/json Accept: application/json Idempotency-Key: <unique-key> # Khuyến nghị cho POST
Ngày giờ phải là ISO-8601 có timezone, ví dụ 2026-08-12T09:30:00+07:00 hoặc UTC với Z.
Enum dùng chuỗi camelCase, không dùng số. Ví dụ: customerAndSupplier, closedWon.
Gửi toàn bộ contract của resource. Không coi PUT là partial update. Field chỉ đọc như id, stage, status, thời gian tạo/sửa không gửi trong body.
Với POST, nên gửi Idempotency-Key dài 1–200 ký tự. Cùng key và cùng request trong 24 giờ sẽ nhận lại kết quả cũ; cùng key nhưng body khác trả 409.
externalId là ID từ hệ thống tích hợp, duy nhất theo client và resource. Sau khi đã gắn, giá trị này không được đổi.
Token endpoint: 30 request/phút theo IP và client. Business API: 600 request/phút theo tenant và integration. Khi bị giới hạn, chờ theo header Retry-After.
PublicApiListRequest có ba tham số: pageSize, updatedFrom và cursor.
| Tham số | Kiểu | Mặc định | Ý nghĩa |
|---|---|---|---|
pageSize | integer | 50 | Số bản ghi mỗi trang. Server giới hạn từ 1 đến 200. |
updatedFrom | ISO-8601 datetime | Từ đầu | Lấy bản ghi được tạo/cập nhật từ mốc này, theo điều kiện inclusive >=. |
cursor | string | null | Chuỗi opaque từ nextCursor, dùng để đọc trang kế tiếp. |
updatedFrom, chưa truyền cursor.data, hasMore và nextCursor.nextCursor.syncUntilUtc cho phiên sau.GET /api/v1/customers?pageSize=100&updatedFrom=2026-08-01T00:00:00Z
GET /api/v1/customers?pageSize=100&cursor=<nextCursor>
(LastModifiedOn, Id), giữ cùng watermark syncUntilUtc và hiệu quả hơn khi đọc sâu.Change feed trả các sự kiện created, updated, deleted cho từng resource.
GET /api/v1/changes/{resource}
resource: customers | contacts | leads | opportunitiesCần scope {resource}.read.
entityId.syncUntilUtc sau khi hoàn tất toàn bộ trang.{
"data": [
{
"id": "b7b5f1c3-09cc-43e3-a5c3-512b39329daf",
"resource": "customers",
"entityId": "3d1ea89b-f36b-4d48-9520-d9e3d765b997",
"operation": "updated",
"occurredOnUtc": "2026-08-12T03:20:15Z",
"externalId": "ERP-CUS-001"
}
],
"nextCursor": null,
"hasMore": false,
"syncUntilUtc": "2026-08-12T03:21:00Z"
}Lấy metadata trước khi ghi dữ liệu để biết key, kiểu, bắt buộc và danh sách lựa chọn.
GET /api/v1/metadata/custom-fields?module=customers
[
{
"key": "customer_tier",
"label": "Hạng khách hàng",
"fieldType": "select",
"description": null,
"isRequired": false,
"options": ["silver", "gold", "diamond"],
"displayOrder": 1
}
]{
"code": "CUS001",
"name": "Công ty ABC",
"customFields": [
{ "key": "customer_tier", "value": "gold" },
{ "key": "credit_limit", "value": 50000000 }
]
}customFields để giữ nguyên giá trị hiện có. Gửi mảng để cập nhật các field tương ứng. Key lặp, không tồn tại hoặc đã vô hiệu hóa sẽ trả 400.Các field dưới đây dùng cho POST và PUT. Response có thêm các field chỉ đọc.
| Field | Kiểu | Bắt buộc | Ghi chú |
|---|
id, createdOnUtc, lastModifiedOnUtc. Contact thêm customerName; Lead thêm status; Opportunity thêm customerName, contactName, leadName, stage.Mở từng endpoint để xem yêu cầu, ví dụ và đưa nhanh vào API Console.
| HTTP | Ý nghĩa | Cách xử lý |
|---|---|---|
400 | Request, cursor, field hoặc enum không hợp lệ. | Đọc detail, errors và sửa request. |
401 | Token/client sai, hết hạn hoặc bị vô hiệu hóa. | Lấy token mới; kiểm tra client và RunAs user. |
403 | Thiếu scope, quyền hoặc gói Public API. | Cấp scope/quyền phù hợp; kiểm tra subscription. |
404 | Không tìm thấy hoặc không nhìn thấy dữ liệu. | Kiểm tra ID và data scope của RunAs user. |
409 | Xung đột external ID, idempotency hoặc concurrency. | Không retry mù; đọc code để xử lý. |
429 | Vượt rate limit. | Chờ số giây trong header Retry-After. |
500 | Lỗi máy chủ. | Retry có backoff và cung cấp traceId khi báo lỗi. |
{
"type": "about:blank",
"title": "Validation failed",
"status": 400,
"detail": "Giá trị ngày giờ phải theo ISO-8601 và có timezone.",
"instance": "/api/v1/customers",
"code": "validation_failed",
"traceId": "00-..."
}Gửi request từ trình duyệt hoặc copy cURL để chạy trong PowerShell. Chọn “Thử trong Console” ở một endpoint để điền tự động.
Kết quả response sẽ hiển thị ở đây.