# Rate limit > Số request mỗi phút cho mỗi API key theo từng gói, các header X-RateLimit, phản hồi 429 trông thế nào, cách backoff và giữ dưới giới hạn. Mỗi API key được gửi một số request nhất định mỗi phút. Con số này phụ thuộc vào gói của tài khoản khách hàng. ## Giới hạn theo gói | Gói | Số request mỗi phút, cho mỗi key | | --- | --- | | Enterprise | 120 | | Custom | Đặt theo khối lượng của bạn. 600 nếu không có thỏa thuận khác. | | Các gói khác | Không có quyền truy cập API (`403 api_not_in_plan`) | Giới hạn tính theo key, không theo tài khoản. Mọi request gửi bằng một key hợp lệ đều được tính, kể cả request thất bại như `404` hay `403 insufficient_scope`. Cửa sổ tính là một phút cố định. Cửa sổ bắt đầu từ request đầu tiên của key và đặt lại sau 60 giây. Đây không phải trung bình trượt, nên một loạt request dồn dập ở đầu cửa sổ có thể dùng hết hạn mức của cả phút. MCP server có giới hạn riêng: 120 lệnh gọi mỗi phút cho mỗi ứng dụng đã kết nối. Xem [MCP server](https://developer.hillsmusic.com/vi/mcp/overview/). ## Header Mọi phản hồi đều mang: | Header | Ý nghĩa | | --- | --- | | `X-RateLimit-Limit` | Số request mỗi phút key này được phép gửi. | | `X-RateLimit-Remaining` | Số request còn lại trong phút hiện tại. | Phản hồi `429` còn mang thêm: | Header | Ý nghĩa | | --- | --- | | `Retry-After` | Số giây cho đến khi cửa sổ được đặt lại. | `GET /ping` hiển thị cùng các con số này trong body, dưới `plan.rate` và `rate_limit`: ```bash curl "https://api.hillsmusic.com/v1/ping" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ```json { "ok": true, "plan": { "included": true, "plan": "enterprise", "rate": 120 }, "rate_limit": { "limit": 120, "remaining": 119 } } ``` ## Khi bạn vượt giới hạn Khi vượt giới hạn, API trả về `429` trước khi đọc body của request: ``` HTTP/2 429 Retry-After: 23 X-RateLimit-Limit: 120 X-RateLimit-Remaining: 0 {"error":"Too many requests: at most 120 a minute per key.","code":"rate_limited"} ``` Hãy chờ `Retry-After` giây, rồi gửi lại request. Request bị từ chối chưa được xử lý chút nào, nên gửi lại là an toàn, kể cả với thao tác ghi. `POST /ddex/validate` cũng có thể trả về `429 busy` khi có quá nhiều lần kiểm thử chạy cùng lúc. Đó không phải giới hạn mỗi phút của bạn. Hãy chờ vài giây rồi thử lại. ## Backoff trong Node ```js const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); export async function hills(path, init = {}) { for (let attempt = 1; attempt <= 5; attempt++) { const res = await fetch("https://api.hillsmusic.com/v1" + path, { ...init, headers: { ...init.headers, Authorization: `Bearer ${process.env.HILLS_API_KEY}` }, }); if (res.status !== 429) return res; const wait = Number(res.headers.get("Retry-After")) || 2 ** attempt; await sleep(wait * 1000); } throw new Error("Still rate limited after 5 tries"); } ``` ## Tốt hơn là tự điều tiết tốc độ Tốt nhất là đừng chạm đến giới hạn. Hãy đọc `X-RateLimit-Remaining` và giảm tốc khi giá trị này xuống thấp: ```js let remaining = Infinity; async function paced(path) { if (remaining < 5) await sleep(5000); // close to the limit: wait for the window to reset const res = await hills(path); remaining = Number(res.headers.get("X-RateLimit-Remaining") ?? Infinity); return res; } ``` Với curl trong một vòng lặp shell, hãy nghỉ nửa giây giữa các lệnh gọi để giữ dưới 120 request mỗi phút: ```bash for id in 812 813 814; do curl -s "https://api.hillsmusic.com/v1/releases/$id" \ -H "Authorization: Bearer $HILLS_API_KEY" sleep 0.5 done ``` ## Gửi ít request hơn - **Dùng trang lớn.** `GET /releases?limit=100` trả về 100 bản phát hành cho một request thay vì 50. - **Chỉ đồng bộ phần thay đổi.** `GET /releases?updated_since=` chỉ trả về các bản phát hành đã thay đổi kể từ thời điểm đó. - **Dùng webhook thay vì polling.** Đăng ký `release.live` hoặc `delivery.store_status_changed` thay vì vài phút lại kiểm tra từng bản phát hành. Xem [Webhook](https://developer.hillsmusic.com/vi/guides/webhooks/). - **Poll các lần phân phối DDEX chậm thôi.** Một lần phân phối mất từ vài giây đến vài phút. Hãy poll `GET /ddex/{id}` mỗi 10–30 giây, hoặc đăng ký `ddex.import.imported`. - **Cache những gì ít thay đổi**, như danh sách thành viên và doanh thu theo tháng. ## Phân tải qua nhiều key Mỗi key có giới hạn riêng. Dùng một key cho mỗi hệ thống (một cho việc đồng bộ ERP, một cho website) giúp một job bận rộn không chiếm hết hạn mức của các job khác. Đừng tạo thêm key chỉ để lách giới hạn. Nếu cần nhiều hơn, hãy hỏi người phụ trách của bạn tại HILLS Music về gói Custom, nơi giới hạn được đặt theo khối lượng của bạn. Nguồn: https://developer.hillsmusic.com/vi/guides/rate-limits/