Limity żądań
Każde żądanie FourA API przechodzi trzy weryfikacje, zanim dotrze do silnika: limity Twojego planu, współdzieloną pulę platformy dla wywołanego endpointu oraz globalną współdzieloną pulę platformy dla całego ruchu. Każda weryfikacja może samodzielnie odrzucić żądanie i każda zwraca inne body.
Trzy weryfikacje, po kolei
- Limity planu. Na co pozwala Twój plan: jakie endpointy i parametry obejmuje, ile żądań może być przetwarzanych jednocześnie na endpoint, ile na minutę, ile żądań przeglądarkowych na dzień oraz dostępne punkty i transfer w okresie rozliczeniowym.
- Globalny limit platformy. Cały ruch obsługiwany w danej chwili przez wywołany host API, niezależnie od endpointu. Odrzucenie na tym etapie zwraca
"service": "api". - Limit platformy na endpoint. Ruch w wywołanej usłudze pojedynczej, proxy lub przeglądarkowej.
Twój plan jest weryfikowany jako pierwszy, a ta kolejność stanowi część kontraktu, a nie szczegół implementacyjny. Współdzielone pule są wspólne, więc żądanie, które i tak zostało by odrzucone, nie może ich zużywać. Konto wysyłające znacznie więcej, niż pozwala jego plan, jest blokowane, zanim dotknie zasobów współdzielonych z innymi.
Weryfikacje 2 i 3 zliczają całkowity ruch FourA, a nie Twój. Odrzucenie z którejkolwiek z nich oznacza "FourA jest zajęte", a nie "wysłano zbyt wiele". Weryfikacja 1 dotyczy wyłącznie Twojego konta i nic innego na platformie na nią nie wpływa.
Odrzucenie przez którąkolwiek ze współdzielonych weryfikacji zwraca Twojemu kontu wszystko, co zostało pobrane przy przyjęciu żądania, zarówno limit na minutę, jak i dzienny slot przeglądarkowy, ponieważ żądanie nigdy nie dotarło do backendu. Nie wlicza się to również do pauzy ponawiania opisanej w Żądania na minutę: odrzuciła je przepustowość FourA, a nie Twój plan.
POST /api/auto/ nie zajmuje własnego slotu. Podrzędne wywołania Single, Proxy i Browser wykonywane w Twoim imieniu przechodzą wszystkie trzy weryfikacje jak każde inne żądanie, więc równoległa pula wywołań auto obciąża Twój plan poprzez swoje podwywołania. (Liczba żądań i wskaźnik sukcesu zliczają samo wywołanie auto raz; podwywołania są widoczne jako jego próby).
Limity planu
Limit planu odpowiada nagłówkiem X-FourA-Limit wskazującym, który limit odrzucił wywołanie. Ten sam kod znajduje się w body w polu reason, co pozwala na warunkową obsługę bez odczytywania nagłówków. Każde body błędu limitu planu zawiera error, reason oraz documentation; pozostałe pola zależą od danego limitu.
X-FourA-Limit |
Status | Co zostało wyczerpane |
|---|---|---|
plan_limit_feature |
403 | Wywołany endpoint lub parametr exitCountries nie jest objęty Twoim planem |
plan_limit_premium |
403 | exitClass: premium nie jest objęty Twoim planem |
plan_limit_concurrency |
429 | Równoczesne requesty do tego endpointu |
plan_limit_rate |
429 | Requesty na minutę do tego endpointu |
plan_limit_browser_daily |
429 | Requesty przeglądarkowe w danym dniu |
plan_limit_credits |
429 | Płatne kredyty w danym okresie rozliczeniowym |
plan_limit_bandwidth |
429 | Transfer w danym okresie rozliczeniowym |
Wartości dla poszczególnych limitów wynikają z Twojego planu, a zakładka Limits & Features w Usage & Limits wyświetla je obok aktualnego zużycia. Nie wpisuj ich na stałe w kodzie: każda odmowa zawiera limit, który ją wywołał.
Odrzucony request nie zużywa środków. Wynikiem jest rate_limit, a naliczany jest tylko status success.
Endpoint lub parametr nieobjęty planem
Błąd 403 z kodem plan_limit_feature oznacza, że wywołanie dotyczyło zasobu niedostępnego w planie. Weryfikacja następuje przed jakimkolwiek naliczeniem, więc odrzucone wywołanie nie wpływa na liczniki rate limit ani dzienne.
{
"error": "The browser endpoint is not included in your plan (Free). Upgrade to use it.",
"reason": "plan_limit_feature",
"documentation": "https://foura.ai/prices"
}
Ten sam kod i status zwraca wywołanie POST /api/proxy/, które ustawia exitCountries w planie bez targetowania geograficznego. Ciąg error wskazuje parametr:
{
"error": "Geo targeting (the exitCountries parameter) is not included in your plan (Free). Remove the parameter or upgrade.",
"reason": "plan_limit_feature",
"documentation": "https://foura.ai/prices"
}
plan_limit_premium ma taką samą strukturę dla exitClass: premium w planie bez wyjść premium. FourA może zamiast tego obsłużyć taki request ze standardowej puli i zwrócić exitClass: standard w response, więc obsłuż obie odpowiedzi. Żadna z nich nie zużywa wyjścia premium. Zobacz exitClass.
Żaden błąd 403 nie ustawia Retry-After. Czekanie nie zmieni odpowiedzi.
Jednoczesne requesty
Współbieżność jest liczona per endpoint: Twój plan ma osobny limit dla Single, osobny dla Proxy i osobny dla Browser. Request przekraczający limit wraca z kodem 429 i Retry-After: 1:
{
"error": "Concurrency limit reached: your plan allows 50 simultaneous proxy request(s). Retry when an in-flight request finishes.",
"reason": "plan_limit_concurrency",
"documentation": "https://foura.ai/prices",
"limit": 50,
"in_flight": 51,
"retry_after_seconds": 1
}
in_flight zlicza również odrzucony request, więc odczytuje co najmniej o jeden więcej niż limit.
Rozwiązaniem jest ograniczenie własnego zrównoleglenia zamiast ponawiania prób z większą częstotliwością. Odpowiedź na 429 poprzez natychmiastowe ponowne wysłanie tego samego batcha generuje kolejny błąd 429 dla każdego wywołania w pakiecie. Zobacz Run Requests in Parallel, aby poznać gotowy wzorzec.
Requests per minute
Single i Proxy mają limit na minutę, mierzony w ramach przesuwnego okna minuty. Wliczają się do niego tylko zaakceptowane requesty: odrzucony request jest wycofywany, więc konto wysyłające stale nieco więcej niż jego limit otrzymuje pełną dozwoloną pulę, zamiast spotkać się z odrzuceniem niemal wszystkiego.
{
"error": "Rate limit reached: your plan allows 600 single requests per minute. Cool down and retry.",
"reason": "plan_limit_rate",
"documentation": "https://foura.ai/prices",
"limit_per_minute": 600,
"current_rate": 613,
"retry_after_seconds": 17
}
retry_after_seconds określa czas oczekiwania na dopuszczenie kolejnego requestu, jeśli w tym czasie nie wyślesz nic innego: co najmniej 1 sekunda i maksymalnie 120 sekund. Nagłówek Retry-After zawiera tę samą wartość.
Ponawianie odrzuconych requestów szybciej niż ten czas podlega osobnemu limitowi. Gdy liczba requestów odrzuconych w ruchomym oknie minuty przekroczy dwukrotność przyznanego limitu, wywołanie zostanie odrzucone z wymuszonym 30-sekundowym wstrzymaniem:
{
"error": "Rate limit cooldown: 1250 requests over your plan's 600 single requests per minute were refused in the last minute and kept arriving. Pause for 30 seconds.",
"reason": "plan_limit_rate",
"documentation": "https://foura.ai/prices",
"limit_per_minute": 600,
"current_rate": 540,
"refused_last_minute": 1250,
"cooldown": true,
"retry_after_seconds": 30
}
Odrzucenia podczas pauzy nie są zliczane, więc pauza kończy się samoczynnie wraz z upływem minuty, nawet w przypadku klienta, który stale ponawia próby. Aby odróżnić pauzę od zwykłego limitu, odczytaj cooldown zamiast tekstu error.
Browser requests per day
Browser nie ma limitu minutowego. Limit w planie to liczba browser requests na dzień, liczona od północy UTC, a licznik uwzględnia każde przyjęte żądanie browser request, nie tylko te zakończone sukcesem.
{
"error": "Daily browser limit reached: your plan allows 300 browser requests per day (resets at midnight UTC).",
"reason": "plan_limit_browser_daily",
"documentation": "https://foura.ai/prices",
"limit_per_day": 300,
"used_today": 301
}
Ta odmowa nie zawiera nagłówka retry_after_seconds ani Retry-After, ponieważ czas oczekiwania wynosi godziny, a nie sekundy. Potraktuj to jako sygnał stopu i zaplanuj kolejne uruchomienie na północ UTC.
Kredyty w okresie rozliczeniowym
Liczą się tylko rozliczone kredyty, czyli wyłącznie udane żądania. Gdy suma rozliczeń osiągnie limit kredytów dostępnych w tym okresie, kolejne żądania będą odrzucane do momentu resetu okresu lub zakupu dodatkowych kredytów.
{
"error": "Credit limit reached: 75,000 of 75,000 credits used this billing period. Upgrade your plan or wait for the reset.",
"reason": "plan_limit_credits",
"documentation": "https://foura.ai/prices",
"used": 75000,
"hard_stop": 75000,
"retry_after_seconds": 86400,
"resets_at": "2026-10-01T00:00:00.000Z"
}
hard_stop to liczba rozliczonych kredytów, po osiągnięciu której żądania w tym okresie zostają wstrzymane. Odczytuj ją z treści odpowiedzi zamiast obliczać samodzielnie: zawiera już wszystkie kredyty dokupione poza planem.
Przepustowość w okresie rozliczeniowym
Plany z limitem przepustowości odrzucają żądania, gdy standardowy ruch w danym okresie osiągnie ten limit. Ruch premium ma własny limit i nie wlicza się do tego ograniczenia. Dokupiona przepustowość jest traktowana tak samo jak ta zawarta w planie, a ciąg error podaje łączną dostępną wartość, a nie tylko to, co zawiera sam plan.
{
"error": "Bandwidth limit reached: 50 GB is available to you this billing period.",
"reason": "plan_limit_bandwidth",
"documentation": "https://foura.ai/prices",
"used_bytes": 53687091200,
"limit_bytes": 53687091200,
"retry_after_seconds": 86400,
"resets_at": "2026-10-01T00:00:00.000Z"
}
W przypadku obu limitów okresowych retry_after_seconds jest ograniczony do 24 godzin; resets_at to dokładny moment odnowienia okresu.
Pola limitów planu
| Pole | Typ | Obecne w | Opis |
|---|---|---|---|
error |
string | wszystkie | Czytelny dla człowieka komunikat, zawierający obowiązujący limit |
reason |
string | wszystkie | plan_limit_ oraz nazwa limitu. Taka sama wartość jak w nagłówku X-FourA-Limit. |
documentation |
string | wszystkie | Link do strony z planami |
retry_after_seconds |
number | współbieżność, rate, kredyty, transfer | Czas oczekiwania. Taka sama wartość jak w nagłówku Retry-After. |
limit |
number | współbieżność | Liczba jednoczesnych requestów dozwolona przez plan dla danego endpointu |
in_flight |
number | współbieżność | Requesty aktualnie przetwarzane dla Twojego konta na tym endpoincie, wliczając odrzucony |
limit_per_minute |
number | rate | Requesty na minutę dozwolone przez plan dla danego endpointu |
current_rate |
number | rate | Requesty zliczone w ruchomej minucie, wliczając odrzucony |
refused_last_minute |
number | pauza rate | Requesty odrzucone przez limit minutowy w ruchomej minucie. Tylko przy 30-sekundowej pauzie. |
cooldown |
boolean | pauza rate | true przy 30-sekundowej pauzie za zbyt szybkie ponawianie. Nieobecne przy zwykłym odrzuceniu minutowym. |
limit_per_day |
number | przeglądarka dziennie | Requesty przeglądarkowe dozwolone przez plan na dzień |
used_today |
number | przeglądarka dziennie | Requesty przeglądarkowe zliczone dzisiaj, wliczając odrzucony |
used |
number | kredyty | Kredyty naliczone dotychczas w tym okresie |
hard_stop |
number | kredyty | Poziom naliczonych kredytów, przy którym requesty są wstrzymywane w tym okresie |
used_bytes |
number | transfer | Standardowy ruch w tym okresie, w bajtach. Ruch premium nie jest wliczany. |
limit_bytes |
number | transfer | Bajty dostępne w tym okresie |
resets_at |
string | kredyty, transfer | Znacznik czasu ISO 8601 końca okresu |
Limity planu używają retry_after_seconds. Poniższe limity platformy używają retryAfter. Mechanizm ponawiania (retry helper) musi odczytywać oba lub czytać nagłówek Retry-After, który jest ustawiany tylko przez limity planu.
Limity platformy
Weryfikacja platformy monitoruje dwie wartości dla każdej usługi i jedną wspólną dla wszystkich:
- Współbieżność: ile requestów FourA przetwarza jednocześnie.
- RPM: ile requestów FourA przyjął w ciągu ostatnich 60 sekund.
Oba liczniki są współdzielone przez wszystkich użytkowników danej usługi. Wartości current i limits w poniższych odpowiedziach opisują platformę, a nie Twoje konto. Jeśli chcesz sprawdzić własne limity, odczytaj in_flight z odpowiedzi limitu planu lub otwórz Usage & Limits w panelu.
429: Przekroczono limit RPM
{
"error": "Rate limit exceeded",
"status": 429,
"service": "single",
"retryAfter": 5,
"current": {
"concurrency": 12,
"rpm": 3000
},
"limits": {
"maxConcurrency": 500,
"maxRpm": 3000
}
}
Usługa wykorzystała dozwoloną liczbę requestów w ostatniej minucie. Poczekaj retryAfter s.
503: Przekroczono limit współbieżności
{
"error": "Service at capacity",
"status": 503,
"service": "proxy",
"retryAfter": 2,
"current": {
"concurrency": 500,
"rpm": 1200
},
"limits": {
"maxConcurrency": 500,
"maxRpm": 3000
}
}
Usługa przetwarza obecnie maksymalną dozwoloną liczbę równoczesnych żądań. Sytuacja ustępuje w ciągu kilku sekund.
Usługa wyłączona
Gdy usługa jest tymczasowo wyłączona z powodu prac konserwacyjnych, API zwraca kod 503 z innym komunikatem błędu:
{
"error": "Service disabled",
"status": 503,
"service": "single",
"retryAfter": 60,
"current": { "concurrency": 0, "rpm": 0 },
"limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}
To nie jest rate limit. Usługa jest tymczasowo niedostępna. Sprawdź wartość retryAfter i ponów próbę po tylu sekundach. Zazwyczaj ustępuje to w ciągu kilku minut.
Oba warianty 503 zawierają te same klucze, więc rozgałęziaj logikę na podstawie ciągu error, a nigdy na podstawie obecności konkretnych pól. Service disabled oznacza przerwę techniczną, a Service at capacity współbieżność.
W wariancie przerwy technicznej current.concurrency i current.rpm zawsze mają wartość 0: request został odrzucony przed dokonaniem jakichkolwiek pomiarów.
Platform Limit Fields
| Field | Type | Description |
|---|---|---|
error |
string | Czytelny dla człowieka komunikat o błędzie |
status |
number | Kod statusu HTTP (429 lub 503) |
service |
string | Która usługa odrzuciła wywołanie: single, proxy, browser lub api |
retryAfter |
number | Zalecany czas oczekiwania w sekundach przed ponowieniem próby |
current.concurrency |
number | Liczba requestów przetwarzanych w całej platformie w momencie odrzucenia |
current.rpm |
number | Liczba requestów przyjętych w całej platformie w ciągu ostatnich 60 sekund |
limits.maxConcurrency |
number | Limit współbieżności usługi w całej platformie |
limits.maxRpm |
number | Limit minutowy usługi w całej platformie |
Obsługa każdego odrzucenia za pomocą jednej funkcji pomocniczej
Retry-After jest ustawiany przy limitach planu, na które warto poczekać, retry_after_seconds znajduje się w ich treściach, a retryAfter w treściach platformy. Odczytuj wszystkie trzy w tej kolejności i zatrzymuj się przy limitach planu, których żadne czekanie nie rozwiąże:
import time
import requests
# Plan limits that a short wait never clears.
STOP_ON = {
"plan_limit_feature",
"plan_limit_premium",
"plan_limit_browser_daily",
"plan_limit_credits",
"plan_limit_bandwidth",
}
def wait_seconds(resp, attempt):
header = resp.headers.get("Retry-After")
if header and header.isdigit():
return int(header)
try:
body = resp.json()
except ValueError:
return 2 ** attempt
return body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** attempt
def fetch(url, api_key, max_retries=5):
for attempt in range(max_retries):
resp = requests.post(
"https://eu.api.foura.ai/api/single/",
headers={"X-API-Key": api_key, "Content-Type": "application/json"},
json={"method": "GET", "url": url},
)
limit = resp.headers.get("X-FourA-Limit")
if limit in STOP_ON:
raise RuntimeError(f"stopped by plan limit {limit}: {resp.json().get('error')}")
if resp.status_code in (429, 503):
time.sleep(wait_seconds(resp, attempt))
continue
return resp
raise RuntimeError("Max retries exceeded")
Dzienny limit nie odnawia się przez godziny, a limit okresowy przez dni, więc traktuj je jako sygnał do zatrzymania, a nie do czekania. Odczytaj resets_at z treści odpowiedzi, jeśli chcesz zaplanować kolejne uruchomienie.
Wskazówki
- Ogranicz liczbę równoległych żądań w toku zamiast ponawiać całą odrzuconą serię. Burza ponowień zamienia jedno 429 w wiele kolejnych.
- Najpierw sprawdzaj
X-FourA-Limit. W jednym ciągu znaków informuje, czy limit dotyczy Twojego konta, czy platformy, a żadne odrzucenie ze strony platformy go nie ustawia. - Nie wpisuj wartości na stałe w kodzie. Każda odpowiedź o przekroczeniu limitu planu zawiera wartość progową, która spowodowała odrzucenie, a sekcja Usage & Limits pokazuje je wszystkie.
- Wartość
retryAfterdla limitów platformy jest stała w zależności od typu: 2 sekundy dla współbieżności, 5 dla RPM, 60 dla prac konserwacyjnych. - Dopasowuj po
error, aby rozróżnić oba przypadki 503. Obie struktury zawierającurrentilimits, więc samo sprawdzenie obecności tych pól zinterpretuje przerwę techniczną jako problem ze współbieżnością. - Błąd 403 z kodem
X-FourA-Limitdotyczy Twojego planu, a nie strony docelowej. Strona docelowa w ogóle nie odpowiedziała.
Port proxy ma własne limity
Wszystko powyżej odnosi się do API JSON. Ruch przesyłany przez proxy.foura.ai podlega osobnemu zestawowi limitów planu w innych jednostkach: jednocześnie otwarte tunele, liczba otwarć tuneli na minutę oraz standardowy transfer w okresie rozliczeniowym. Odrzucenia te są zwracane jako status HTTP z nagłówkiem X-Foura-Error zamiast treści JSON, ponieważ CONNECT nie zawiera treści odpowiedzi. Zobacz Proxy Port, aby sprawdzić tabelę statusów, oraz How Your Plan Is Metered, aby dowiedzieć się, z której puli pobierane są gigabajty dla portu.
Powiązane
- Run Requests in Parallel: Gotowy wzorzec ograniczonej współbieżności
- Usage & Limits: Wszystkie limity planu zestawione z bieżącym zużyciem
- API Endpoints: Pełna dokumentacja parametrów
- Error Handling: Wszystkie typy błędów i odpowiedzi
- Response Headers:
X-FourA-Limit,Retry-Afteri pozostałe - Troubleshooting: Typowe problemy i rozwiązania