API đối tác (B2B)
Errors & rate limits
Partner API error codes, per-key rate limits with X-RateLimit headers, and how to retry.
On this page
Error format#
Nội dung lỗi có dạng { statusCode, code, message }. message là văn bản tiếng Anh dễ đọc và có thể thay đổi, vì vậy hãy luôn rẽ nhánh theo code.
// Success
{ "success": true, "data": ..., "total": 128, "page": 1, "limit": 20 }
// Error
{ "statusCode": 401, "code": "INVALID_API_KEY", "message": "The API key is invalid." }Lưu ý
Error codes#
| HTTP | code | Ý nghĩa và cách khắc phục |
|---|---|---|
| 401 | API_KEY_REQUIRED | Chưa gửi khóa — hãy thêm header X-API-Key |
| 401 | INVALID_API_KEY | Khóa sai định dạng hoặc không xác định — hãy kiểm tra khóa không bị cắt khi sao chép và không phải khóa Public API |
| 401 | KEY_REVOKED | Khóa đã bị thu hồi — hãy tạo khóa mới |
| 401 | KEY_EXPIRED | Khóa đã hết hạn (bao gồm khóa cũ sau thời gian ân hạn khi xoay vòng) — hãy dùng khóa mới |
| 403 | PARTNER_SUSPENDED | Tài khoản không hoạt động — hãy liên hệ esimoa |
| 403 | INSUFFICIENT_SCOPE | Yêu cầu nằm ngoài các phạm vi của khóa |
| 403 | IP_NOT_ALLOWED | Được gọi từ IP nằm ngoài danh sách cho phép — hãy thêm IP đi ra của máy chủ |
| 404 | PRODUCT_NOT_FOUND | Sản phẩm không xác định hoặc đã ngừng bán |
| 429 | RATE_LIMITED | Đã vượt giới hạn tần suất — thử lại sau số giây trong Retry-After |
Rate limits#
Lưu ý
Yêu cầu API B2B mặc định giới hạn 20,000 lượt mỗi giờ cho mỗi khóa.
Khung 3,600 giây bắt đầu từ yêu cầu đầu tiên; giới hạn theo phút cũng được áp dụng. Hạn mức tính theo số lần gọi, không phải số MB truyền tải. Cài đặt vận hành có thể thay đổi hạn mức.
X-RateLimit-Hour-Limit · X-RateLimit-Hour-Remaining · X-RateLimit-Hour-Reset
Các header này cho biết giới hạn theo giờ, số lần gọi còn lại và thời điểm đặt lại (giây Unix). Khi hết hạn mức theo giờ, hệ thống trả về HTTP 429 kèm Retry-After tính bằng giây. Các lần gọi bị từ chối do giới hạn theo phút không tính vào hạn mức theo giờ.
Mặc định là 300 yêu cầu mỗi phút cho mỗi khóa (theo khung 60 giây, dùng chung cho tất cả máy chủ). esimoa có thể nâng mức này cho từng tài khoản theo hợp đồng. Mọi phản hồi đã xác thực đều kèm header hạn mức.
X-RateLimit-Limit— số yêu cầu được phép mỗi phútX-RateLimit-Remaining— số yêu cầu còn lại trong khung thời gian hiện tạiX-RateLimit-Reset— thời điểm khung thời gian được đặt lại (giây Unix)Retry-After— khi gặp 429, số giây cần chờ trước khi thử lại
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1790000000
HTTP/1.1 429 Too Many Requests
Retry-After: 18
{ "statusCode": 429, "code": "RATE_LIMITED", "message": "Rate limit exceeded (300 requests per minute)." }Retrying#
- Khi nhận mã 429, hãy chờ số giây trong Retry-After rồi thử lại.
- Thử lại lỗi 5xx vài lần với cơ chế lùi lũy thừa (exponential backoff).
- 400, 401, 403 và 404 sẽ không thay đổi khi thử lại — hãy khắc phục nguyên nhân.
- Lưu bộ nhớ đệm danh mục trong vài phút giúp bạn luôn ở dưới giới hạn.
async function b2bFetch(url, attempt = 0) {
const res = await fetch(url, { headers: { 'X-API-Key': process.env.ESIMOA_PARTNER_KEY } });
if (res.status === 429 && attempt < 3) {
const wait = Number(res.headers.get('Retry-After') ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
return b2bFetch(url, attempt + 1);
}
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.message), { code: body.code, status: res.status });
return body;
}