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

  1. 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.
  2. 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".
  3. 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ść retryAfter dla 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ą current i limits, 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-Limit dotyczy 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

Aktualizacja: 30 września 2026