OpenRouter रेट लिमिट और HTTP 429: मूल कारणों का विश्लेषण और अनुरोध रीस्टोर करने का तरीका
OpenRouter में HTTP 429 और 402 त्रुटियों के निदान के लिए एक व्यावहारिक गाइड: मुफ्त टियर कोटे को प्लेटफ़ॉर्म और अपस्ट्रीम प्रदाता सीमाओं से अलग करना, हेडर और मेटाडेटा की जांच करना, और एक लचीली पायथन रीट्राय स्क्रिप्ट लागू करना।
विषय-सूची

OpenRouter गेटवे के माध्यम से बड़ी संख्या में AI मॉडल को अनुरोध भेजते समय, क्लाइंट एप्लिकेशन को अक्सर HTTP 429 Too Many Requests स्थिति कोड का सामना करना पड़ता है। चूंकि OpenRouter दर्जनों स्वतंत्र इंफ़रेंस प्रदाताओं को एकीकृत करता है, इसलिए यह त्रुटि बुनियादी ढांचे के बिल्कुल अलग-अलग स्तरों पर उत्पन्न हो सकती है। बिना सोचे-समझे तुरंत पुनः प्रयास करने से अक्सर क्लाइंट रेट-लिमिट हो जाता है या पुनः प्रयास के प्रयास व्यर्थ चले जाते हैं। स्थिर अनुरोध प्रवाह को बहाल करने के लिए विफलता के सटीक स्तर की पहचान करना और उसके अनुरूप उपाय चुनना आवश्यक है: प्रतीक्षा करना (backoff), समवर्ती अनुरोधों (concurrency) को कम करना, मॉडल प्रदाता बदलना, या व्यय सीमा (spending caps) को समायोजित करना।
सीमाओं के स्तर: मुफ्त टियर, प्लेटफ़ॉर्म और अपस्ट्रीम
आधिकारिक OpenRouter Limits दस्तावेज़ सेवा-व्यापी रेट लिमिट, व्यक्तिगत प्रदाता थ्रूपुट और खाता शेष प्रवर्तन के बीच स्पष्ट अंतर करता है।
OpenRouter Pricing पृष्ठ पर, बुनियादी मुफ्त टियर सार्वजनिक रूप से उपलब्ध मुफ्त मॉडलों (जिनमें :free प्रत्यय होता है) के लिए प्रति दिन 50 अनुरोधों की सीमा लागू करता है। चूंकि प्रति मिनट अनुरोध (RPM) की सटीक सीमाएं और टियर थ्रेशोल्ड समय के साथ बदल सकते हैं, इसलिए वास्तविक संख्यात्मक मानों को हमेशा लाइव सीमा तालिका के माध्यम से सत्यापित किया जाना चाहिए।
त्रुटियों का विश्लेषण करते समय, HTTP 429 और संबंधित HTTP 402 स्थिति के लिए जिम्मेदार स्तरों को अलग-अलग समझना महत्वपूर्ण है:
- OpenRouter प्लेटफ़ॉर्म रेट लिमिट (Platform Rate Limits)। ये तब उत्पन्न होती हैं जब स्वयं राउटर को बहुत तेज़ी से अनुरोध प्राप्त होते हैं। दैनिक मुफ्त पूल कोटा इसी प्लेटफ़ॉर्म-स्तरीय सीमा श्रेणी में आता है (न कि किसी स्वतंत्र तीसरे पक्ष के प्रतिबंध में): मुफ्त मॉडल पर प्रति दिन 50 अनुरोधों की सीमा पार होने पर, प्लेटफ़ॉर्म दैनिक काउंटर रीसेट होने तक आने वाले अनुरोधों को अस्वीकार कर देता है। जब प्लेटफ़ॉर्म-स्तरीय रेट लिमिट लागू होती है, तो सर्वर
X-RateLimit-Limit,X-RateLimit-Remaining, औरX-RateLimit-ResetHTTP हेडर लौटाता है। सफल रिस्पॉन्स (HTTP 200) में ये परिचालन हेडर शामिल नहीं होते हैं, जिसका अर्थ है कि सामान्य ट्रैफ़िक के दौरान क्लाइंट एप्लिकेशन सीमाओं का अनुमान लगाने के लिए इन पर निर्भर नहीं रह सकते हैं। - अपस्ट्रीम प्रदाता रेट लिमिट (Upstream Provider Rate Limits)। मॉडल भौतिक रूप से विशिष्ट अपस्ट्रीम कंपनियों (जैसे Anthropic, Meta, DeepSeek, Mistral, या तृतीय-पक्ष क्लाउड होस्ट) के सर्वर पर होस्ट और संचालित किए जाते हैं। यदि उस अपस्ट्रीम भागीदार का बुनियादी ढांचा ओवरलोड हो जाता है, तो OpenRouter क्लाइंट को 429 स्थिति कोड अग्रेषित करता है। रिस्पॉन्स बॉडी संरचना में,
error.metadata.provider_codeफ़ील्ड उपलब्ध होने पर अपस्ट्रीम प्रदाता का मूल त्रुटि कोड (उदाहरण के लिए, 429) शामिल करता है, न कि प्रदाता का नाम या स्ट्रिंग पहचानकर्ता। - वित्तीय सीमाएं (
HTTP 402 Payment Required)। OpenRouter Limits दस्तावेज़ बिलिंग समाप्ति को फ़्रीक्वेंसी रेट सीमाओं से स्पष्ट रूप से अलग करता है। 402 स्थिति कोड अपर्याप्त या नकारात्मक खाता शेष, या किसी व्यक्तिगत API कुंजी व्यय सीमा (key cap) तक पहुंचने का संकेत देता है, न कि केवल शून्य शेष राशि को।
वर्तमान कुंजी मापदंडों का सीधे API अनुरोध द्वारा निरीक्षण किया जा सकता है:
curl -s -X GET https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
रिस्पॉन्स पेलोड में usage, limit_reset, और limit_remaining फ़ील्ड वापस आते हैं। limit_remaining: null का मान इंगित करता है कि इस विशिष्ट API कुंजी पर कोई स्थानीय व्यय सीमा लागू नहीं है। यह मान यह सत्यापित नहीं करता है कि संगठन के प्राथमिक खाते में धनराशि उपलब्ध है या नहीं; यह केवल यह पुष्टि करता है कि इस व्यक्तिगत टोकन के लिए कोई कृत्रिम व्यय सीमा कॉन्फ़िगर नहीं की गई है।
निदान सारांश तालिका
| रिस्पॉन्स कोड और संकेत | जांच का स्रोत | मूल कारण | क्लाइंट की कार्रवाई |
|---|---|---|---|
HTTP 402 Payment Required | GET /api/v1/key एंडपॉइंट या डैशबोर्ड | अपर्याप्त/नकारात्मक संगठन शेष या कुंजी व्यय सीमा समाप्त (limit_remaining: 0) | बैलेंस टॉप अप करें या कुंजी सीमा बढ़ाएं; बिना बदलाव के प्रोग्रामेटिक रीट्राय व्यर्थ हैं |
HTTP 429 (X-RateLimit-* हेडर के साथ) | गेटवे HTTP रिस्पॉन्स हेडर | OpenRouter प्लेटफ़ॉर्म की समवर्तीता या अनुरोध आवृत्ति सीमा पार हो गई | Retry-After हेडर की जांच करें और समानांतर थ्रेड्स की संख्या कम करें |
HTTP 429 (provider_code में कोड के साथ) | JSON बॉडी में error.metadata.provider_code फ़ील्ड (वैकल्पिक) | अपस्ट्रीम प्रदाता पर ओवरलोड या आउटेज (अपस्ट्रीम का मूल त्रुटि कोड) | मॉडल या प्रदाता बदलना मदद कर सकता है लेकिन तुरंत समाधान की गारंटी नहीं देता; Activity > provider_responses में प्रदाता की पुष्टि करें |
:free मॉडल पर HTTP 429 | OpenRouter Pricing सेक्शन | दैनिक प्लेटफ़ॉर्म सीमा (50 अनुरोध/दिन) या समग्र क्षमता समाप्त | सशुल्क मॉडल पर अपग्रेड करें या कार्य को बाद के लिए टालें |
जटिल रूटिंग के साथ HTTP 429 | डैशबोर्ड: Activity > Request > View Raw Metadata | provider_responses ऑब्जेक्ट के भीतर मध्यवर्ती नोड विफलता | विफल प्रदाता की पहचान करें और BYOK/Routing गाइड में फ़ालबैक श्रृंखला सत्यापित करें |
दो परिदृश्यों का विश्लेषण: कुंजी सीमा बनाम प्रदाता विफलता
अनुरोध विफल होने पर क्लाइंट एप्लिकेशन कैसे प्रतिक्रिया देता है, यह मेटाडेटा निरीक्षण पर निर्भर करता है। नीचे दो काल्पनिक परिदृश्य दिए गए हैं (वास्तविक खाते के अवलोकनों के बजाय उदाहरणात्मक मामले)।
परिदृश्य 1 (काल्पनिक): स्थानीय टोकन सीमा समाप्त होना
इस काल्पनिक परिदृश्य में, एक बैकग्राउंड वर्कर को HTTP 402 अस्वीकृति प्राप्त होती है। यहाँ संगठन का सकारात्मक शेष एक स्पष्ट आधारभूत धारणा है, जिसे वेब डैशबोर्ड के माध्यम से अलग से सत्यापित किया गया है (कुंजी एंडपॉइंट स्वयं पूरे संगठन के शेष की पुष्टि नहीं करता है)। https://openrouter.ai/api/v1/key एंडपॉइंट पर क्वेरी करने पर प्राप्त होता है:
{
"data": {
"label": "worker-key",
"usage": 25.04,
"limit": 25.0,
"is_free_tier": false,
"limit_remaining": 0.0,
"limit_reset": null
}
}
यद्यपि प्राथमिक खाता शेष धनात्मक है, limit_remaining फ़ील्ड शून्य तक पहुँच गया है। टोकन प्रशासक द्वारा निर्धारित $25 की व्यय सीमा तक पहुँच चुका है। इस कुंजी का उपयोग करके किया गया कोई भी स्वचालित पुनः प्रयास उसी 402 त्रुटि के साथ बार-बार विफल होगा। वर्कर प्रक्रिया को तुरंत समाप्त होना चाहिए और ऑपरेटर को कुंजी की सीमा समायोजित करने के लिए सूचित करना चाहिए।
परिदृश्य 2 (काल्पनिक): अपस्ट्रीम प्रदाता पर अत्यधिक लोड
एक उदाहरणात्मक उदाहरण के रूप में, उस मामले पर विचार करें जहां अपस्ट्रीम आउटेज के कारण अनुरोध HTTP 429 लौटाता है। केवल 429 स्थिति कोड प्राप्त होने से समग्र गेटवे की स्थिति या शेष खाते की राशि के बारे में कोई निश्चित निष्कर्ष नहीं निकाला जा सकता है। त्रुटि रिस्पॉन्स बॉडी में एक वैकल्पिक मेटाडेटा ब्लॉक शामिल हो सकता है:
{
"error": {
"message": "Provider returned rate limit error",
"code": 429,
"metadata": {
"provider_code": 429
}
}
}
error.metadata.provider_code फ़ील्ड वैकल्पिक है और उपलब्ध होने पर अपस्ट्रीम प्रदाता का मूल स्थिति कोड (इस उदाहरण में, 429) दिखाता है—प्रदाता का नाम या स्ट्रिंग पहचानकर्ता नहीं। अकेले इस कोड की उपस्थिति यह प्रकट नहीं करती है कि किस विशिष्ट होस्ट ने कॉल को अस्वीकार किया।
विफल प्रदाता की पहचान करने के लिए, प्रबंधन डैशबोर्ड में जाएं: Activity > विशिष्ट अनुरोध > View Raw Metadata। जैसा कि रूटिंग गाइड में प्रलेखित है, provider_responses ऑब्जेक्ट प्रत्येक मूल्यांकित प्रदाता और उसकी स्थिति को सूचीबद्ध करता है। किसी अन्य प्रदाता पर स्विच करना या मॉडल बदलना इस स्थिति में सहायक हो सकता है, लेकिन यह तत्काल रिकवरी की गारंटी नहीं देता है।
Python 3 क्लाइंट रीट्राय स्क्रिप्ट
जब HTTP 429 स्थिति अस्थायी होती है, तो अगले प्रयास से पहले की देरी की गणना Retry-After हेडर का उपयोग करके की जाती है। सर्वर इस हेडर को सेकंड की पूर्णांक संख्या के रूप में या HTTP-प्रारूपित दिनांक स्ट्रिंग के रूप में भेजता है।
निम्नलिखित कार्यान्वयन विशेष रूप से केवल Python 3 मानक लाइब्रेरी पर निर्भर करता है। यह केवल HTTP 429 त्रुटियों को संभालता है, सर्वर द्वारा दिए गए विलंब हेडर के अभाव में यादृच्छिक विचलन (jitter) के साथ घातीय बैकऑफ़ (exponential backoff) लागू करता है, और यदि सर्वर 60 सेकंड से अधिक की प्रतीक्षा अवधि का अनुरोध करता है तो निष्पादन को रोक देता है।
import email.utils
import json
import os
import random
import sys
import time
import urllib.error
import urllib.request
API_KEY = os.environ.get("OPENROUTER_API_KEY")
MODEL_ID = os.environ.get("OPENROUTER_MODEL_ID", "openai/gpt-4o-mini")
MAX_ATTEMPTS = 3
MAX_ACCEPTABLE_WAIT = 60.0
def parse_retry_after(header_value: str | None) -> float | None:
if not header_value:
return None
raw = header_value.strip()
if raw.isdigit():
return max(0.0, float(raw))
try:
parsed_date = email.utils.parsedate_to_datetime(raw)
delay = parsed_date.timestamp() - time.time()
return max(0.0, delay)
except Exception:
return None
def execute_completion(prompt_text: str) -> str | None:
if not API_KEY:
sys.stderr.write("Переменная окружения OPENROUTER_API_KEY не задана.\n")
return None
endpoint = "https://openrouter.ai/api/v1/chat/completions"
payload = json.dumps(
{
"model": MODEL_ID,
"messages": [{"role": "user", "content": prompt_text}],
}
).encode("utf-8")
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
for attempt in range(1, MAX_ATTEMPTS + 1):
req = urllib.request.Request(endpoint, data=payload, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=30) as response:
status_code = response.getcode()
body = response.read().decode("utf-8")
if status_code == 200:
data = json.loads(body)
return data["choices"][0]["message"]["content"]
except urllib.error.HTTPError as err:
if err.code == 429:
retry_header = err.headers.get("Retry-After")
server_delay = parse_retry_after(retry_header)
if server_delay is not None:
wait_seconds = server_delay
else:
base_delay = 2.0 ** attempt
wait_seconds = base_delay + random.uniform(0.1, 1.0)
if wait_seconds > MAX_ACCEPTABLE_WAIT:
sys.stderr.write(
f"Сервер запросил паузу {wait_seconds:.1f} с. "
"Ожидание превышает 60 секунд. Запрос отменен.\n"
)
return None
if attempt == MAX_ATTEMPTS:
sys.stderr.write("Исчерпан лимит из 3 попыток на статус 429.\n")
return None
sys.stderr.write(
f"Получен 429. Попытка {attempt} завершилась неудачей. "
f"Пауза {wait_seconds:.2f} с перед следующим запросом.\n"
)
time.sleep(wait_seconds)
continue
elif err.code == 402:
sys.stderr.write("Ошибка 402: проверьте баланс счета и лимит ключа.\n")
return None
else:
sys.stderr.write(f"HTTP-ошибка {err.code}: запрос отклонен без повтора.\n")
return None
except urllib.error.URLError as err:
sys.stderr.write(f"Сетевой сбой: {err.reason}. Повтор отменен.\n")
return None
return None
if __name__ == "__main__":
result = execute_completion("Назови три базовых принципа надежности сетевых API.")
if result:
print(result)
चूंकि ऊपर दिए गए स्क्रिप्ट स्निपेट में मूल रूसी डायग्नोस्टिक लॉगिंग स्ट्रिंग्स को बाइट-दर-बाइट सुरक्षित रखा गया है, इसलिए इसके आंतरिक निर्णय वृक्ष (decision tree) और स्थानीयकृत अर्थों का स्पष्टीकरण यहाँ दिया गया है:
OPENROUTER_API_KEY एनवायरनमेंट वेरिएबल सेट नहीं है(“Переменная окружения OPENROUTER_API_KEY не задана.\n”): यह दर्शाता है कि आवश्यक वातावरण चर अनुपलब्ध है; फ़ंक्शन नेटवर्क कॉल किए बिना तुरंत रुक जाता है।सर्वर ने विराम का अनुरोध किया ... प्रतीक्षा 60 सेकंड से अधिक है। अनुरोध रद्द किया गया(“Сервер запросил паузу … Ожидание превышает 60 секунд. Запрос отменен.\n”): जब सर्वर काRetry-AfterहेडरMAX_ACCEPTABLE_WAIT(60 सेकंड) से अधिक प्रतीक्षा अवधि की मांग करता है, तो बैकग्राउंड प्रोसेस को अनिश्चित काल के लिए रोकने के बजाय अनुरोध तुरंत रद्द कर दिया जाता है।स्थिति 429 पर 3 प्रयासों की सीमा समाप्त(“Исчерпан лимит из 3 попыток на статус 429.\n”): यह दर्शाता है कि 429 स्थिति कोड पर सभी 3 अनुमत पुनः प्रयास विफल हो चुके हैं।429 प्राप्त हुआ। प्रयास X विफल रहा। अगले अनुरोध से पहले Y सेकंड का विराम(“Получен 429. Попытка {attempt} завершилась неудачей. Пауза {wait_seconds:.2f} с перед следующим запросом.\n”): यह प्रयास X पर अस्थायी दर सीमा विफलता को लॉग करता है और पुनः प्रयास करने से पहले गणना किए गए अंतराल Y सेकंड तक प्रतीक्षा करता है।त्रुटि 402: खाता शेष और कुंजी सीमा की जांच करें(“Ошибка 402: проверьте баланс счета и лимит ключа.\n”): यह अपूरणीय HTTP 402 भुगतान विफलता को इंगित करता है (शेष समाप्त या कुंजी सीमा पार); इस स्थिति में कोई पुनः प्रयास नहीं किया जाता है।HTTP त्रुटि {code}: बिना पुनः प्रयास के अनुरोध अस्वीकृत(“HTTP-ошибка {err.code}: запрос отклонен без повтора.\n”): किसी अन्य HTTP त्रुटि कोड को लॉग करता है और निष्पादन समाप्त करता है।नेटवर्क विफलता: {reason}। पुनः प्रयास रद्द(“Сетевой сбой: {err.reason}. Повтор отменен.\n”): सामान्य सॉकेट या नेटवर्क त्रुटियों (URLError) को पकड़ता है और कॉल को दोहराने से रोकता है ताकि अस्पष्ट नेटवर्क स्थिति में डुप्लिकेट अनुरोध न जाएं।- परीक्षण प्रॉम्प्ट (“Назови три базовых принципа надежности сетевых API.”) का अर्थ है: “नेटवर्क API विश्वसनीयता के तीन बुनियादी सिद्धांत बताइए।”
नेटवर्क अनुरोधों को पुनः प्रयास करना और उनके दुष्प्रभाव
स्वायत्त एजेंट वर्कफ़्लो में टूल-कॉलिंग (tool calling) प्रक्रियाओं को डिज़ाइन करते समय, HTTP अनुरोधों को दोहराने में अत्यधिक सावधानी बरतनी चाहिए। यदि मॉडल ने पिछले चरण में पहले ही किसी ऐसे बाहरी टूल को निष्पादित कर दिया है जिसने बाहरी सिस्टम की स्थिति को बदल दिया है (जैसे कि डेटाबेस में लिखना, भुगतान प्रक्रिया शुरू करना, या कोई टिकट बनाना), तो पूरी श्रृंखला को दोबारा चलाने से डुप्लिकेट ऑपरेशन का जोखिम होता है। यदि संबंधित व्यावसायिक टूल पहले ही निष्पादित हो चुके हों, या नेटवर्क का परिणाम अस्पष्ट रहा हो (जैसे कनेक्शन टूटना या टाइम-आउट, जहाँ यह अनिश्चित हो कि अनुरोध वास्तव में सर्वर तक पहुँचा और संसाधित हुआ या नहीं), तो कभी भी स्वचालित पुनः प्रयास नहीं किया जाना चाहिए।
ऊपर दी गई स्क्रिप्ट में, पुनः प्रयास केवल उन अनुरोधों के लिए सख्ती से सीमित हैं जिन्हें मॉडल द्वारा HTTP 429 स्थिति कोड के साथ स्पष्ट रूप से अस्वीकार कर दिया गया है। महत्वपूर्ण बात यह है कि टेक्स्ट जनरेशन को कभी भी कड़ाई से इडेम्पोटेंट (idempotent) या लागत-मुक्त नहीं माना जा सकता: कॉल को दोहराने से अतिरिक्त टोकन कोटा और बजट खर्च होता है, और मॉडल सैंपलिंग की स्टोकेस्टिक प्रकृति के कारण बाद के आउटपुट भिन्न हो सकते हैं। यदि एजेंट द्वारा किसी बाहरी कमांड को निष्पादित करते समय विफलता होती है, तो भाषा मॉडल के साथ संवाद फिर से शुरू करने से पहले सिस्टम की स्थिति को एक्शन लॉग के माध्यम से सिंक्रनाइज़ किया जाना चाहिए।
लचीले रूटिंग आर्किटेक्चर का निर्माण
मूल्य निर्धारण पृष्ठ पर, फ्री टियर मुफ्त मॉडल पर प्रति दिन 50 अनुरोधों की प्लेटफ़ॉर्म-स्तरीय सीमा लागू करता है। यह ध्यान रखना महत्वपूर्ण है कि दस्तावेज़ों में उल्लिखित प्लेटफ़ॉर्म सीमाओं का अभाव सशुल्क मॉडल पर जाने पर लागू होता है, न कि केवल खाता क्रेडिट खरीदने पर—खाता रिचार्ज करने से :free एंडपॉइंट्स से दर सीमाएं स्वतः समाप्त नहीं होती हैं। सटीक शर्तों और अपने खाते के कोटे को हमेशा लाइव सीमा तालिका में सत्यापित किया जाना चाहिए। इसके अतिरिक्त, सशुल्क मॉडल का उपयोग करने पर भी अपस्ट्रीम प्रदाता क्लस्टर ओवरलोड पूरी तरह से समाप्त नहीं होता है (और प्रदाता बदलना सहायक हो सकता है, लेकिन यह तत्काल रिकवरी की गारंटी नहीं देता है)।
उत्पादन परिवेश में सेवाओं की विश्वसनीयता सुनिश्चित करने के लिए इंजीनियरिंग टीमें निम्नलिखित रणनीतियों का संयोजन करती हैं:
- OpenRouter के
modelsअनुरोध पैरामीटर ऐरे में फ़ालबैक मॉडल निर्दिष्ट करना, जिससे प्राथमिक विकल्प विफल होने पर गेटवे स्वचालित रूप से ट्रैफ़िक को वैकल्पिक प्रदाता पर पुनर्निर्देशित कर सके। - टास्क कतारों, रेट लिमिटर्स या टोकन बकेट एल्गोरिदम का उपयोग करके क्लाइंट-साइड पर अधिकतम समवर्ती अनुरोधों को सीमित करना।
- मिशन-महत्वपूर्ण बुनियादी ढांचे के लिए संगत स्कीमा वाले वैकल्पिक मल्टी-मॉडल API के माध्यम से एक स्वतंत्र बैकअप रूट बनाए रखना, जिससे प्राथमिक गेटवे के लंबे समय तक अनुपलब्ध रहने पर ट्रैफ़िक को तुरंत माइग्रेट किया जा सके।