Chuyển tới nội dung chính

Giới hạn tần suất

REST API giới hạn số request mà một doanh nghiệp gọi được mỗi giây, tính riêng cho từng module; riêng Email còn có hạn mức gửi hằng ngày. Trang này liệt kê các giới hạn, các header cho biết bạn đang ở đâu, và cách thử lại khi chạm giới hạn.

Số request mỗi giây​

Giới hạn được đếm theo doanh nghiệp (không theo API key), trong cửa sổ trượt một giây. Mọi key của một doanh nghiệp dùng chung một hạn mức.

EndpointGiới hạn
Hỗ trợ, Sản phẩm và CRM: mọi thứ dưới /chat/50 request mỗi giây
Thanh toán: /payments và /einvoices20 request mỗi giây
Email và phần còn lại: /emails, /domains, /templates, /contacts, /audiences, /segments, /topics, /broadcasts, /automations, /events, /webhooks, /api-keys, /logs, /usage10 request mỗi giây

Mỗi module có hạn mức riêng: một đợt gửi email dồn dập không làm chậm các lời gọi chat hay thanh toán.

Chat gateway tại chat.hatang.dev, nơi widget và SDK di động kết nối, có giới hạn riêng về khách truy cập và tin nhắn. Xem Giới hạn.

Header giới hạn tần suất​

Mọi response của endpoint có giới hạn tần suất đều kèm các header sau:

HeaderÝ nghĩa
ratelimit-limitSố request được phép trong một cửa sổ của module này
ratelimit-remainingSố request còn lại trong cửa sổ hiện tại
ratelimit-resetSố giây tới khi cửa sổ làm mới (luôn là 1)
retry-afterChỉ có khi nhận 429: số giây cần chờ trước khi thử lại
HTTP/1.1 429 Too Many Requests
ratelimit-limit: 10
ratelimit-remaining: 0
ratelimit-reset: 1
retry-after: 1
content-type: application/json

{
"statusCode": 429,
"name": "rate_limit_exceeded",
"message": "Too many requests. You can only make 10 requests per second."
}

Hạn mức email hằng ngày​

Ngoài giới hạn mỗi giây, mỗi doanh nghiệp có hạn mức email hằng ngày: số email được nhận gửi trong một ngày. Mỗi email được nhận tính một lần, dù đến từ POST /emails, gửi theo lô, SMTP relay hay chiến dịch email. Email trả lời gửi từ hộp thư Hỗ trợ không bị tính. Bộ đếm làm mới lúc 0 giờ UTC.

Vượt hạn mức, lệnh gửi nhận 429 daily_quota_exceeded:

{
"statusCode": 429,
"name": "daily_quota_exceeded",
"message": "You have reached your daily email sending quota of 10000. It resets at midnight UTC."
}

Thử lại không có tác dụng cho tới khi hạn mức làm mới. Xem hạn mức và số đã dùng hôm nay ở Email → Cài đặt email (Hạn mức hằng ngày), hoặc qua GET /usage (response đã rút gọn):

{
"object": "usage",
"emails": {
"daily": { "used": 1520, "limit": 10000, "resets_at": "2026-10-24T00:00:00.000Z" }
}
}

Thành viên có quyền Quản lý ở Email đặt được hạn mức thấp hơn hoặc cao hơn cho doanh nghiệp trong Cài đặt email, một lưới an toàn hữu ích khi code lỡ chạy vòng lặp gửi thư. Để trống ô này để dùng mặc định của nền tảng. GET /usage cần key có một scope write.

Thử lại với backoff​

Chỉ thử lại 429 rate_limit_exceeded và lỗi 5xx, không thử lại lỗi 4xx do chính request gây ra. Chờ đúng retry-after giây nếu có header này, nếu không thì tăng thời gian chờ theo cấp số nhân, và cộng thêm một chút ngẫu nhiên để nhiều worker không thử lại cùng lúc. Kết hợp thử lại với Idempotency-Key để lệnh gửi lặp lại không bao giờ tạo bản trùng.

import { Hatang } from "@hatang/sdk";

const hatang = new Hatang(process.env.HATANG_API_KEY, { baseUrl: "https://api.hatang.dev" });
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

// statusCode 0 nghĩa là không kết nối được tới API (lỗi mạng).
const retryable = (e) => e.name === "rate_limit_exceeded" || e.statusCode >= 500 || e.statusCode === 0;

async function withRetry(call, { attempts = 5 } = {}) {
for (let i = 0; ; i++) {
const result = await call();
if (!result.error || !retryable(result.error) || i === attempts - 1) return result;
const backoff = Math.min(1000 * 2 ** i, 30_000);
await sleep(backoff + Math.random() * 250);
}
}

const { data, error } = await withRetry(() =>
hatang.emails.send(
{ from: "Shop <[email protected]>", to: "[email protected]", subject: "Xin chào", html: "<p>Xin chào</p>" },
{ idempotencyKey: "welcome-user-42" },
),
);

SDK Node.js trả về { data, error } và không tự thử lại, nên hãy bọc các lời gọi quan trọng như ví dụ trên.

Giữ dưới giới hạn​

  • Gửi email theo lô. POST /emails/batch gửi tối đa 100 email trong một request, và chỉ tính là một request với giới hạn mỗi giây.
  • Dùng webhook thay vì hỏi liên tục. Đăng ký email.delivered hay chat.message.created thay vì hỏi trạng thái trong vòng lặp (Webhook).
  • Xếp hàng việc lớn. Chạy import và đồng bộ qua hàng đợi với số luồng cố định thay vì bắn mọi request cùng lúc.
  • Đọc header. Giảm tốc khi ratelimit-remaining gần về 0.

Bước tiếp theo​

Xem trang này dạng Markdown