Asosiy kontentga o'tish
MilliySavdo

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:

HeaderMa'nosi
RateLimit-PolicySiyosat, masalan 600;w=60
RateLimit-LimitOynadagi maksimal so'rovlar
RateLimit-RemainingQolgan so'rovlar
RateLimit-ResetOyna yangilanishigacha soniyalar
X-RateLimit-Limit / -RemainingYuqoridagilar bilan bir xil
X-RateLimit-ResetYangilanish vaqti — Unix epoch (soniya)
X-Quota-Limit / X-Quota-RemainingKunlik kvota va qoldiq
Retry-AfterFaqat 429 da: qancha soniya kutish kerak
X-Request-IdHar 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-After bo'lsa — aynan shuncha kuting.
  • Bo'lmasa — exponential backoff (1s, 2s, 4s… maks 30s) + tasodifiy jitter.
  • quota_exceeded da 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))  # jitter

Maslahat

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-Remaining ni kuzating va 0 ga yaqinlashganda sekinlashing.