Ile i jak liczone#
| Parametr | Wartość |
|---|---|
| Limit domyślny | 600 żądań / 60 s na aplikację |
| Okno | Stałe, wyrównane do pełnej minuty zegara (koniec okna w X-RateLimit-Reset) |
| Klucz | client_id aplikacji — wspólny dla wszystkich tokenów i wszystkich sprzedawców korzystających z tej aplikacji |
| Co się liczy | Każde żądanie do /v1/*, które przeszło uwierzytelnienie — także zakończone 4xx (np. 403 insufficient_scope, 404) i same 429 |
| Co się nie liczy | Żądania bez tokenu lub z nieważnym tokenem (401), bez User-Agent (400) oraz /oauth/* |
| Zakres | Wspólny dla wszystkich zasobów; nie ma osobnych limitów per zasób |
Nagłówki#
| Nagłówek | Kiedy | Znaczenie |
|---|---|---|
X-RateLimit-Limit | każda odpowiedź | Limit aplikacji w bieżącym oknie (domyślnie 600). |
X-RateLimit-Remaining | każda odpowiedź | Ile żądań zostało do końca okna. 0 = kolejne dostanie 429. |
X-RateLimit-Reset | każda odpowiedź | Czas końca okna jako epoch w sekundach (UTC). Różnica do „teraz” = ile czekać na nową pulę. |
Retry-After | tylko 429 | Liczba sekund do końca okna (min. 1). Po tym czasie limit jest pełny. |
X-Trace-Id | każda odpowiedź | Identyfikator żądania — podaj w zgłoszeniu. Możesz nadać własny nagłówkiem X-Request-Id (8–64 znaki [A-Za-z0-9._:-]); wtedy odbijamy Twój. |
Odpowiedź 429#
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-Trace-Id: b7f3c2e1-4d9a-4c1e-9f2a-1d3e5f7a9b0c
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1788386460
Retry-After: 37
{
"traceId": "b7f3c2e1-4d9a-4c1e-9f2a-1d3e5f7a9b0c",
"errors": [
{
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 37s.",
"userMessage": "Za dużo żądań — spróbuj za chwilę."
}
]
}Kod błędu to zawsze rate_limited. Żądania wysłane po 429 w tym samym oknie także wracają jako 429 i również są liczone — ponawianie „na sztywno” co sekundę tylko wydłuża przestój.
Wzorzec ponowień#
Trzy zasady: przy 429 czekaj dokładnie Retry-After; przy 5xx ponawiaj wykładniczo z losowym rozrzutem; 4xx innych niż 429 nie ponawiaj — to błąd w żądaniu, powtórzenie go nie naprawi. Ponowienia zapisów zawsze z tym samym Idempotency-Key.
funkcja wyślij(żądanie):
dla próby od 1 do 5:
odpowiedź = HTTP(żądanie) # z nagłówkiem Idempotency-Key przy POST/PATCH/DELETE
jeśli odpowiedź.status == 429:
czekaj(odpowiedź.nagłówki["Retry-After"] sekund) # dokładnie tyle — nie „chwilę”, nie 2^n
kontynuuj
jeśli odpowiedź.status >= 500:
czekaj(min(30 s, 0,5 s × 2^próby) + losowo(0…0,5 s)) # wykładniczo, z jitterem
kontynuuj
zwróć odpowiedź # 2xx oraz 4xx inne niż 429: NIE ponawiaj
zgłoś awarię z ostatnim X-Trace-Id
funkcja zwolnij_jeśli_trzeba(odpowiedź): # hamowanie zanim padnie 429
pozostało = odpowiedź.nagłówki["X-RateLimit-Remaining"]
reset = odpowiedź.nagłówki["X-RateLimit-Reset"] # epoch, sekundy
jeśli pozostało < 30:
czekaj((reset − teraz()) / max(pozostało, 1)) # rozłóż resztę okna równoWymagany nagłówek User-Agent#
Każde żądanie do /v1/* musi się przedstawić. Format:
User-Agent: NazwaAplikacji/Wersja (+https://adres-dokumentacji-aplikacji)- NazwaAplikacji — jak w panelu; spacje zamień na
-lub_. Znaki dozwolone:[A-Za-z0-9._-], do 64. - Wersja — do 32 znaków
[A-Za-z0-9._-]. Zmieniaj ją przy wydaniach; to jedyna część, która ma się zmieniać. - (+adres) — link do strony opisującej aplikację (ten sam, co „Link do dokumentacji” w panelu). Formalnie opcjonalny, praktycznie niezbędny: po nim znajdujemy właściciela ruchu w logach.
Bramka sprawdza wyrażenie ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}/[A-Za-z0-9][A-Za-z0-9._-]{0,31}. Brak dopasowania → 400 missing_user_agent, zanim jeszcze sprawdzimy token. Domyślne nagłówki bibliotek (python-requests/2.31, axios/1.7) formalnie przechodzą, ale nie identyfikują Twojej aplikacji — przy problemach nie umiemy się z Tobą skontaktować, a przy nadużyciach blokujemy aplikację, nie IP, więc identyfikacja leży w Twoim interesie.
Generator i walidator#
Generator
Walidator
- ✓ Format poprawny — bramka przyjmie żądanie.
Jak być dobrym klientem HTTP#
- Keep-alive. Przy setkach żądań utrzymuj połączenie (HTTP/1.1 keep-alive lub HTTP/2) — uścisk TLS przy każdym żądaniu kosztuje więcej niż samo żądanie.
- Strony po 200.
limit=200zamiast domyślnych 50 to cztery razy mniej żądań na pełną synchronizację. - Tylko potrzebne pola.
?fields=id,price,stock,updated_atprzy synchronizacji cen i stanów. Mniej bajtów po obu stronach. - Przyrostowo.
updated_after(oferty) iplaced_after(zamówienia) zamiast pełnego przebiegu. Zapamiętuj znacznik z poprzedniego przebiegu z marginesem kilku sekund. - Webhooki zamiast odpytywania. Odpytywanie
GET /v1/ordersco minutę zużywa 1 440 żądań dziennie na nic. Webhookorder.paidprzychodzi wtedy, gdy jest co pobrać. - Idempotency-Key na każdym zapisie. Wtedy ponowienie po timeoucie jest bezpieczne, a przesyłka nie zgłosi się dwa razy.
- Własny X-Request-Id. Odbijamy go w
X-Trace-Id— jeden identyfikator w Twoich i naszych logach. - Zegar w UTC. Wszystkie daty w API są ISO 8601 w UTC (
Z). Porównuj instanty, nie łańcuchy.
Potrzebujesz więcej#
Limit jest parametrem aplikacji i możemy go podnieść. Napisz na api@premiumsupply.pl z client_id, opisem przepływu (co, jak często, dla ilu sprzedawców) i szczytową liczbą żądań na minutę, jakiej potrzebujesz. Zanim poprosisz, sprawdź, czy fields, updated_after i webhooki nie rozwiązują sprawy — zwykle tak.