Brevo API: Hướng dẫn thực chiến cho lập trình viên
Hướng dẫn Brevo API cho lập trình viên: xác thực, base URL, danh bạ, email giao dịch, chiến dịch, đối tượng CRM, webhook, giới hạn tốc độ và các giới hạn thực tế.
Brevo cung cấp một REST API duy nhất trải rộng từ nhắn tin giao dịch, chiến dịch marketing, dữ liệu danh bạ cho tới bản ghi CRM. Để request đầu tiên trả về 201 chỉ mất khoảng hai phút. Nhưng để có một tích hợp chạy trên môi trường production mà không âm thầm làm mất dữ liệu thì mất lâu hơn nhiều, vì một số ràng buộc quan trọng nhất hoặc không được ghi trong tài liệu, hoặc mâu thuẫn với chính những gì API tự báo cáo về mình.
Hướng dẫn này bao trùm cả hai nửa: các endpoint, SDK và cơ chế xác thực bạn cần trong ngày đầu tiên, cùng những giới hạn nền tảng mà bạn phải thiết kế để né trước khi đưa sản phẩm lên.
Brevo API bao gồm những gì
Mọi thứ nằm dưới một host duy nhất và một đường dẫn phiên bản duy nhất. Tài liệu dành cho lập trình viên chia bề mặt API thành bốn mảng sản phẩm:
- Nhắn tin: email giao dịch, SMS và WhatsApp, gồm cả gửi hàng loạt, lên lịch và theo dõi hoạt động tin nhắn.
- Nền tảng marketing: danh bạ, danh sách, phân khúc và chiến dịch email.
- Thương mại điện tử: sản phẩm, đơn hàng và theo dõi sự kiện khách hàng.
- Conversations: widget chat và quản lý hội thoại bằng chương trình.
Bốn mảng đó dùng chung một tài khoản, một cơ sở dữ liệu danh bạ và một khóa API. Điều đó vừa tiện lợi vừa đôi khi nguy hiểm: một script viết theo hình dung về dữ liệu staging thực ra đang nói chuyện với đúng những danh bạ mà chiến dịch của bạn gửi tới.
Giao dịch so với marketing
Hai nhóm này hoạt động khác nhau đủ nhiều để việc nhầm lẫn giữa chúng trở thành lỗi thiết kế phổ biến nhất.
| Giao dịch | Marketing | |
|---|---|---|
| Endpoint chính | POST /v3/smtp/email | POST /v3/emailCampaigns |
| Cách chỉ định người nhận | Người nhận khai báo tường minh trong request | listIds hoặc segmentIds |
| Yếu tố kích hoạt | Ứng dụng của bạn, theo thời gian thực | Lên lịch trước hoặc gửi khi cần |
| Hình dạng lưu lượng điển hình | Liên tục, mỗi lần một tin nhắn | Dồn dập, một lượt gửi lớn |
| Thế của giới hạn tốc độ | Rất cao, 1.000 request mỗi giây trên gói tiêu chuẩn | Thấp, endpoint chiến dịch nằm trong hạn mức chung |
Nếu bạn vẫn đang cân nhắc liệu Brevo có phải nền tảng phù hợp hay không, bài tổng quan nền tảng đã bàn kỹ chuyện đó.
Xác thực và quản lý khóa
Brevo dùng một khóa API thuần trong header tùy chỉnh. Header có tên là api-key, không phải Authorization, và không có tiền tố Bearer. Điểm này khiến gần như ai từng dùng một API nhắn tin khác trước đó đều vấp phải.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"Khóa được tạo trong ứng dụng Brevo, ở phần cài đặt tài khoản, mục SMTP and API, tab API keys. Hãy đặt cho mỗi khóa một cái tên mô tả gắn với hệ thống sử dụng nó. Giá trị khóa chỉ hiển thị đúng một lần khi được tạo, nên nếu làm mất, bạn phải tạo khóa mới chứ không khôi phục lại khóa cũ.
Một vài nguyên tắc thực dụng:
- Cấp một khóa riêng cho từng môi trường triển khai và từng dịch vụ. Việc thu hồi một khóa bị lộ không bao giờ nên kéo sập ba hệ thống không liên quan.
- Khóa API tiêu chuẩn có phạm vi toàn tài khoản. Hãy coi mọi khóa như quyền truy cập đầy đủ vào danh bạ, khả năng gửi và dữ liệu CRM.
- Brevo cũng hỗ trợ OAuth 2.0 cho các ứng dụng hành động thay mặt tài khoản Brevo khác, được mô tả cùng luồng khóa trong authentication schemes.
- Máy chủ MCP dùng cho trợ lý AI cần một token riêng và có dùng header bearer. Token đó được tạo trong cùng màn hình API keys nhưng không thể dùng thay cho khóa REST.
Base URL, phiên bản và lệnh ghi đầu tiên
Base URL là https://api.brevo.com/v3/. Phiên bản nằm trong đường dẫn chứ không nằm trong header, và v3 là thế hệ hiện tại. Mọi đường dẫn trong hướng dẫn này đều tương đối so với base đó.
Một lệnh ghi đầu tiên cho bạn nhiều thông tin hơn một lệnh đọc đầu tiên, vì nó chạm vào đúng những phần của tài khoản thường bị cấu hình sai, đặc biệt là người gửi đã xác minh:
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sender": { "name": "Ops", "email": "[email protected]" }, "to": [{ "email": "[email protected]", "name": "Dev" }], "subject": "First transactional send", "htmlContent": "<html><body><p>It works.</p></body></html>", "tags": ["smoke-test"] }'Một lượt gửi thành công trả về 201 kèm messageId. Một lượt gửi có lên lịch trả về 202.
Những endpoint bạn thực sự sẽ dùng
Danh bạ
POST /v3/contacts tạo một liên hệ. Body nhận email, một map attributes cho các trường tùy chỉnh, listIds, ext_id cho khóa ngoại của riêng bạn, và hai cờ quan trọng nhất trong thực tế: updateEnabled, biến lệnh gọi thành upsert, và getId, khiến phản hồi trả về id của liên hệ.
Việc đọc đi qua GET /v3/contacts, phân trang bằng limit (mặc định 50, tối đa 1000) và offset, đồng thời hỗ trợ modifiedSince và createdSince theo giờ UTC. Các luồng đồng bộ gia tăng nên dựa vào modifiedSince thay vì duyệt toàn bộ danh sách. Lưu ý rằng tham số filter chỉ hỗ trợ toán tử bằng, nên bất cứ điều kiện nào phức tạp hơn đều thuộc về một phân khúc.
Để nạp hàng loạt, POST /v3/contacts/import nhận fileUrl, fileBody hoặc jsonBody, nhắm tới listIds và chạy bất đồng bộ, trả về một processId. Brevo ghi rõ giới hạn body tối đa 10 MB và khuyến nghị giữ quanh mức 8 MB vì quá trình phân tích cú pháp làm phình payload. Hãy cung cấp notifyUrl để biết kết quả thay vì phải hỏi liên tục.
Email giao dịch
POST /v3/smtp/email là con ngựa kéo chính. Ngoài sender, to, subject và htmlContent, những trường đáng biết là:
templateIdđi kèmparams, thay nội dung nội tuyến bằng một mẫu của Brevo cùng các phép thay biến. Params của từng phiên bản bị giới hạn ở 100 KB, tổng cộng ở mức 1000 KB.messageVersions, gửi các biến thể được cá nhân hóa trong một lệnh gọi, với tối đa 99 người nhận cho mỗi phiên bản.tags, thứ bạn luôn nên đặt. Thẻ quay về trong các sự kiện webhook, và đó là cách rẻ tiền duy nhất để đối chiếu một sự kiện gửi với đoạn mã đã tạo ra nó.scheduledAtcùngbatchId, cho những lượt gửi tương lai mà bạn có thể muốn hủy theo nhóm.headers, viết theo Title-Case, cho các header SMTP tùy chỉnh.
Một request đơn lẻ chấp nhận tối đa 2.000 người nhận. Về khác biệt giữa endpoint này và việc gửi chiến dịch, hướng dẫn email giao dịch trình bày góc nhìn chiến lược nhắn tin.
Chiến dịch email
POST /v3/emailCampaigns yêu cầu name và sender, cộng đúng một nguồn nội dung: htmlContent (tối thiểu 10 ký tự, dưới 1 MB), htmlUrl hoặc templateId. Đối tượng nhận nằm trong recipients dưới dạng listIds hoặc segmentIds, còn scheduledAt dùng định dạng UTC YYYY-MM-DDTHH:mm:ss.SSSZ. Các route đi kèm bao gồm gửi ngay, gửi bản thử, cập nhật trạng thái và lấy báo cáo chiến dịch.
Công ty, thương vụ và object
CRM của Brevo có hai đường ghi chồng lấn nhau, và chọn đúng là chuyện quan trọng.
Các route CRM là POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id} và bộ tương đương cho thương vụ. Chúng là đồng bộ. Một lệnh PATCH trả về 204 ngay khi thay đổi được áp dụng.
API object là đường đi hàng loạt: POST /v3/objects/{object_type}/batch/upsert nhận tối đa 1000 bản ghi và 1 MB mỗi request, tối đa 500 thuộc tính cho mỗi bản ghi, và tối đa 10 bản ghi liên kết cho mỗi loại object trên mỗi bản ghi. Nó trả về 202 kèm một processId, nghĩa là đã tiếp nhận chứ chưa áp dụng.
curl -X POST https://api.brevo.com/v3/objects/company/batch/upsert \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [ { "identifiers": { "id": 12345 }, "attributes": { "domain": "acme.example", "industry": "retail" } } ] }'Hướng dẫn Brevo CRM trình bày mô hình dữ liệu này từ góc nhìn người vận hành.
SDK chính thức
Brevo duy trì các client dưới tổ chức GitHub getbrevo:
| Ngôn ngữ | Kho mã |
|---|---|
| Node.js | github.com/getbrevo/brevo-node |
| Python | github.com/getbrevo/brevo-python |
| PHP | github.com/getbrevo/brevo-php |
| Java | github.com/getbrevo/brevo-java |
| C# | github.com/getbrevo/brevo-csharp |
| Go | github.com/getbrevo/brevo-go |
| Ruby | github.com/getbrevo/brevo-ruby |
Client Node cài đặt dưới tên @getbrevo/brevo:
npm install @getbrevo/brevoimport { BrevoClient } from "@getbrevo/brevo";
const brevo = new BrevoClient({ apiKey: process.env.BREVO_API_KEY });
const result = await brevo.transactionalEmails.sendTransacEmail({ subject: "Order confirmed", htmlContent: "<html><body><p>Thanks for your order.</p></body></html>", tags: ["order-confirmation"],});
console.log("Message ID:", result.messageId);Client Python cài bằng pip install brevo-python. Nếu bạn không muốn gánh thêm một phụ thuộc SDK chỉ vì hai endpoint, bề mặt HTTP thô đủ nhỏ để gọi trực tiếp, và cách đó cũng giúp bạn tránh được những đợt thay đổi phiên bản SDK:
import osimport requests
BASE = "https://api.brevo.com/v3"HEADERS = { "api-key": os.environ["BREVO_API_KEY"], "Content-Type": "application/json",}
def upsert_contact(email, attributes, list_ids): response = requests.post( f"{BASE}/contacts", headers=HEADERS, json={ "email": email, "attributes": attributes, "listIds": list_ids, "updateEnabled": True, }, timeout=30, ) response.raise_for_status() return responseNgoài ra còn có máy chủ MCP tại https://mcp.brevo.com/v1/brevo/mcp dành cho trợ lý AI, xác thực bằng bearer token tạo trong cùng màn hình cài đặt. Nó hữu ích để khám phá và hỏi đáp về tài khoản, không dành cho luồng dữ liệu production.
Webhook
Webhook là cách bạn biết chuyện gì đã xảy ra sau khi gửi. POST /v3/webhooks tạo một webhook, với url, events, type, và tùy chọn channel (email hoặc sms), batched, headers tùy chỉnh cùng một đối tượng auth.
Có ba loại webhook với ba bộ từ vựng sự kiện riêng:
- Giao dịch:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - Marketing:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - Inbound:
inboundEmailProcessedvàreply, hai sự kiện này còn đòi hỏi thêm mộtdomain.
curl -X POST https://api.brevo.com/v3/webhooks \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://yourapp.example/hooks/brevo", "type": "transactional", "events": ["delivered", "hardBounce", "spam", "unsubscribed"], "description": "Deliverability signals" }'Có ba điều cần làm cho đúng. Thứ nhất, một tài khoản chỉ giữ được tối đa 40 webhook trên tất cả các loại, nên hãy định tuyến theo sự kiện bên trong handler thay vì đăng ký một endpoint cho mỗi sự kiện. Thứ hai, hãy dùng cờ batched khi bạn dự kiến lưu lượng lớn, vì một request mang nhiều sự kiện rẻ hơn nhiều so với nhiều request riêng lẻ. Thứ ba, hãy bảo vệ bên nhận: Brevo công bố dải IP gửi của mình, và giới hạn endpoint của bạn theo các dải đó là cách làm được ghi trong tài liệu. Hãy thêm một khóa bí mật dùng chung qua trường headers như lớp bảo vệ thứ hai.
Handler bắt buộc phải bất biến khi gọi lại nhiều lần. Hãy lấy id tin nhắn cộng loại sự kiện cộng dấu thời gian làm khóa khử trùng lặp.
Giới hạn tốc độ và xử lý lỗi
Giới hạn tốc độ của Brevo được đặt theo từng endpoint và từng bậc gói dịch vụ, và khoảng cách giữa các endpoint là rất lớn.
| Endpoint | Tiêu chuẩn | Professional và Enterprise |
|---|---|---|
POST /v3/smtp/email | 1.000 RPS | 2.000 RPS |
POST /v3/transactionalSMS/send | 150 RPS | 200 RPS |
/v3/contacts/... | 10 RPS, 36.000 RPH | 20 RPS, 72.000 RPH |
POST /v3/events | 10 RPS, 36.000 RPH | cao hơn trên Enterprise |
GET /v3/smtp/emails | 2 RPS, 7.200 RPH | 3 RPS, 10.800 RPH |
| Mọi endpoint còn lại | 100 RPH | 200 RPH |
Hàng cuối cùng mới là hàng gây đau. Việc gửi gần như không bị đo đếm, trong khi quản lý chiến dịch, đọc dữ liệu CRM và phần lớn lệnh gọi quản trị cùng chia nhau ngân sách 100 request mỗi giờ trên gói tiêu chuẩn. Một tác vụ nạp lại dữ liệu ngây thơ, đọc bản ghi công ty trước mỗi lần ghi, sẽ ngốn sạch hạn mức một giờ trong chưa đầy hai phút.
Mọi phản hồi đều mang theo x-sib-ratelimit-limit, x-sib-ratelimit-remaining và x-sib-ratelimit-reset. Hãy đọc chúng cả khi thành công, không chỉ khi thất bại. Vượt giới hạn sẽ trả về 429, và phản ứng đúng là chờ hết khoảng thời gian trong header reset rồi áp dụng lùi thời gian theo cấp số nhân có thêm nhiễu ngẫu nhiên.
async function callBrevo(path, init, attempt = 0) { const response = await fetch(`https://api.brevo.com/v3${path}`, { ...init, headers: { "api-key": process.env.BREVO_API_KEY, "Content-Type": "application/json", ...init.headers }, });
if (response.status === 429 && attempt < 5) { const reset = Number(response.headers.get("x-sib-ratelimit-reset") || 1); const backoff = Math.pow(2, attempt) * 250 + Math.random() * 250; await new Promise((r) => setTimeout(r, reset * 1000 + backoff)); return callBrevo(path, init, attempt + 1); }
return response;}Hãy thử lại với 429 và 5xx. Đừng bao giờ thử lại 400 hay 409 một cách mù quáng, vì cả hai thường có nghĩa là request sai chứ không phải gọi quá sớm, và riêng 409 cần một hành động khác chứ không phải lặp lại.
Thử nghiệm mà không gửi thư
Hãy thêm header X-Sib-Sandbox với giá trị drop vào một lệnh gửi giao dịch. Brevo kiểm tra request, trả về 201 kèm messageId, không chuyển phát gì và không ghi nhật ký email.
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "X-Sib-Sandbox: drop" \ -H "Content-Type: application/json" \ -d '{ "sender": { "email": "[email protected]" }, "to": [{ "email": "[email protected]" }], "subject": "Sandbox", "htmlContent": "<p>hi</p>" }'Hãy hiểu rõ điều này chứng minh được gì và không chứng minh được gì. Chế độ sandbox chỉ kiểm tra định dạng request. Nó không nói gì về xác thực người gửi, kết xuất mẫu hay khả năng vào hộp thư. Hãy giữ một tài khoản Brevo riêng để kiểm thử tích hợp cho bất cứ thứ gì chạm vào danh bạ hoặc dữ liệu CRM, vì chế độ sandbox chỉ bao phủ việc gửi chứ không bao phủ phần còn lại của API.
Những giới hạn định hình thiết kế tích hợp của bạn
Đây là các ràng buộc chỉ lộ ra khi một tích hợp chạy trên tài khoản thật với lưu lượng thật. Vài điều trong số đó mâu thuẫn với chính những gì API tự nói về mình. Không điều nào có thể thương lượng, nên phản ứng hợp lý duy nhất là thiết kế để né chúng.
Công ty bắt buộc có domain, và mỗi domain chỉ một công ty
GET /v3/crm/attributes/companies báo rằng mọi thuộc tính đều không bắt buộc, còn tài liệu tham chiếu tạo công ty chỉ liệt kê name là bắt buộc. Trên thực tế, POST /v3/companies mà thiếu thuộc tính domain khác rỗng sẽ trả về 400 kèm thông báo thiếu thuộc tính mặc định bắt buộc. Chuỗi rỗng cũng thất bại y hệt như bỏ trống.
Tệ hơn, tính duy nhất của domain được cưỡng chế. Công ty thứ hai trên một domain đã dùng sẽ nhận về 409. Với thương mại B2B thì đây là vấn đề cấu trúc: các công ty con dùng chung một domain email người mua không thể cùng tồn tại như những công ty riêng biệt trong Brevo. Việc đồng bộ một liên hệ cũng đủ để một công ty xuất hiện theo domain email của liên hệ đó, nên một lệnh tạo có thể va chạm với công ty mà không ai chủ động tạo ra. Handler đúng sẽ nhận lấy công ty đã tồn tại khi gặp 409 thay vì báo lỗi hay thử lại.
Thuộc tính chưa khai báo bị loại bỏ âm thầm
Đây là hành vi nguy hiểm nhất của nền tảng, và Brevo ghi rõ nó trong tài liệu: nếu một thuộc tính xuất hiện trong request nhưng chưa từng được định nghĩa trong schema của object, sẽ không có gì xảy ra. Không lỗi, không tạo thuộc tính, không cảnh báo.
Vì vậy một phản hồi 2xx không phải bằng chứng rằng dữ liệu của bạn đã hạ cánh. Hãy đọc schema trước khi ghi, tự loại bỏ mọi thứ chưa khai báo ngay trong client của bạn, và từ chối chạy một luồng đồng bộ có thuộc tính không tồn tại, thay vì ghi nửa vời một bản ghi suốt một tháng trước khi có người nhận ra.
Bộ lọc thuộc tính được chấp nhận rồi bị bỏ qua
GET /v3/companies?filters[attributes.domain]=... trả về 200 và bỏ qua bộ lọc. Hai bộ lọc hoàn toàn khác nhau trả về cùng một tập bản ghi. Không có cách nào hoạt động được để tra cứu một công ty theo thuộc tính qua route đó.
Kết hợp với việc danh sách không lọc bị timeout với 504 trên các tài khoản lớn ở mọi kích thước trang, một công ty đang tồn tại có thể thực sự không tìm ra được qua đường đi được ghi trong tài liệu. Cách khắc phục là quét GET /v3/objects/company/records với sort=desc, vốn nhanh, có phân trang và trả về thuộc tính, giới hạn ở một số trang hợp lý. Công ty vừa gây ra lỗi 409 gần như luôn được tạo ra chỉ vài khoảnh khắc trước đó, nên quét theo thứ tự mới nhất trước sẽ tìm ra nó rất nhanh.
Một triệu bản ghi cho mỗi loại object, và không có xóa hàng loạt
POST /v3/objects/{type}/batch/upsert trả về 400 ngay khi một loại object chứa một triệu bản ghi. Nó chặn cả cập nhật lẫn tạo mới: chỉ định một bản ghi đang tồn tại bằng chính id số của nó cũng thất bại y hệt. Toàn bộ đường ghi object đóng lại cùng lúc.
Việc quay về dưới ngưỡng rất chậm, vì POST /v3/objects/{type}/batch/delete trả về 403 với các loại object tiêu chuẩn của Brevo như company. Đường duy nhất là DELETE /v3/companies/{id}, mỗi lệnh gọi một bản ghi ở tốc độ khoảng 156 ms. Dọn 124.000 bản ghi theo cách đó mất nhiều giờ với 20 luồng chạy song song. Hãy giám sát số lượng bản ghi theo lịch thay vì phát hiện ngưỡng qua một lượt đồng bộ thất bại, và định tuyến các cập nhật lưu lượng lớn qua PATCH /v3/companies/{id}, vốn không có giới hạn này.
ext_id là id của Brevo, không phải của bạn
Trên bản ghi object, identifiers.ext_id giữ chính id công ty CRM của Brevo, một chuỗi kiểu Mongo. Đó không phải một khóa ngoại tự do. Việc upsert theo ext_id gán bằng định danh của nền tảng bạn sẽ tạo ra bản trùng thay vì khớp bản ghi. Id ngoại của bạn thuộc về một thuộc tính riêng đã được khai báo.
Upsert object là bất đồng bộ, ghi CRM thì không
batch/upsert trả về 202 kèm một processId, rồi mới áp dụng sau. Một id không tồn tại sẽ thất bại bất đồng bộ và vẫn trả về 202 cho bên gọi. PATCH /v3/companies/{id} trả về 204 và được áp dụng đồng bộ. Nếu luồng đồng bộ của bạn báo thành công, chỉ đường đồng bộ mới xứng đáng với từ đó mà không cần một lệnh đọc kiểm tra lại.
Danh sách kiểm tra tích hợp ngắn gọn
- Khóa API tách riêng theo từng dịch vụ và từng môi trường, xoay vòng khi có thay đổi nhân sự.
- Mọi lệnh ghi đi qua một client duy nhất biết đọc header giới hạn tốc độ và lùi thời gian khi gặp 429.
- Schema thuộc tính được xác minh lúc khởi động, và luồng đồng bộ từ chối chạy nếu thiếu thuộc tính.
- Lỗi 409 khi tạo công ty nghĩa là nhận lấy công ty cũ, không phải thử lại.
- Đường hàng loạt dùng API object để đạt thông lượng, còn route CRM cho bất cứ thứ gì cần xác nhận chắc chắn.
- Webhook bất biến khi gọi lại, gộp theo lô, giới hạn theo IP và mang theo header bí mật dùng chung.
- Đồng bộ danh bạ gia tăng dùng
modifiedSince, không duyệt toàn bộ danh sách.
Xây dựng và duy trì lớp này là công việc kỹ thuật thực thụ: xác minh schema, lùi thời gian, logic nhận lấy bản ghi, đối soát. Tajo tồn tại để gánh phần đó, giữ dữ liệu Shopify và thương mại đồng bộ với danh bạ, công ty và sự kiện của Brevo mà không ai phải tự viết tay logic thử lại và khử trùng lặp. Nếu bạn tự đấu nối, hướng dẫn tích hợp Brevo đi qua các lựa chọn mô hình dữ liệu cần quyết trước khi viết mã.
Những điểm chính cần nhớ
- API là một bề mặt REST duy nhất tại
https://api.brevo.com/v3/, xác thực bằng headerapi-keychứ không phải bearer token. - Giới hạn tốc độ rất chênh lệch: việc gửi gần như không bị đo đếm, trong khi phần lớn endpoint còn lại chia nhau 100 request mỗi giờ trên gói tiêu chuẩn.
- Có SDK chính thức cho bảy ngôn ngữ, nhưng bề mặt HTTP đủ đơn giản để gọi trực tiếp khi bạn chỉ cần vài endpoint.
- Chế độ sandbox chỉ kiểm tra định dạng request, nên hãy giữ một tài khoản riêng để thử nghiệm mọi thứ ngoài việc gửi.
- Phản hồi 2xx không chứng minh lệnh ghi đã được áp dụng. Thuộc tính chưa khai báo bị bỏ âm thầm, và upsert object là bất đồng bộ.
- Hãy thiết kế để né các giới hạn cố định: một công ty cho mỗi domain, một triệu bản ghi cho mỗi loại object, không có xóa hàng loạt cho object tiêu chuẩn, và bộ lọc thuộc tính lặng lẽ không làm gì cả.