Dokumentacja punktów końcowych API
Dokumentacja referencyjna wszystkich endpointów FourA API z parametrami requestów i formatami response.
Base URL
https://eu.api.foura.ai/api
Uwierzytelnianie
Każde żądanie wymaga Twojego klucza API w nagłówku X-API-Key:
curl -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"method": "GET", "url": "https://example.com"}'
Twórz klucze API i zarządzaj nimi w Dashboardzie. Klucze używają prefiksu pk_live_.
Response Headers
Odpowiedzi z /api/* zawierają dwa nagłówki korelacji:
| Header | Value | Description |
|---|---|---|
X-FourA-Request-Id |
UUID | Unikalny identyfikator przypisany do żądania. Zwracany przy każdej odpowiedzi, w tym 4xx i 5xx, z wyjątkiem treści, których FourA nie może w ogóle odczytać: 400 Invalid JSON in request body i 413 są odrzucane przed przypisaniem identyfikatora. Zapisuj go w logach po swojej stronie. |
X-FourA-Credits |
integer | Kredyty zużyte na to żądanie. Zwracane przy każdej odpowiedzi, która dotarła do silnika, bez względu na sukces czy błąd (praca została wykonana w obu przypadkach). Wywołanie odrzucone przez FourA przed uruchomieniem silnika (brakujący lub nieprawidłowy klucz, limit planu lub platformy, odrzucony cel lub identyfikator proxy) nie zawiera tego nagłówka. Zobacz Request Outcomes, aby sprawdzić, które wyniki są rozliczane. |
Ten sam identyfikator żądania służy jako klucz do podglądu payloadu żądania i odpowiedzi w Activity Log w Dashboardzie (przechowywane przez 24 godziny, ostatnie 200 na klucz), dzięki czemu możesz sprawdzić dokładne żądanie później i odtworzyć je z Activity bezpośrednio w Playgroundzie. Dołącz go podczas kontaktu z pomocą techniczną, a pozwoli on zlokalizować żądanie w kilka sekund.
$ curl -i -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"method": "GET", "url": "https://example.com"}'
HTTP/2 200
content-type: application/json
x-foura-request-id: 8f3e2a14-7b6c-4d1a-9e2f-5a3b8c1d4e7f
x-foura-credits: 2
...
Zobacz Response Headers, aby sprawdzić pełną listę i wskazówki dotyczące użycia.
Endpoints
Używasz tych endpointów przez MCP? Serwer
@fouradata/mcpudostępnia wszystkie cztery endpointy jako natywne narzędzia MCP (foura_auto,foura_single,foura_proxy,foura_browser) z takimi samymi formatami danych wejściowych oraz opcjonalną obsługąoffload_largezoptymalizowaną pod kątem tokenów przy dużych odpowiedziach.
FourA oferuje cztery endpointy request, każdy zoptymalizowany pod kątem innego scenariusza:
| Endpoint | Najlepszy do |
|---|---|
POST /auto/ |
Inteligentne pobieranie. Przekazujesz URL, FourA wybiera najtańszą działającą ścieżkę (bezpośrednią, rotowane proxy lub przeglądarkę) i zapamiętuje skuteczne metody dla danego hosta. |
POST /single/ |
Szybkie żądania HTTP, strony statyczne, API |
POST /proxy/ |
Zabezpieczone witryny z automatyczną rotacją proxy, opcjonalne targetowanie na określony kraj widoczny dla celu |
POST /browser/ |
Strony renderowane przez JavaScript, SPA |
GET /profiles |
Katalog profili przeglądarek dla single i proxy. Publiczny, nie wymaga klucza API. |
Szczegółowe omówienie wyboru odpowiedniego rozwiązania znajdziesz w dokumentacji Choosing the Right Endpoint oraz w przewodniku Smart Fetch guide.
Ograniczenia docelowych URL
Cele, które wskazują na prywatne, pętli zwrotnej (loopback) lub zarezerwowane zakresy IP (RFC 5735, RFC 6598, zarezerwowane bloki IPv6), są odrzucane z kodem 400, zanim żądanie opuści FourA. Przekazywane są wyłącznie publiczne nazwy hostów i adresy IP.
{ "error": "Refusing to fetch <target>: target resolves to a private or reserved IP range. The FourA scraping API only forwards requests to public internet hosts." }
Smart Fetch (Auto)
POST /api/auto/
Przekazujesz URL oraz opcjonalne reguły validate. FourA przechodzi przez zoptymalizowaną pod kątem kosztów drabinkę (tania próba bezpośrednia, rotowane proxy, pełna przeglądarka) i zatrzymuje się na pierwszym szczeblu, który zwróci response zaakceptowany przez Twoje reguły. Przy kolejnych wywołaniach do tego samego hosta odtwarzana jest rozgrzana sesja, dzięki czemu drugie zapytanie jest tanie.
Nie musisz konfigurować ponowień, rozmiarów puli ani liczby proxy. FourA uczy się ich dla każdego hosta.
Request Body
| Parametr | Typ | Wymagany | Domyślnie | Opis |
|---|---|---|---|---|
url |
string | Tak | - | Docelowy URL |
method |
string | Nie | "GET" |
Metoda HTTP |
headers |
[string, string][] | Nie | - | Niestandardowe headers jako pary [nazwa, wartość] |
data |
any | Nie | - | Request body dla zapytań innych niż GET |
validate |
object | Nie | - | Kryteria sukcesu, w takim samym formacie jak validate w Single Request (zobacz poniżej). Zdefiniuj, jak wygląda poprawna strona, aby tryb auto mógł odróżnić właściwą treść od strony z wyzwaniem (challenge). |
returnSession |
boolean | Nie | true |
Dołącz udaną sesję (proxy, cookies, userAgent) do response, aby umożliwić jej odtworzenie przez /api/single/ lub /api/browser/. |
forceProxy |
boolean | Nie | true |
Zawsze kieruj ruch przez rotowane proxy. Ustaw false, aby zezwolić na tańszą ścieżkę bezpośrednią, jeśli cel na to pozwala (niektóre mechanizmy obronne są bardziej rygorystyczne wobec ruchu z proxy). |
timeout_ms |
integer | Nie | 120000 |
Całkowity budżet czasu na całe wywołanie w milisekundach. Wszystkie próby cząstkowe są wykonywane w ramach tego budżetu. Min 5000, max 180000. |
ignoreProxies |
string[] | Nie | - | Identyfikatory proxy do pominięcia przy każdej próbie cząstkowej. Użyj identyfikatorów zwróconych przez wcześniejsze response z /api/auto/ lub /api/proxy/. |
followRedirects |
integer | Nie | 5 |
Maksymalna liczba przekierowań do obsłużenia na niższych szczeblach drabinki. 0, aby wyłączyć. Max 20. |
Response
{
"status": 200,
"data": "<!doctype html>...",
"headers": [{"content-type": "text/html"}],
"meta": {
"rung": "cache",
"solved": false,
"attempts": 1,
"credits": 2
},
"session": {
"proxy": "A1B2C3",
"cookies": [{"name": "session", "value": "abc", "domain": "example.com"}],
"userAgent": "Mozilla/5.0..."
}
}
| Pole | Typ | Opis |
|---|---|---|
status |
number | Kod statusu HTTP z celu. |
data |
string | Ciało odpowiedzi jako tekst, niezależnie od poziomu, który je obsłużył. Strona JSON jest zwracana jako tekst JSON, więc należy ją sparsować samodzielnie. |
headers |
array lub object | Nagłówki odpowiedzi celu. Poziomy pojedyncze i proxy zwracają tablicę obiektów nagłówków per-hop; poziomy przeglądarkowe zwracają płaski obiekt. |
meta.rung |
string | Poziom drabiny, który dostarczył odpowiedź. Jeden z: probe (tanie zapytanie bezpośrednie), proxy (rotujące proxy), browser (pełny render w przeglądarce), cache (odtworzona rozgrzana sesja), warmup (najpierw pobrano stronę główną witryny, a jej pliki cookie otworzyły głęboki adres URL) lub fail (żaden poziom nie wygenerował zaakceptowanej odpowiedzi). |
meta.solved |
boolean | Informacja, czy strona wymagała dodatkowego kroku (strony wyzwania) i został on ukończony podczas tego wywołania. |
meta.attempts |
number | Liczba prób podrzędnych wykonanych przed sukcesem. |
meta.credits |
number | Łączna liczba kredytów wykorzystanych na to wywołanie. Zgodna z X-FourA-Credits. |
session.proxy |
string | Zakodowany identyfikator proxy, które dostarczyło odpowiedź. Można go użyć ponownie w żądaniu Single lub Browser. Obecny, gdy returnSession ma wartość true. |
session.cookies |
array | Pliki cookie ze zwycięskiej próby. Obecne, gdy returnSession ma wartość true. |
session.userAgent |
string | Nagłówek User-Agent użyty w zwycięskiej próbie. Obecny, gdy returnSession ma wartość true. |
error |
string | Komunikat błędu, jeśli wywołanie nie powiodło się. |
Przykład
curl -X POST https://eu.api.foura.ai/api/auto/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product/42",
"validate": {"data": {"accept": ["Add to cart"]}}
}'
Uwagi
- Auto działa jako koordynator. Wywołuje wewnętrznie Single, Proxy lub Browser i przekazuje Twój klucz API do każdego podwywołania. Wywołanie Auto to jedno żądanie w Activity Log i na stronie Overview, z sumą kredytów jego podwywołań; podwywołania są wymienione pod nim jako próby i nigdy nie liczą się jako osobne żądania.
- Przekaż
validate.data.acceptz podciągiem znaków, który zawiera tylko właściwa strona. Bez tego tryb auto nie odróżni prawdziwego statusu 200 od strony z wyzwaniem zwróconej ze statusem 200. timeout_msogranicza czas trwania całego wywołania. Pierwsze wywołanie na zimno do chronionej witryny może zająć kilkadziesiąt sekund; ponownie używane, rozgrzane sesje kończą się zwykle w czasie poniżej sekundy.
Single Request
POST /api/single/
Wysyła żądanie HTTP z realistyczną charakterystyką sieciową przeglądarki, bez uruchamiania rzeczywistej przeglądarki. Jest to najszybszy endpoint.
Request Body
| Parametr | Typ | Wymagany | Domyślnie | Opis |
|---|---|---|---|---|
method |
string | Tak | - | Metoda HTTP: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
url |
string | Tak | - | Docelowy URL. Użyj {ts} w dowolnym miejscu adresu URL, aby wstawić bieżący znacznik czasu do ominięcia pamięci podręcznej. |
headers |
[string, string][] | Nie | - | Niestandardowe nagłówki jako pary [nazwa, wartość] |
unblocker |
boolean | Nie | true |
Wysyłaj realistyczne nagłówki przeglądarki (User-Agent, Sec-Ch-Ua, Sec-Fetch-*, Accept-Encoding). Domyślnie włączone. Ustaw false, aby wysłać czystą sygnaturę klienta. |
timeout_ms |
number | Nie | 15000 | Całkowity limit czasu w ms (maksymalnie: 120000) |
connect_timeout_ms |
number | Nie | 5000 | Limit czasu połączenia w ms |
accept_timeout_ms |
number | Nie | 5000 | Limit czasu akceptacji w ms (czas oczekiwania na zaakceptowanie połączenia) |
server_response_timeout_ms |
number | Nie | 15000 | Limit czasu odpowiedzi serwera w ms (czas oczekiwania na pierwszy bajt) |
dns_cache_timeout_sec |
number | Nie | 120 | TTL pamięci podręcznej DNS w sekundach (maksymalnie: 240) |
followRedirects |
number | Nie | wyłączone | Maksymalna liczba przekierowań do wykonania (0-20). Pomiń, aby wyłączyć. |
tryJsonData |
boolean | Nie | false | Przetwarzaj treść odpowiedzi jako JSON, jeśli to możliwe |
returnBuffer |
boolean | Nie | false | Zwracaj surowy bufor zamiast zdekodowanego ciągu znaków |
data |
any | Nie | - | Treść żądania (ciąg znaków lub obiekt, automatycznie serializowany do JSON) |
proxy |
string | Nie | - | Identyfikator proxy z wcześniejszej odpowiedzi, aby przypiąć ten sam punkt wyjścia. Przekaż nieprzetworzony ciąg znaków z powrotem bez zmian. Surowy adres proxy jest odrzucany z kodem 400 Invalid proxy format. Niektóre identyfikatory nie mogą być przypięte: zobacz Pinning an exit. |
browser |
string | Nie | Chrome | Prezentowana przeglądarka: Chrome, Edge, Safari, Firefox lub Tor. Zobacz Browser profiles. |
os |
string | Nie | - | Prezentowany system operacyjny: Windows, macOS, Android lub iOS. Nazwa rodziny akceptuje dowolną z jej wersji. |
version |
string | Nie | newest | Prezentowana wersja przeglądarki, zgodnie z katalogiem. W przypadku kilku pasujących wybierana jest najnowsza. |
profile |
string | Nie | - | Dokładny identyfikator profilu z GET /api/profiles, zamiast powyższych trzech pól. |
validate |
object | Nie | - | Reguły walidacji odpowiedzi (zobacz poniżej) |
Profile przeglądarek
Domyślnie żądanie przedstawia się jako najnowszy Google Chrome. Niektóre cele akceptują jedną przeglądarkę, a odrzucają inną, dlatego browser, os i version zawężają katalog zmierzonych profili, a profile wybiera profil na podstawie identyfikatora.
{
"method": "GET",
"url": "https://example.com",
"browser": "Firefox",
"os": "Windows"
}
Zasady:
- Wybór wymaga
unblocker(domyślnie włączone). Gdyunblockerjest wyłączone, nagłówki przeglądarki nie są wysyłane, więc request zostaje odrzucony, zamiast być częściowo zaaplikowany. - Gdy pasuje kilka profili, wygrywa najnowsza wersja.
- Kombinacja, której katalog nie może zaoferować, zwraca błąd wskazujący dostępne opcje. Request nigdy nie jest wysyłany jako inna przeglądarka.
- Te same cztery pola są dostępne w obiekcie
requestwPOST /proxy/.
GET /api/profiles zwraca pełny katalog i nie wymaga klucza API:
{
"profiles": [
{ "id": "...", "browser": "Chrome", "version": "...", "os": "...", "osFamily": "macOS" }
],
"default": "..."
}
osFamily to wartość używana do filtrowania podczas tworzenia selektora; os zachowuje nazwę wydania do wyświetlenia.
Reguły walidacji
Obiekt validate pozwala zdefiniować warunki sukcesu i niepowodzenia. Jeśli warunek fail zostanie spełniony, żądanie jest traktowane jako nieudane. Jeśli ustawione są warunki accept, tylko pasujące odpowiedzi są traktowane jako udane.
{
"validate": {
"status": { "accept": [200, 201], "fail": [403, 503] },
"headers": { "accept": {"content-type": "application/json"} },
"data": { "accept": ["product"], "fail": ["captcha", "blocked"] }
}
}
| Pole | Typ | Opis |
|---|---|---|
validate.status.accept |
number[] | Kody statusu HTTP do zaakceptowania |
validate.status.fail |
number[] | Kody statusu HTTP do odrzucenia |
validate.headers.accept |
object | Pary klucz-wartość nagłówków, które muszą być obecne |
validate.headers.fail |
object | Pary klucz-wartość nagłówków wywołujące błąd |
validate.data.accept |
string[] | Ciągi znaków, które muszą występować w treści response |
validate.data.fail |
string[] | Ciągi znaków w treści response wywołujące błąd |
Przykład
curl -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "GET",
"url": "https://example.com/products",
"timeout_ms": 10000
}'
Response:
{
"status": 200,
"headers": [{"result": {"version": "HTTP/2", "code": 200, "reason": ""}, "content-type": "text/html", "server": "...", "set-cookie": ["session=abc", "tracker=xyz"]}],
"data": "<!doctype html>...",
"total_time": 0.342,
"proxy": "A1B2C3"
}
Gdy cel uruchamia weryfikację bota przed zwróceniem treści, response zawiera również obiekt defense ze wskazaniem dostawcy oraz informacją, czy weryfikacja zakończyła się sukcesem:
{
"status": 200,
"data": "<!doctype html>...",
"total_time": 3.61,
"defense": {
"vendor": "sgcaptcha",
"solved": true,
"present": ["sgcaptcha"],
"ms": 3412,
"cookie": "_I_=<clearance>"
}
}
| Pole | Typ | Opis |
|---|---|---|
status |
number | Kod statusu HTTP z celu |
headers |
array | Jeden obiekt na każdy przeskok przekierowania. Każdy zawiera pole result z linią statusu oraz wszystkimi nagłówkami odpowiedzi. Nagłówki wielowartościowe (Set-Cookie, Link, WWW-Authenticate) są zwracane jako tablice ciągów znaków. |
data |
string/object | Treść odpowiedzi (JSON, jeśli tryJsonData ma wartość true) |
total_time |
number | Całkowity czas żądania w sekundach |
proxy |
string | Zakodowany identyfikator proxy, przez który przeszło żądanie (tylko wtedy, gdy w żądaniu podano proxy). Użyj go ponownie w kolejnym wywołaniu, aby przypiąć ten sam węzeł wyjściowy. |
defense |
object | Obecne, gdy cel przeprowadził weryfikację pod kątem botów dla tego żądania lub gdy ponowienie z własnymi plikami cookie witryny wygenerowało treść. Pole defense.solved określa, czy weryfikacja zakończyła się powodzeniem, a pole defense.retry określa, czy ponowienie przyniosło treść. Zobacz Site checks, aby sprawdzić wszystkie pola i pełną listę systemów. |
error |
string | Komunikat o błędzie, jeśli żądanie nie powiodło się |
Proxy Request
POST /api/proxy/
Kieruje Twoje żądanie przez rotacyjne proxy z automatycznym ponawianiem w przypadku błędu. Opcjonalnie ogranicza wybór do zestawu krajów wyjściowych widocznych dla celu.
Request Body
| Parametr | Typ | Wymagany | Domyślnie | Opis |
|---|---|---|---|---|
request |
object | Tak | - | Pojedyncza treść żądania (te same pola co w Single Request powyżej) |
timeout_ms |
number | Nie | 45000 | Całkowity limit czasu dla wszystkich prób w ms (maks.: 120000) |
maxTries |
number | Nie | 5 | Maksymalna liczba prób rotacji proxy (maks.: 90) |
ignoreProxies |
string[] | Nie | - | Identyfikatory proxy do wykluczenia z rotacji (użyj identyfikatorów zwróconych w poprzednich odpowiedziach) |
exitCountries |
string[] | Nie | - | Ścisła biała lista dwuliterowych kodów krajów widocznych dla celu (np. ["CZ", "GB"]). Wartości są przycinane, konwertowane na wielkie litery i deduplikowane. Proxy o nieznanych węzłach wyjściowych są wykluczane, a żądanie nigdy nie przełącza się awaryjnie na niezażądany kraj. |
exitClass |
string | Nie | - | standard lub premium. Opcja premium pozwala żądaniu na eskalację do węzła wyjściowego premium, gdy standardowa pula ma trudności z chronionym celem. Wymaga planu obejmującego węzły wyjściowe premium. |
Ograniczanie exitCountries
Wybór korzysta z najnowszych dostępnych metadanych kraju widocznego dla celu, zwykle odświeżanych w ciągu około dziesięciu minut. Nie jest to wyszukiwanie geolokalizacyjne na żywo podczas żądania. Nie należy wnioskować o kraju obsługującym na podstawie adresu hosta proxy.
Jeśli bieżąca pula nie zawiera dopasowania dla żądanych krajów, odpowiedź zwraca HTTP 200 z kopertą błędu:
{
"error": "No eligible proxy found for exit countries: CZ, GB",
"code": "no_eligible_proxy",
"details": { "exitCountries": ["CZ", "GB"] },
"total": 0.084
}
Zachowaj żądany zakres i ponów próbę później. Zmień lub rozszerz go tylko wtedy, gdy wymagania dotyczące kraju w Twoim przepływie pracy ulegną wyraźnej zmianie.
Przykład
curl -X POST https://eu.api.foura.ai/api/proxy/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"maxTries": 3,
"exitCountries": ["CZ", "GB"],
"request": {
"method": "GET",
"url": "https://example.com/prices"
}
}'
Odpowiedź:
{
"status": 200,
"headers": [{"result": {"code": 200}, "content-type": "text/html", "set-cookie": ["a=1", "b=2"]}],
"data": "<!doctype html>...",
"total_time": 1.204,
"proxy": "A1B2C3",
"exitCountry": "CZ",
"total": 2.341
}
| Pole | Typ | Opis |
|---|---|---|
proxy |
string | Zakodowany identyfikator użytego proxy. Użyj go ponownie w żądaniu Single lub Browser, przekazując go jako pole proxy, albo pomiń go w kolejnym żądaniu Proxy za pomocą ignoreProxies. |
exitCountry |
string | Dwuliterowy kod kraju proxy widoczny dla celu, który obsłużył żądanie. Obecny tylko wtedy, gdy w żądaniu ustawiono exitCountries. Zawsze sprawdź, czy jest to jeden z żądanych kodów, zanim zaufasz odpowiedzi. |
exitClass |
string | Klasa węzła wyjściowego, która obsłużyła to żądanie, obecna w udanej odpowiedzi, gdy w żądaniu wskazano klasę. premium oznacza, że treść zwrócił węzeł premium; standard oznacza, że pochodziła ona ze standardowej puli. Nieudane wywołanie niczego nie zwróciło, więc nie zawiera exitClass; sprawdź jego attemptReport, aby dowiedzieć się, co napotkały próby. |
total |
number | Całkowity czas trwania (wall-clock) w sekundach (float). Obejmuje wybór proxy, ponowne próby i udaną próbę. total_time dotyczy wyłącznie żądania wewnętrznego; total jest zawsze >= total_time. |
profile |
string | Profil przeglądarki wybrany przez rotację, obecny tylko wtedy, gdy nie był to profil wskazany w żądaniu. Brak pola oznacza, że żądanie wyszło dokładnie w podanej postaci. Przekaż identyfikator z powrotem jako profile w kolejnych wywołaniach, aby zachować działającą przeglądarkę. |
error |
string | Komunikat o błędzie w przypadku niepowodzenia żądania. W przypadku braku dopasowania zakresu (scope miss), code ma wartość no_eligible_proxy, a details.exitCountries powtarza znormalizowany zakres. |
attemptReport |
object | Obecny przy każdym nieudanym wywołaniu Proxy. Zlicza zdarzenia napotkane podczas prób, dzięki czemu zablokowana pula, martwa pula oraz reguła validate, która nigdy nie została dopasowana, nie wyglądają jak ten sam błąd. Zobacz poniżej. |
Uwzględniono także wszystkie pola odpowiedzi Single Request, w tym defense: próba proxy, która napotkała weryfikację botów, raportuje to w taki sam sposób jak Single.
Dlaczego wywołanie Proxy zakończyło się niepowodzeniem
Download maxTry limit reached ma taką samą postać niezależnie od przebiegu prób, dlatego każda nieudana odpowiedź Proxy zawiera attemptReport obok błędu:
{
"error": "Download maxTry limit reached",
"attemptReport": {
"total": 25,
"noResponse": 0,
"defense": 0,
"contentRejected": 25,
"statusRejected": 0,
"other": 0,
"vendors": [],
"profilesTried": ["default"],
"summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
},
"total": 34.812
}
| Pole | Typ | Opis |
|---|---|---|
total |
integer | Liczba wykonanych prób |
noResponse |
integer | Węzeł wyjściowy (exit) nie odpowiedział, więc witryna nie została osiągnięta |
defense |
integer | Witryna odpowiedziała i w tej odpowiedzi wykryto weryfikację bota |
contentRejected |
integer | HTTP 200, brak weryfikacji bota, odrzucono wyłącznie przez Twoje validate.data |
statusRejected |
integer | Witryna odpowiedziała, brak weryfikacji bota, odrzucono przez Twoje validate.status |
other |
integer | Uzyskano odpowiedź i żaden z powyższych przypadków nie miał miejsca |
vendors |
string[] | Dostawcy systemów bot-check wykryci w dowolnym momencie zadania |
profilesTried |
string[] | Profile przeglądarki wysłane w zadaniu, w kolejności pierwszego użycia. default oznacza, że request został wysłany bez modyfikacji. |
summary |
string | Jedno zdanie wygenerowane na podstawie liczników, bezpieczne do logowania |
Ciąg znaków error pozostaje niezmieniony, więc klient dopasowujący do niego nadal działa. Co zrobić w przypadku każdej wartości licznika: Dlaczego wyczerpały się próby dla Proxy Request.
exitClass
Niektóre cele odrzucają węzły wyjściowe z puli standardowej niezależnie od liczby podjętych prób. exitClass: premium informuje Proxy, że może przekazać taki request do premium exit jako uzupełnienie puli standardowej, zamiast jedynie rotować w jej obrębie.
{
"exitClass": "premium",
"request": { "method": "GET", "url": "https://example.com/report" }
}
Trzy rzeczy warto wiedzieć przed jego wysłaniem.
To jest zezwolenie, a nie polecenie. Standardowa pula nadal rywalizuje o odpowiedź i zazwyczaj wygrywa. Wyjście premium dołącza tylko wtedy, gdy pula wyczerpie krótki budżet na request lub cel widocznie go odrzuci. Request, na który standardowa pula odpowie, zanim zostanie wypróbowane jakiekolwiek wyjście premium, stanowi normalny sukces i nie kosztuje ruchu premium. Po wypróbowaniu wyjścia premium jego ruch jest wliczany zgodnie z poniższym opisem.
Response informuje o tym, co faktycznie obsłużyło żądanie. Gdy wskażesz klasę, response zwraca exitClass:
{
"status": 200,
"exitClass": "premium",
"proxy": "Y2QXVK",
"data": "..."
}
premium oznacza, że treść odpowiedzi zwrócił węzeł wyjściowy premium. standard oznacza, że odpowiedź zwróciła pula standardowa. Jest to również wynik zwracany wtedy, gdy nie udało się uzyskać węzła premium oraz gdy limit transferu premium w ramach planu (wraz z dokupionym pakietem) został wyczerpany w danym okresie rozliczeniowym. Żadna z tych sytuacji nie jest błędem, a zużycie transferu premium można weryfikować na poziomie pojedynczego requestu, zamiast opierać się na danych miesięcznych. Ta sama wartość jest przesyłana w nagłówku odpowiedzi X-FourA-Exit-Class (zobacz Response Headers).
Transfer premium jest mierzony na poziomie sieci. Próba premium zlicza bajty wysłane i odebrane podczas transmisji sieciowej, w postaci skompresowanej i zaszyfrowanej, niezależnie od tego, czy strona została pomyślnie zwrócona. Próba, która wciąż trwała w momencie uzyskania odpowiedzi z innego węzła wyjściowego, jest natychmiast przerywana i nie wlicza się do limitu. Transfer premium wlicza się do dostępnego limitu premium oraz do łącznego transferu: te same bajty są raportowane w obu miejscach, ale nigdy nie są sumowane podwójnie. Gdy stronę dostarczy węzeł premium, jego transfer stanowi całkowity transfer requestu, więc strona nie jest liczona ponownie jako transfer standardowy. Strona Usage & Limits wyświetla łączny transfer, udział transferu premium oraz limit premium, według którego rozliczane jest konto.
Pominięcie tego pola to nie to samo co przesłanie standard. Pominięcie pozostawia decyzję nieokreśloną; przesłanie standard jawnie wskazuje, że ten request nie może przejść na wyższy poziom, co pozwala całkowicie wykluczyć dane zadanie z transferu premium.
Wyczerpanie limitu nie jest błędem. Request wskazujący premium po wyczerpaniu limitu nadal działa: jest obsługiwany przez pulę standardową, a w odpowiedzi zwracana jest wartość standard. Żadne zadanie nie zatrzymuje się z powodu wyczerpania limitu.
exitClass: premium wymaga planu obejmującego węzły wyjściowe premium. W planie bez nich request nigdy nie zużywa węzła premium: zostaje odrzucony ze statusem 403 i kodem X-FourA-Limit: plan_limit_premium (zobacz Rate Limits) lub obsłużony z puli standardowej z wartością exitClass: standard w odpowiedzi. Należy obsłużyć oba przypadki.
Browser Profile Rotation
Proxy rotuje węzły wyjściowe. Gdy strona odrzuca przeglądarkę przedstawioną przez FourA, a nie sam węzeł wyjściowy, Proxy przełącza się również na inną rodzinę przeglądarek z katalogu. Nie dodaje to kolejnej próby: rotacja zmienia parametry ponawianego requestu, ale nie decyduje o samym fakcie jego wykonania.
Proxy zapamiętuje także na pewien czas rodzinę ostatnio zaakceptowaną przez daną stronę, dzięki czemu kolejne wywołanie tego samego serwisu może rozpocząć się od tej rodziny zamiast domyślnej. Odpowiedź wskazuje ją w profile, tak jak w przypadku każdej rodziny wybranej w procesie rotacji.
Jawnie ustawione wartości profile, browser, os lub version w wewnętrznym obiekcie request nigdy nie są nadpisywane. Dotyczy to również requestu z własnym nagłówkiem User-Agent lub Cookie, ponieważ autoryzacja jest powiązana z sygnaturą, która ją uzyskała.
Browser Request
POST /api/browser/
Otwiera podany URL w instancji przeglądarki Chrome. Strona się ładuje, JavaScript wykonuje kod, a Ty otrzymujesz w pełni wyrenderowany HTML oraz zestaw cookies.
Request Body
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string | Tak | - | Docelowy URL |
headers |
object | Nie | - | Niestandardowe nagłówki jako pary klucz-wartość |
cookies |
array | Nie | - | Pliki cookie do ustawienia: [{name, value, domain?}] |
userAgent |
string | Nie | - | Niestandardowy ciąg User-Agent |
unblocker |
boolean | Nie | true |
Wykonuje weryfikację wymaganą przez stronę przed jej załadowaniem (ekran challenge lub podobna blokada). Domyślnie włączone. Ustaw false, aby wyrenderować dokładnie to, co zwraca strona, w tym ekran challenge. |
proxy |
string | Nie | - | ID proxy z wcześniejszej odpowiedzi w celu przypięcia tego samego węzła wyjściowego. Przekaż nieprzetworzony ciąg znaków bez zmian. Bezpośredni adres proxy zostanie odrzucony z błędem 400 Invalid proxy format. |
exitCountry |
string | Nie | - | D 친dwuliterowy kod kraju (ISO 3166-1 alpha-2), z którego wychodzi request. Ustawia zegar przeglądarki na pasującą strefę czasową. Zobacz Dopasowanie zegara przeglądarki do węzła wyjściowego. |
timeout_ms |
number | Nie | 30000 | Limit czasu ładowania strony w ms (maksymalnie: 120000) |
checkStatus |
number | Nie | - | Oczekiwany status HTTP (request kończy się niepowodzeniem, jeśli jest inny) |
checkText |
string | Nie | - | Tekst, który musi pojawić się na wyrenderowanej stronie |
Dopasowanie zegara przeglądarki do węzła wyjściowego
Strona może odczytać strefę czasową przeglądarki i porównać ją z krajem adresu IP, który widzi. Rozbieżność jest jednym z najprostszych sygnałów dla systemów wykrywania botów, a jej wyeliminowanie nic nie kosztuje.
Ustaw exitCountry na kraj, z którego wychodzi Twój ruch, a przeglądarka zgłosi powiązaną z nim strefę czasową:
{
"url": "https://example.com",
"proxy": "A1B2C3",
"exitCountry": "BR"
}
Zasady:
- Wartość określa kraj wyjściowy, czyli kraj widziany przez cel, a nie miejsce hostowania proxy. Te dwie wartości różnią się na tyle często, że ma to znaczenie.
- W przypadku pominięcia FourA używa kraju wyjściowego, jeśli jest znany, a w przeciwnym razie nie modyfikuje zegara przeglądarki zamiast zgadywać.
- Kod kraju nierozpoznany przez FourA jest traktowany tak samo jak pominięcie pola. Nie powoduje to błędu.
- Tylko zegar zależy od kraju.
Accept-Languageoraz treść serwowana przez witrynę pozostają nienaruszone, więc strona nie zmieni niespodziewanie języka.
Parametr userAgent
Wyślij userAgent, a dokładnie ten ciąg zobaczy strona, jej procesy robocze oraz cel. FourA generuje na jego podstawie także pasujące client hints (sec-ch-ua, sec-ch-ua-platform, navigator.platform oraz wartości high-entropy, o które system detekcji prosi po nazwie), dzięki czemu request nie deklaruje jednej przeglądarki w headerze i innej w JavaScript.
Wartość userAgent w response to ta, która została faktycznie zaprezentowana. Ma to znaczenie przy ponownym użyciu clearance: cookie cf_clearance jest powiązane z węzłem wyjściowym oraz User-Agent, który je uzyskał, dlatego należy odesłać ciąg zwrócony w response, a nie ten, który według Ciebie został użyty. Zobacz Site checks.
Wyślij ciąg inny niż Chromium (np. User-Agent Firefoksa), a zostanie on zaprezentowany w postaci niezmienionej, bez dołączonej listy marek Chromium.
Przykład
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/spa-app",
"timeout_ms": 15000,
"checkText": "product-list"
}'
Odpowiedź:
{
"status": 200,
"headers": {"content-type": "text/html"},
"body": "<!doctype html>...",
"cookies": [{"name": "session", "value": "abc123", "domain": "example.com", "path": "/", "expires": 1735689600, "httpOnly": true, "secure": true, "sameSite": "Lax"}],
"userAgent": "Mozilla/5.0...",
"defenseSolved": true,
"defenses": {"present": ["cloudflare"], "cleared": ["cloudflare"]},
"proxy": "A1B2C3"
}
| Pole | Typ | Opis |
|---|---|---|
status |
number | Kod statusu HTTP z celu |
headers |
object | Nagłówki odpowiedzi |
body |
string lub object | W pełni wyrenderowana zawartość strony. String HTML, gdy content-type to HTML; object, gdy strona zwróciła JSON i został on automatycznie sparsowany. |
cookies |
array | Pełne obiekty cookie ze strony. Każdy cookie zawiera name, value, domain, path, expires, httpOnly, secure, sameSite oraz inne właściwości cookie. |
userAgent |
string | Użyty User-Agent przeglądarki |
defenseSolved |
boolean | true, jeśli podczas tego wywołania napotkano i pomyślnie rozwiązano zabezpieczenie przed botami. W przeciwnym razie brak. Decyduje, czy wywołanie kosztuje 5 czy 10 kredytów. |
defenses |
object | present zawiera listę wszystkich dostawców rozpoznanych podczas ładowania strony, cleared wymienia tych, których autoryzację zawiera ostateczna strona. Dostawca może pojawić się w present i nigdy w cleared. Zobacz Site checks. |
proxy |
string | Zakodowane ID proxy, przez które przeszło żądanie (tylko gdy w żądaniu podano proxy). Użyj go ponownie w kolejnych wywołaniach, aby zachować ten sam węzeł wyjściowy. |
error |
string | Komunikat o błędzie, jeśli żądanie się nie powiodło |
Przypinanie węzła wyjściowego (Exit)
Wartość proxy w żądaniu Single lub Browser przypina węzeł wyjściowy użyty przez poprzednie wywołanie. Przekaż z powrotem nieprzejrzyste ID dokładnie w takiej formie, w jakiej zostało zwrócone, nigdy jako adres proxy.
Trzy wartości są odrzucane, wszystkie z kodem 400:
| Błąd | Znaczenie |
|---|---|
Invalid proxy format |
Wartość nie jest ID wydanym przez FourA. Surowy adres proxy trafi tutaj. |
Proxy not found |
ID zostało zdekodowane, ale nie wskazuje już na aktywny węzeł wyjściowy. Pobierz nowy z nowego wywołania. |
Managed exit: this proxy id cannot be pinned to a request |
Węzeł wyjściowy istnieje, ale nie jest to węzeł, który FourA utrzyma otwarty dla nazwanego żądania. ID węzła wyjściowego premium trafi tutaj, gdy w Twoim planie nie ma już dostępnego transferu premium. Użyj ponownie sesji, w której został zwrócony, lub uruchom wywołanie przez POST /api/proxy/ i skorzystaj z dowolnego węzła, który zostanie wybrany. |
Przypięty węzeł wyjściowy premium jest rozliczany jako ruch premium. Odpowiedź zawiera X-FourA-Exit-Class: premium, dzięki czemu możesz to sprawdzić dla każdego żądania, a ruch obsłużony przez węzeł wyjściowy wlicza się do transferu premium na stronie Usage & Limits, jak i do całkowitej przepustowości, niezależnie od tego, czy witryna zwróciła żądaną stronę. Przypinanie wymaga dostępności węzłów premium w planie oraz niewyczerpanego limitu; w przeciwnym razie ID zostanie odrzucone z powyższym błędem 400 dla węzła zarządzanego.
Kody statusu HTTP
| Kod | Znaczenie |
|---|---|
| 200 | Żądanie zakończone (sprawdź wewnętrzne status dla odpowiedzi docelowej) |
| 400 | Nieprawidłowe body żądania, parametry, docelowy IP w zakresie prywatnym/zarezerwowanym lub ID proxy, którego nie można przypiąć |
| 401 | Brakujący lub nieprawidłowy klucz API |
| 403 | Endpoint lub parametr nie jest dostępny w Twoim planie. Wskazuje go X-FourA-Limit: plan_limit_feature lub plan_limit_premium. |
| 404 | Not Found: brak endpointu pod tą ścieżką. |
| 413 | Body żądania JSON przekracza 100 KB. Odpowiedź nie jest w formacie JSON i nie zawiera X-FourA-Request-Id. |
| 429 | Limit planu (ustawiony X-FourA-Limit) lub współdzielony limit platformy na minutę (brak nagłówka) |
| 500 | Wewnętrzny błąd serwera |
| 502 | Upstream unavailable. FourA połączyło się ze swoim silnikiem, ale odpowiedź była bezużyteczna. Ponów próbę. |
| 503 | Usługa tymczasowo wyłączona lub przeciążona, albo Backend service unavailable podczas restartu silnika |
| 504 | Upstream timeout. Silnik nie zakończył pracy w limicie czasu dla tego żądania. Zwiększ timeout_ms lub ponów próbę. |
Kolejne kroki
- Smart Fetch (Auto): Kiedy pozwolić FourA na automatyczny wybór ścieżki
- Wybór właściwego endpointu: Kiedy ręcznie wybrać Single, Proxy lub Browser
- Uwierzytelnianie: Zarządzaj swoimi kluczami API
- Obsługa błędów: Prawidłowa obsługa błędów
- Weryfikacje stron: Odczytaj pole
defensei powtórz autoryzację - Dlaczego żądanie przez proxy wyczerpało próby: Odczytaj
attemptReporti podejmij działanie - Rate limity: Zrozum limity żądań
- Szybki start: Twoje pierwsze żądanie w 30 sekund