API LinkHarbor cho phép bao nhiêu yêu cầu mỗi phút, một yêu cầu lớn tối đa bao nhiêu, cách đọc các header và cách xử lý 429 đúng cách.
Để giữ API nhanh cho mọi người, LinkHarbor giới hạn số yêu cầu mỗi phút. Các giới hạn không phụ thuộc vào gói – không có hạn mức lệnh gọi API hằng tháng. Bài này liệt kê mọi giới hạn và cho thấy mã của bạn có thể xử lý chúng gọn gàng ra sao.
Yêu cầu được đếm thế nào
- Mỗi yêu cầu rơi vào đúng một bucket, ví dụ user cho yêu cầu đã xác thực hoặc token cho việc đổi token
- Đếm theo từng phút tròn (UTC); bộ đếm bắt đầu lại từ 0 mỗi phút mới
- Tùy bucket, API đếm theo không gian làm việc, theo người, theo kết nối hoặc theo địa chỉ IP
- Các yêu cầu đã thất bại ở bước token, phạm vi hay schema (401, 403 insufficient_scope, 400, 422 validation_failed từ bước kiểm tra schema) không được tính; các lỗi muộn hơn như 403 feature_not_available thì được tính
Mọi giới hạn
| Bucket (X-RateLimit-Bucket) | Giới hạn | Đếm theo | Áp dụng cho |
|---|---|---|---|
| user | 600 mỗi phút | Không gian làm việc với token từ khóa API (mọi khóa và công cụ AI của không gian làm việc cộng lại); người với đăng nhập bảng điều khiển | Mọi yêu cầu đã xác thực đến /v1 không có bucket riêng |
| token | 30 mỗi phút | Địa chỉ IP | POST /v1/token |
| public | 120 mỗi phút | Địa chỉ IP | Yêu cầu đến API không cần xác thực, như GET /v1/plans và GET /v1/pages/available |
| callback | 120 mỗi phút | Địa chỉ IP | POST /v1/callbacks/sale |
| internal | 120 mỗi phút | Địa chỉ IP | URL ingest của tích hợp “Custom (API)” (POST /v1/ingest/{id}) |
| mcp | 120 mỗi phút | Kết nối AI (access token) | Máy chủ MCP tại /mcp |
| oauth | 300 mỗi phút | Địa chỉ IP | Đăng nhập OAuth và discovery cho trợ lý AI |
| auth | 30 mỗi phút | Địa chỉ IP | Đăng nhập, đăng ký, đặt lại mật khẩu (bảng điều khiển và ứng dụng) |
| refresh | 120 mỗi phút | Địa chỉ IP | Gia hạn phiên bảng điều khiển |
| discover | 60 mỗi phút | Người, địa chỉ IP khi chưa đăng nhập | Mục Khám phá của ứng dụng |
| subs_read | 120 mỗi phút | Người, địa chỉ IP khi chưa đăng nhập | Đọc các trang bạn theo dõi (ứng dụng) |
| subs_write | 20 mỗi phút | Người, địa chỉ IP khi chưa đăng nhập | Thay đổi các trang bạn theo dõi (ứng dụng) |
Một ngân sách cho mỗi không gian làm việc
Mọi token từ khóa API trong cùng một không gian làm việc dùng chung 600 yêu cầu mỗi phút – bất kể bạn tạo bao nhiêu khóa. Công cụ của các trợ lý AI đã kết nối cũng được tính ở đây, vì chúng gọi API nội bộ. Vì vậy thêm khóa không làm tăng giới hạn. Nếu tải lớn được chia cho nhiều chương trình, hãy lên kế hoạch dựa trên ngân sách dùng chung.
Các header
- X-RateLimit-Limit
- Giới hạn mỗi phút của bucket, ví dụ 600.
- X-RateLimit-Remaining
- Số yêu cầu còn lại trong phút hiện tại.
- X-RateLimit-Bucket
- Bucket mà yêu cầu rơi vào, ví dụ user.
- Retry-After
- Chỉ với 429 rate_limited: số giây cho đến khi phút tiếp theo bắt đầu. Với api_key_locked, thời gian chờ nằm trong details.retry_after_sec.
Khi đạt giới hạn
Khi đạt giới hạn, API phản hồi HTTP 429 với phần thân này. Văn bản trong message theo ngôn ngữ tài khoản (xem Định dạng lỗi API), ở đây bằng tiếng Anh. Hãy dựa vào mã rate_limited:
HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Bucket: user
{ "error": "rate_limited", "message": "Too many requests. Please try again in a moment.", "retry_after_sec": 37 } - Đọc Retry-After hoặc retry_after_sec
- Đợi ít nhất số giây đó, cộng thêm một chút ngẫu nhiên để không phải mọi tiến trình cùng khởi động lại một lúc
- Chỉ thử lại yêu cầu tối đa vài lần
- Nếu cứ nhận 429, hãy rải công việc ra trong thời gian dài hơn
const BASE = 'https://dock.at-harbor.com';
let cached = null; // { token, expiresAt }
async function getToken() {
if (cached && Date.now() < cached.expiresAt - 60_000) return cached.token;
const res = await fetch(BASE + '/v1/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
key_id: process.env.LH_KEY_ID,
key_secret: process.env.LH_KEY_SECRET,
}),
});
if (!res.ok) throw new Error('Token exchange failed: HTTP ' + res.status);
const data = await res.json();
cached = { token: data.token, expiresAt: Date.now() + data.expires_in * 1000 };
return cached.token;
}
async function lh(method, path, body, attempt = 0) {
const headers = { Authorization: 'Bearer ' + (await getToken()) };
if (body !== undefined) headers['Content-Type'] = 'application/json';
const res = await fetch(BASE + path, {
method,
headers,
body: body === undefined ? undefined : JSON.stringify(body),
});
if (res.status === 429 && attempt < 3) {
const wait = Number(res.headers.get('Retry-After') ?? 5);
await new Promise((r) => setTimeout(r, (wait + Math.random() * 2) * 1000));
return lh(method, path, body, attempt + 1);
}
if (res.status === 401 && attempt === 0) {
cached = null; // token đã hết hạn – thử thêm một lần với token mới
return lh(method, path, body, attempt + 1);
}
const data = await res.json().catch(() => null);
if (!res.ok) throw new Error((data && data.error) + ' (HTTP ' + res.status + ')');
return data;
}
// Ví dụ: const { items } = await lh('GET', '/v1/pages'); Mẹo cho lượng dữ liệu lớn
- Lưu token vào bộ nhớ đệm và chỉ làm mới ngay trước khi hết hạn sau 15 phút
- Theo dõi X-RateLimit-Remaining và chậm lại khi giá trị thấp
- Gửi yêu cầu lần lượt thay vì qua hàng chục kết nối song song
- Tải danh sách một lần và lọc cục bộ thay vì truy vấn từng trang riêng lẻ
- Rải các lần đồng bộ lớn ra nhiều phút
- Thử lại lỗi 5xx với khoảng nghỉ tăng dần, nhưng không thử lại lỗi 4xx
Các giới hạn khác
| Cái gì | Giới hạn | Phản hồi |
|---|---|---|
| Đăng nhập thất bại | Khóa sau 5, 10 và 20 lần thử sai cho mỗi địa chỉ email và IP: 60 giây, 5 phút, 30 phút | 429 account_locked |
| Bài gửi biểu mẫu | 10 mỗi giờ cho mỗi địa chỉ IP, trên mọi biểu mẫu | 429 form_rate_limited |
Các lần thử sai khi đổi token sẽ tạm khóa khóa và IP, xem Khóa API và token. Bạn chỉ gửi thông báo đẩy trong bảng điều khiển; giới hạn của chúng được giải thích trong Người theo dõi và thông báo đẩy.
Giới hạn nội dung của gói – trang, liên kết, khối, liên kết rút gọn, v.v. – không phải giới hạn tần suất mà là mức trần cố định. Chúng được liệt kê trong So sánh các gói.
Kích thước yêu cầu
Mọi phần thân đều được đo trước khi API đọc. Kích thước tối đa phụ thuộc vào endpoint:
| Endpoint | Phần thân lớn nhất |
|---|---|
| Đăng nhập, đăng ký và các lệnh gọi không xác thực khác dưới /v1/auth, POST /v1/token, POST /v1/oauth/exchange, các endpoint OAuth cho trợ lý AI dưới /oauth và bước chấp thuận của chúng, POST /v1/ingest/{id}, trang thanh toán của khối Ủng hộ, các lệnh gọi theo dõi của ứng dụng (theo dõi, bộ sưu tập, thiết bị nhận thông báo đẩy), chuyển không gian làm việc, POST /v1/auth/logout-all, xóa tài khoản, thiết lập xác thực hai yếu tố, chấp nhận lời mời, kích hoạt chương trình giới thiệu và bước quay lại khi kết nối tích hợp | 64 KB |
| Mọi endpoint JSON khác, kể cả gửi biểu mẫu trên trang | 1 MB |
| POST /v1/webhooks/{id}/verify-signature và máy chủ MCP tại /mcp | 2 MB |
| Tải tệp lên (POST /v1/assets và POST /v1/pages/{id}/uploads, multipart/form-data) | 11 MB cho toàn bộ yêu cầu, bản thân tệp tối đa 10 MB |
Nếu phần thân lớn hơn, API phản hồi 413 request_too_large; details.max_bytes và details.max_kb cho biết giới hạn. Tệp quá lớn khi tải lên dẫn đến 413 payload_too_large. Các endpoint không có phần thân, như các lệnh DELETE, không nhận phần thân hoặc chỉ nhận {}.
HTTP/1.1 413 Payload Too Large
{ "error": "request_too_large", "message": "…", "details": { "max_bytes": 65536, "max_kb": 64 }, "request_id": "…" } Bên trong phần thân cũng có giới hạn: mọi văn bản có độ dài tối đa, mọi danh sách có số mục tối đa, và các trường không xác định bị từ chối. Các giá trị được liệt kê theo từng endpoint trong tài liệu tham chiếu API. Vi phạm dẫn đến 422 validation_failed, và details nêu trường, quy tắc và giới hạn. Đường dẫn và query string của một yêu cầu cộng lại tối đa 16 KB.
Có thể bạn cũng thấy hữu ích
Không tìm thấy?
Hãy cho chúng tôi biết bạn cần gì, đội hỗ trợ sẽ trực tiếp giúp bạn.