Rate limitlar
So'rovlar chegarasi, kunlik va oylik kvotalar, RateLimit-* headerlari va 429 javobini to'g'ri qayta ishlash (exponential backoff).
Limitlar#
Har bir akkaunt uchun test va live rejimlarda alohida limitlar bor:
- Daqiqalik so'rovlar chegarasi (standart: test 120/daqiqa, live 600/daqiqa);
- Kunlik va oylik so'rovlar kvotasi;
- Kunlik buyurtmalar soni va bir vaqtdagi faol buyurtmalar soni.
Aniq qiymatlar tarifingizga bog'liq — Kabinet → Limitlar yoki GET /v1/me javobidagi limits.
Headerlar#
Har bir javobda IETF RateLimit draft headerlari va mashhur X-RateLimit-* ekvivalentlari qaytadi:
| Header | Ma'nosi |
|---|---|
RateLimit-Policy | Siyosat, masalan 600;w=60 |
RateLimit-Limit | Oynadagi maksimal so'rovlar |
RateLimit-Remaining | Qolgan so'rovlar |
RateLimit-Reset | Oyna yangilanishigacha soniyalar |
X-RateLimit-Limit / -Remaining | Yuqoridagilar bilan bir xil |
X-RateLimit-Reset | Yangilanish vaqti — Unix epoch (soniya) |
X-Quota-Limit / X-Quota-Remaining | Kunlik kvota va qoldiq |
Retry-After | Faqat 429 da: qancha soniya kutish kerak |
X-Request-Id | Har bir so'rov ID si — qo'llab-quvvatlashga yuboring |
HTTP
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 12
RateLimit-Policy: 120;w=60
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 12
X-Request-Id: req_…
{"type":"https://api.milliysavdo.uz/docs/errors#rate_limited","title":"So'rovlar chegarasi oshdi","status":429,"code":"rate_limited", …}429 ni qayta ishlash#
429 kodlari: rate_limited (daqiqalik), quota_exceeded (kunlik/oylik), order_limit_reached, too_many_failed_orders, temporarily_blocked.
Retry-Afterbo'lsa — aynan shuncha kuting.- Bo'lmasa — exponential backoff (1s, 2s, 4s… maks 30s) + tasodifiy jitter.
quota_exceededda qayta urinish foyda bermaydi — ertangi kungacha kuting yoki limitni oshirishni so'rang.
Diqqat
Daqiqalik limit oshsa, faqat o'sha daqiqa yopiladi. Lekin
Retry-After ga qaramay limitdan bir necha baravar ko'p so'rov yuborilsa yoki bitta IP'dan ko'p yaroqsiz kalit kelsa — temporarily_blocked (10–15 daqiqa).import random, time, requests
def request_with_retry(method, url, *, max_attempts=5, **kw):
for attempt in range(max_attempts):
resp = requests.request(method, url, timeout=30, **kw)
if resp.status_code != 429 and resp.status_code < 500:
return resp
if attempt == max_attempts - 1:
return resp
retry_after = resp.headers.get("Retry-After")
delay = float(retry_after) if retry_after else min(2 ** attempt, 30)
time.sleep(delay + random.uniform(0, 0.5)) # jitterMaslahat
POST /v1/orders ni qayta yuborganda albatta bir xil Idempotency-Key ishlating — aks holda ikkita raqam olishingiz mumkin.Limitni tejash#
- Pollingning o'rniga webhooklardan foydalaning.
- Katalogni (
/countries,/services) keshlang — u tez-tez o'zgarmaydi. RateLimit-Remainingni kuzating va 0 ga yaqinlashganda sekinlashing.