LinkHarbor API प्रति मिनट कितने अनुरोधों की अनुमति देता है, अनुरोध कितना बड़ा हो सकता है, हेडर कैसे पढ़ें और 429 को सही तरीके से कैसे सँभालें।
API को सबके लिए तेज़ रखने के लिए LinkHarbor प्रति मिनट अनुरोधों की संख्या सीमित करता है। सीमाएँ आपके प्लान पर निर्भर नहीं करतीं – API कॉल का कोई मासिक कोटा नहीं है। यह लेख हर सीमा की सूची देता है और दिखाता है कि आपका कोड उन्हें साफ़-सुथरे तरीके से कैसे सँभाल सकता है।
अनुरोध कैसे गिने जाते हैं
- हर अनुरोध ठीक एक bucket में आता है, जैसे ऑथेंटिकेटेड अनुरोधों के लिए user या टोकन बदलने के लिए token
- गिनती हर पूरे मिनट (UTC) की होती है; हर नए मिनट के साथ काउंटर फिर शून्य से शुरू होता है
- bucket के हिसाब से API हर वर्कस्पेस, हर व्यक्ति, हर कनेक्शन या हर IP पते पर गिनता है
- जो अनुरोध टोकन, स्कोप या स्कीमा पर ही विफल हो जाते हैं (401, 403 insufficient_scope, 400, स्कीमा जाँच से 422 validation_failed), वे नहीं गिने जाते; 403 feature_not_available जैसी बाद की त्रुटियाँ गिनी जाती हैं
सभी सीमाएँ
| Bucket (X-RateLimit-Bucket) | सीमा | किसके हिसाब से गिना जाता है | किस पर लागू |
|---|---|---|---|
| user | हर मिनट 600 | API keys के टोकन के लिए वर्कस्पेस (वर्कस्पेस की सभी keys और AI टूल साथ में); डैशबोर्ड साइन-इन के लिए व्यक्ति | /v1 पर सभी ऑथेंटिकेटेड अनुरोध जिनका अपना bucket नहीं है |
| token | हर मिनट 30 | IP पता | POST /v1/token |
| public | हर मिनट 120 | IP पता | बिना ऑथेंटिकेशन के API अनुरोध, जैसे GET /v1/plans और GET /v1/pages/available |
| callback | हर मिनट 120 | IP पता | POST /v1/callbacks/sale |
| internal | हर मिनट 120 | IP पता | “Custom (API)” इंटीग्रेशन का Ingest URL (POST /v1/ingest/{id}) |
| mcp | हर मिनट 120 | AI कनेक्शन (access token) | /mcp पर MCP सर्वर |
| oauth | हर मिनट 300 | IP पता | AI असिस्टेंट के लिए OAuth साइन-इन और डिस्कवरी |
| auth | हर मिनट 30 | IP पता | लॉगिन, रजिस्ट्रेशन, पासवर्ड रीसेट (डैशबोर्ड और ऐप) |
| refresh | हर मिनट 120 | IP पता | डैशबोर्ड सेशन बढ़ाना |
| discover | हर मिनट 60 | व्यक्ति, साइन इन न होने पर IP पता | ऐप का “खोजें” हिस्सा |
| subs_read | हर मिनट 120 | व्यक्ति, साइन इन न होने पर IP पता | आपके फ़ॉलो किए पेज पढ़ना (ऐप) |
| subs_write | हर मिनट 20 | व्यक्ति, साइन इन न होने पर IP पता | आपके फ़ॉलो किए पेज बदलना (ऐप) |
हर वर्कस्पेस का एक बजट
एक ही वर्कस्पेस की API keys के सभी टोकन हर मिनट 600 अनुरोध साझा करते हैं – चाहे आप कितनी भी keys बनाएँ। जुड़े हुए AI असिस्टेंट के टूल भी यहाँ गिने जाते हैं, क्योंकि वे अंदर से API को कॉल करते हैं। इसलिए ज़्यादा keys से सीमा नहीं बढ़ती। अगर बहुत सारा लोड कई प्रोग्राम में बँटा है, तो साझा बजट को ध्यान में रखकर योजना बनाएँ।
हेडर
- X-RateLimit-Limit
- bucket की प्रति मिनट सीमा, जैसे 600।
- X-RateLimit-Remaining
- मौजूदा मिनट में कितने अनुरोध बचे हैं।
- X-RateLimit-Bucket
- वह bucket जिसमें अनुरोध आया, जैसे user।
- Retry-After
- सिर्फ़ 429 rate_limited के साथ: अगला मिनट शुरू होने तक के सेकंड। api_key_locked के साथ इंतज़ार का समय details.retry_after_sec में होता है।
जब सीमा पूरी हो जाए
सीमा पूरी होते ही API HTTP 429 और इस बॉडी के साथ जवाब देता है। message अकाउंट की भाषा में होता है (देखें त्रुटि फ़ॉर्मैट और त्रुटि कोड), यहाँ अंग्रेज़ी में। error कोड 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 } - Retry-After या retry_after_sec पढ़ें
- कम से कम उतने सेकंड इंतज़ार करें, साथ में थोड़ा रैंडम समय, ताकि सभी प्रोसेस एक ही पल में फिर शुरू न हों
- अनुरोध ज़्यादा से ज़्यादा कुछ बार दोहराएँ
- अगर आपको बार-बार 429 मिलता है, तो काम को ज़्यादा समय में बाँटें
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; // टोकन की अवधि ख़त्म – नए टोकन से एक बार और कोशिश करें
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;
}
// उदाहरण: const { items } = await lh('GET', '/v1/pages'); बड़ी मात्रा में डेटा के लिए टिप्स
- टोकन कैश करें और 15 मिनट बाद उसकी अवधि ख़त्म होने से थोड़ा पहले ही उसे नवीनीकृत करें
- X-RateLimit-Remaining पर नज़र रखें और कम होने पर धीमे हो जाएँ
- दर्जनों समानांतर कनेक्शन के बजाय अनुरोध एक के बाद एक भेजें
- हर पेज से अलग-अलग पूछने के बजाय सूचियाँ एक बार लोड करें और उन्हें लोकल रूप से फ़िल्टर करें
- बड़े सिंक कई मिनटों में बाँटें
- 5xx त्रुटियों को बढ़ते अंतराल के साथ दोहराएँ, लेकिन 4xx त्रुटियों को नहीं
दूसरी सीमाएँ
| क्या | सीमा | जवाब |
|---|---|---|
| असफल लॉगिन | हर ईमेल पते और IP पर 5, 10 और 20 असफल कोशिशों के बाद लॉक: 60 सेकंड, 5 मिनट, 30 मिनट | 429 account_locked |
| फ़ॉर्म सबमिशन | हर IP पते से प्रति घंटे 10, सभी फ़ॉर्म मिलाकर | 429 form_rate_limited |
टोकन बदलने की असफल कोशिशें key और IP को कुछ समय के लिए लॉक कर देती हैं, देखें API keys और एक्सेस टोकन। पुश नोटिफ़िकेशन आप सिर्फ़ डैशबोर्ड में भेजते हैं; उनकी सीमाएँ फ़ॉलोअर्स और पुश नोटिफ़िकेशन में बताई गई हैं।
आपके प्लान की कंटेंट सीमाएँ – पेज, लिंक, ब्लॉक, शॉर्ट लिंक वग़ैरह – रेट लिमिट नहीं, बल्कि तय ऊपरी सीमाएँ हैं। ये प्लान की तुलना में दी गई हैं।
अनुरोध का साइज़
हर बॉडी API के पढ़ने से पहले मापी जाती है। वह कितनी बड़ी हो सकती है, यह एंडपॉइंट पर निर्भर करता है:
| एंडपॉइंट | सबसे बड़ी बॉडी |
|---|---|
| /v1/auth के तहत लॉगिन, रजिस्ट्रेशन और दूसरी बिना ऑथेंटिकेशन वाली कॉल, POST /v1/token, POST /v1/oauth/exchange, /oauth के तहत AI असिस्टेंट के OAuth एंडपॉइंट और उनकी सहमति, POST /v1/ingest/{id}, सपोर्ट ब्लॉक का चेकआउट, ऐप की सब्सक्रिप्शन कॉल (फ़ॉलो करना, कलेक्शन, पुश डिवाइस), वर्कस्पेस बदलना, POST /v1/auth/logout-all, अकाउंट हटाना, टू-फ़ैक्टर सेटअप, आमंत्रण स्वीकार करना, रेफ़रल प्रोग्राम सक्रिय करना और इंटीग्रेशन जोड़ते समय लौटने का चरण | 64 KB |
| बाकी सभी JSON एंडपॉइंट, किसी पेज पर फ़ॉर्म भेजना भी | 1 MB |
| POST /v1/webhooks/{id}/verify-signature और /mcp पर MCP सर्वर | 2 MB |
| फ़ाइल अपलोड (POST /v1/assets और POST /v1/pages/{id}/uploads, multipart/form-data) | पूरे अनुरोध के लिए 11 MB, फ़ाइल ख़ुद ज़्यादा से ज़्यादा 10 MB |
अगर बॉडी इससे बड़ी है, तो API 413 request_too_large के साथ जवाब देता है; details.max_bytes और details.max_kb सीमा बताते हैं। अपलोड में बहुत बड़ी फ़ाइल से 413 payload_too_large होता है। बिना बॉडी वाले एंडपॉइंट, जैसे DELETE कॉल, कोई बॉडी या सिर्फ़ {} स्वीकार करते हैं।
HTTP/1.1 413 Payload Too Large
{ "error": "request_too_large", "message": "…", "details": { "max_bytes": 65536, "max_kb": 64 }, "request_id": "…" } बॉडी के अंदर भी सीमाएँ हैं: हर टेक्स्ट की अधिकतम लंबाई होती है, हर सूची की अधिकतम एंट्री, और अज्ञात फ़ील्ड अस्वीकार होते हैं। वैल्यू API रेफ़रेंस में हर एंडपॉइंट के लिए दी गई हैं। उल्लंघन से 422 validation_failed होता है, और details फ़ील्ड, नियम और सीमा बताता है। किसी अनुरोध का पाथ और query string मिलाकर ज़्यादा से ज़्यादा 16 KB लंबे हो सकते हैं।
यह भी आपके काम आ सकता है
कुछ नहीं मिला?
हमें बताएँ कि आपको क्या चाहिए, और हमारी सपोर्ट टीम ख़ुद आपकी मदद करेगी।