API Endpoints Referenz

Eine Referenz für alle FourA-API-Endpoints mit Request-Parametern und Response-Formaten.

Base-URL

https://eu.api.foura.ai/api

Authentifizierung

Jeder Request erfordert deinen API-Key im X-API-Key-Header:

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"}'

Erstelle und verwalte API-Keys im Dashboard. Keys nutzen das Präfix pk_live_.

Response Headers

Responses von /api/* enthalten zwei Korrelations-Header:

Header Value Description
X-FourA-Request-Id UUID Eindeutige ID, die dem Request zugewiesen wird. Wird bei jeder Response zurückgegeben, einschließlich 4xx und 5xx, außer bei einem Body, den FourA überhaupt nicht lesen kann: 400 Invalid JSON in request body und 413 werden abgelehnt, bevor eine ID zugewiesen wird. Logge sie auf deiner Seite.
X-FourA-Credits integer Für diesen Request verbrauchte Credits. Wird bei jeder Response zurückgegeben, die eine Engine erreicht hat, egal ob Erfolg oder Fehler (die Arbeit wurde in beiden Fällen ausgeführt). Ein Aufruf, den FourA abgelehnt hat, bevor eine Engine ihn ausgeführt hat (ein fehlender oder ungültiger Key, ein Plan- oder Plattform-Limit, eine abgelehnte Ziel- oder Proxy-ID), enthält keinen. Unter Request-Ergebnisse siehst du, welche Ergebnisse abrechenbar sind.

Dieselbe Request-ID dient als Schlüssel für die Vorschau der Request- und Response-Payloads im Activity Log des Dashboards (24 Stunden aufbewahrt, die letzten 200 pro Key). So kannst du den genauen Request später nachschlagen und direkt aus dem Activity Log im Playground erneut ausführen. Gib sie an, wenn du den Support kontaktierst, damit der Request in Sekundenschnelle gefunden werden kann.

$ 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
...

Siehe Response Headers für die vollständige Liste und Nutzungstipps.

Endpoints

Verwendest du diese Endpoints über MCP? Der @fouradata/mcp Server verpackt alle vier Endpoints als native MCP-Tools (foura_auto, foura_single, foura_proxy, foura_browser) mit denselben Eingabeformaten plus einem offload_large Opt-in für token-effizientes Handling großer Responses.

FourA bietet vier Request-Endpoints, jeweils optimiert für ein anderes Szenario:

Endpoint Best for
POST /auto/ Smart Fetch. Du übergibst eine URL, FourA wählt den günstigsten funktionierenden Pfad (direkt, rotierter Proxy oder Browser) und speichert, was pro Host funktioniert.
POST /single/ Schnelle HTTP-Requests, statische Seiten, APIs
POST /proxy/ Geschützte Seiten mit automatischer Proxy-Rotation, optionalem zielseitig sichtbarem Länder-Scoping
POST /browser/ JavaScript-gerenderte Seiten, SPAs
GET /profiles Der Browser-Profil-Katalog für single und proxy. Öffentlich, kein API-Key.

Einen detaillierteren Leitfaden zur Auswahl findest du unter Choosing the Right Endpoint und im Smart Fetch guide.

Target URL Restrictions

Ziele, die zu privaten, Loopback- oder reservierten IP-Bereichen auflösen (RFC 5735, RFC 6598, reservierte IPv6-Blöcke), werden mit einem 400 abgelehnt, bevor der Request FourA verlässt. Nur öffentliche Hostnames und IPs werden weitergeleitet.

{ "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/

Du uebergibst eine URL sowie optionale validate Regeln. FourA durchlaeuft eine kostenoptimierte Eskalationsstufe (guenstiger Direkt-Probe, rotierter Proxy, vollstaendiger Browser) und stoppt auf der ersten Stufe, die eine Antwort liefert, die deine Regeln akzeptieren. Bei wiederholten Aufrufen desselben Hosts wird stattdessen eine warme Session wiederverwendet, sodass der zweite Aufruf guenstig ist.

Du musst Retries, Pool-Groessen oder Proxy-Anzahlen nicht optimieren. FourA lernt diese pro Host.

Request Body

Parameter Typ Erforderlich Standard Beschreibung
url string Ja - Ziel-URL
method string Nein "GET" HTTP-Methode
headers [string, string][] Nein - Benutzerdefinierte Header als [name, value]-Paare
data any Nein - Request-Body fuer Nicht-GET-Requests
validate object Nein - Erfolgskriterien, gleiche Struktur wie validate bei Single Request (siehe unten). Gib auto an, wie eine echte Seite aussieht, damit Content von einer Challenge-Seite unterschieden werden kann.
returnSession boolean Nein true Fuege die erfolgreiche Session (proxy, cookies, userAgent) in die Response ein, damit du sie ueber /api/single/ oder /api/browser/ erneut abspielen kannst.
forceProxy boolean Nein true Immer ueber einen rotierenden Proxy leiten. Setze false, um den guenstigeren direkten Pfad zu erlauben, wenn das Ziel dies zulaesst (einige Schutzmechanismen sind bei Proxy-Traffic strenger).
timeout_ms integer Nein 120000 Gesamtzeitbudget fuer den gesamten Aufruf in Millisekunden. Alle Unterversuche laufen innerhalb dieses Budgets. Min 5000, max 180000.
ignoreProxies string[] Nein - Proxy-IDs, die bei jedem Unterversuch vermieden werden sollen. Verwende IDs aus vorherigen /api/auto/- oder /api/proxy/-Responses.
followRedirects integer Nein 5 Maximale Anzahl an Redirects, denen auf den guenstigen Stufen gefolgt wird. 0 zum Deaktivieren. 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..."
  }
}
Feld Typ Beschreibung
status number HTTP-Status des Ziels.
data string Response-Body als Text, unabhängig von der ausführenden Stufe. Eine JSON-Seite wird als JSON-Text zurückgegeben, den du selbst parsen musst.
headers array or object Response-Header des Ziels. Single- und Proxy-Stufen geben ein Array von Header-Objekten pro Hop zurück; Browser-Stufen liefern ein flaches Objekt.
meta.rung string Gibt an, welche Stufe die Response geliefert hat. Einer der folgenden Werte: probe (günstiger direkter Request), proxy (rotierender Proxy), browser (vollständiges Browser-Rendering), cache (erneutes Abspielen einer aktiven Session), warmup (die Startseite der Website wurde zuerst abgerufen und ihre Cookies öffneten die Deep-URL) oder fail (keine Stufe lieferte eine akzeptierte Response).
meta.solved boolean Gibt an, ob die Seite einen zusätzlichen Schritt erforderte (eine Challenge-Seite) und dieser während dieses Aufrufs abgeschlossen wurde.
meta.attempts number Anzahl der Teilversuche vor dem Erfolg.
meta.credits number Gesamte verbrauchte Credits für diesen Aufruf. Entspricht X-FourA-Credits.
session.proxy string Encodierte ID des Proxys, der die Response geliefert hat. Kannst du bei einem Single- oder Browser-Request wiederverwenden. Vorhanden, wenn returnSession gleich true ist.
session.cookies array Cookies aus dem erfolgreichen Versuch. Vorhanden, wenn returnSession gleich true ist.
session.userAgent string User-Agent, der beim erfolgreichen Versuch verwendet wurde. Vorhanden, wenn returnSession gleich true ist.
error string Fehlermeldung, falls der Aufruf fehlgeschlagen ist.

Beispiel

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"]}}
  }'

Hinweise

  • Auto fungiert als Koordinator. Es ruft intern Single, Proxy oder Browser auf und leitet deinen API-Key an jeden Unteraufruf weiter. Der Auto-Aufruf zählt als ein Request in deinem Activity Log und in deiner Overview, mit der Summe der Credits seiner Unteraufrufe. Die Unteraufrufe werden darunter als Versuche aufgeführt und zählen niemals als eigene Requests.
  • Übergib validate.data.accept mit einem Substring, den nur die echte Seite enthält. Ohne ihn kann Auto einen echten 200-Status nicht von einer Challenge-Zwischenseite mit Status 200 unterscheiden.
  • timeout_ms begrenzt den gesamten Aufruf. Ein erster Cold-Aufruf einer geschützten Website kann zig Sekunden dauern; wiederverwendete Warm-Sessions sind meist in unter einer Sekunde fertig.

Single Request

POST /api/single/

Sendet einen HTTP-Request mit realistischen, browserähnlichen Wire-Eigenschaften, ohne einen echten Browser zu starten. Dies ist der schnellste Endpoint.

Request Body

Parameter Typ Erforderlich Standard Beschreibung
method string Ja - HTTP-Methode: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
url string Ja - Ziel-URL. Verwende {ts} an beliebiger Stelle in der URL, um den aktuellen Zeitstempel für Cache-Busting einzufügen.
headers [string, string][] Nein - Benutzerdefinierte Header als [name, value]-Paare
unblocker boolean Nein true Realistische Browser-Header senden (User-Agent, Sec-Ch-Ua, Sec-Fetch-*, Accept-Encoding). Standardmäßig aktiviert. Setze false, um eine einfache Client-Signatur zu senden.
timeout_ms number Nein 15000 Gesamt-Timeout in ms (max: 120000)
connect_timeout_ms number Nein 5000 Verbindungs-Timeout in ms
accept_timeout_ms number Nein 5000 Accept-Timeout in ms (Wartezeit auf Verbindungsannahme)
server_response_timeout_ms number Nein 15000 Serverantwort-Timeout in ms (Wartezeit auf erstes Byte)
dns_cache_timeout_sec number Nein 120 DNS-Cache-TTL in Sekunden (max: 240)
followRedirects number Nein disabled Max. Weiterleitungen (0-20). Weglassen zum Deaktivieren.
tryJsonData boolean Nein false Response-Body wenn möglich als JSON parsen
returnBuffer boolean Nein false Roh-Buffer statt decodiertem String zurückgeben
data any Nein - Request-Body (String oder Objekt, automatisch nach JSON serialisiert)
proxy string Nein - Proxy-ID aus einer früheren Response, um denselben Exit zu pinnen. Übergib den opaken String unverändert. Eine rohe Proxy-Adresse wird mit 400 Invalid proxy format abgelehnt. Manche IDs können nicht gepinnt werden: siehe Pinning an exit.
browser string Nein Chrome Vorzutäuschender Browser: Chrome, Edge, Safari, Firefox oder Tor. Siehe Browser profiles.
os string Nein - Vorzutäuschendes Betriebssystem: Windows, macOS, Android oder iOS. Ein Familienname akzeptiert jede seiner Versionen.
version string Nein newest Vorzutäuschende Browser-Version gemäß Katalog. Bei mehreren Treffern gewinnt der neueste.
profile string Nein - Exakte Profil-ID aus GET /api/profiles anstelle der drei obigen Felder.
validate object Nein - Response-Validierungsregeln (siehe unten)

Browser profiles

Standardmäßig verwendet ein Request das neueste Google Chrome. Manche Ziele akzeptieren einen bestimmten Browser und blockieren andere. Mit browser, os und version schränkst du einen Katalog vermessener Profile ein; profile wählt eines direkt per ID aus.

{
  "method": "GET",
  "url": "https://example.com",
  "browser": "Firefox",
  "os": "Windows"
}

Regeln:

  • Die Auswahl erfordert unblocker (standardmäßig aktiviert). Wenn unblocker deaktiviert ist, werden keine Browser-Header gesendet; der Request wird daher abgelehnt statt unvollständig angewendet.
  • Wenn mehrere Profile übereinstimmen, gewinnt die neueste Version.
  • Eine Kombination, die der Katalog nicht bereitstellen kann, gibt einen Fehler zurück, der die verfügbaren Optionen nennt. Der Request wird niemals als anderer Browser gesendet.
  • Dieselben vier Felder sind im request-Objekt von POST /proxy/ verfügbar.

GET /api/profiles gibt den vollständigen Katalog zurück und benötigt keinen API-Key:

{
  "profiles": [
    { "id": "...", "browser": "Chrome", "version": "...", "os": "...", "osFamily": "macOS" }
  ],
  "default": "..."
}

osFamily ist der Wert zum Filtern beim Erstellen eines Pickers; os behält den Release-Namen für die Anzeige.

Validierungsregeln

Mit dem Objekt validate kannst du Bedingungen für Erfolg und Fehler definieren. Wenn eine fail-Bedingung zutrifft, wird der Request als fehlgeschlagen gewertet. Wenn accept-Bedingungen festgelegt sind, werden nur übereinstimmende Responses als erfolgreich gewertet.

{
  "validate": {
    "status": { "accept": [200, 201], "fail": [403, 503] },
    "headers": { "accept": {"content-type": "application/json"} },
    "data": { "accept": ["product"], "fail": ["captcha", "blocked"] }
  }
}
Feld Typ Beschreibung
validate.status.accept number[] Zu akzeptierende HTTP-Statuscodes
validate.status.fail number[] Abzuweisende HTTP-Statuscodes
validate.headers.accept object Header-Schlüssel-Wert-Paare, die vorhanden sein müssen
validate.headers.fail object Header-Schlüssel-Wert-Paare, die einen Fehler auslösen
validate.data.accept string[] Zeichenketten, die im Response-Body enthalten sein müssen
validate.data.fail string[] Zeichenketten im Response-Body, die einen Fehler auslösen

Beispiel

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"
}

Wenn das Ziel vor der Auslieferung des Body einen Bot-Check durchführt, enthält die Response auch ein defense-Objekt, das den Anbieter nennt und angibt, ob der Check bestanden wurde:

{
  "status": 200,
  "data": "<!doctype html>...",
  "total_time": 3.61,
  "defense": {
    "vendor": "sgcaptcha",
    "solved": true,
    "present": ["sgcaptcha"],
    "ms": 3412,
    "cookie": "_I_=<clearance>"
  }
}
Feld Typ Beschreibung
status number HTTP-Statuscode des Ziels
headers array Ein Objekt pro Redirect-Hop. Jedes enthält ein Feld result mit der Statuszeile und allen Response-Headern. Multi-Value-Header (Set-Cookie, Link, WWW-Authenticate) werden als String-Arrays zurückgegeben.
data string/object Response-Body (JSON, wenn tryJsonData true ist)
total_time number Gesamte Request-Dauer in Sekunden
proxy string Encodierte ID des Proxys, über den der Request lief (nur wenn beim Request ein proxy übergeben wurde). Verwende sie bei Folgeaufrufen wieder, um denselben Exit festzuhalten.
defense object Vorhanden, wenn das Ziel bei diesem Request einen Bot-Check ausgeführt hat oder wenn ein Retry mit den Cookies der Website den Body geliefert hat. defense.solved gibt an, ob ein Check gelöst wurde, defense.retry gibt an, ob ein Retry den Inhalt geliefert hat. Siehe Site-Checks für alle Felder und die vollständige Liste der Systeme.
error string Fehlermeldung, falls der Request fehlgeschlagen ist

Proxy Request

POST /api/proxy/

Leitet deinen Request über rotierende Proxys mit automatischem Retry bei Fehlern weiter. Die Auswahl kann optional auf bestimmte zielseitig sichtbare Exit-Länder eingeschränkt werden.

Request Body

Parameter Typ Erforderlich Standard Beschreibung
request object Ja - Ein einzelner Request-Body (dieselben Felder wie bei Single Request oben)
timeout_ms number Nein 45000 Gesamt-Timeout für alle Versuche in ms (max: 120000)
maxTries number Nein 5 Maximale Proxy-Rotationsversuche (max: 90)
ignoreProxies string[] Nein - Proxy-IDs, die von der Rotation ausgeschlossen werden sollen (IDs aus vorherigen Responses verwenden)
exitCountries string[] Nein - Strikte Allowlist aus zweistelligen, zielseitig sichtbaren Ländercodes (z. B. ["CZ", "GB"]). Werte werden getrimmt, in Großbuchstaben umgewandelt und dedupliziert. Proxys mit unbekannten Exits werden ausgeschlossen und der Request weicht niemals auf ein nicht angefordertes Land aus.
exitClass string Nein - standard oder premium. premium erlaubt die Eskalation auf einen Premium-Exit, wenn der Standard-Pool bei einem geschützten Ziel scheitert. Erfordert einen Plan mit Premium-Exits.

exitCountries-Scoping

Die Auswahl nutzt die neuesten verfügbaren zielseitig sichtbaren Ländermetadaten, die üblicherweise etwa alle zehn Minuten aktualisiert werden. Es handelt sich nicht um ein Live-Geolocation-Lookup während des Requests. Leite das bereitstellende Land nicht aus der Proxy-Hostadresse ab.

Wenn der aktuelle Pool keine Übereinstimmung für die angeforderten Länder hat, gibt die Response HTTP 200 mit einem Error-Envelope zurück:

{
  "error": "No eligible proxy found for exit countries: CZ, GB",
  "code": "no_eligible_proxy",
  "details": { "exitCountries": ["CZ", "GB"] },
  "total": 0.084
}

Behalte den angeforderten Scope bei und versuche es später erneut. Ändere oder erweitere ihn nur, wenn sich die Länderanforderung deines Workflows explizit ändert.

Beispiel

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"
    }
  }'

Response:

{
  "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
}
Feld Typ Beschreibung
proxy string Codierte Kennung des verwendeten Proxys. Verwende sie bei einem Single- oder Browser-Request wieder, indem du sie als Feld proxy übergibst, oder überspringe sie beim nächsten Proxy-Request via ignoreProxies.
exitCountry string Für das Ziel sichtbarer zweistelliger Ländercode des Proxys, der den Request verarbeitet hat. Nur vorhanden, wenn der Request exitCountries gesetzt hat. Prüfe immer, ob es sich um einen der von dir angeforderten Codes handelt, bevor du der Response vertraust.
exitClass string Gibt an, welche Exit-Klasse diesen Request verarbeitet hat. Bei erfolgreicher Response vorhanden, wenn der Request eine angegeben hat. premium bedeutet, dass ein Premium-Exit den Body zurückgegeben hat; standard bedeutet, dass dies der Standard-Pool war. Ein fehlgeschlagener Aufruf hat nichts verarbeitet und enthält daher kein exitClass; lies attemptReport aus, um zu erfahren, worauf die Versuche gestoßen sind.
total number Gesamte reale Laufzeit in Sekunden (Float). Beinhaltet Proxy-Auswahl, Retries und den erfolgreichen Versuch. total_time betrifft nur den inneren Request; total ist immer >= total_time.
profile string Das von der Rotation gewählte Browser-Profil. Nur vorhanden, wenn es nicht das von dir angeforderte war. Fehlt der Wert, wurde der Request exakt wie angegeben ausgeführt. Übergib die ID bei Folgeaufrufen als profile zurück, um den funktionierenden Browser beizubehalten.
error string Fehlermeldung, falls der Request fehlschlägt. Bei einem Scope-Miss ist code gleich no_eligible_proxy und details.exitCountries gibt den normalisierten Scope aus.
attemptReport object Bei jedem fehlgeschlagenen Proxy-Aufruf vorhanden. Zählt die aufgetretenen Probleme der Versuche, damit ein blockierter Pool, ein toter Pool und eine validate-Regel ohne Treffer nicht als derselbe Fehler gewertet werden. Siehe unten.

Alle Response-Felder von Single Request sind ebenfalls enthalten, darunter defense: Ein Proxy-Versuch, der auf einen Bot-Check stößt, meldet dies genauso wie Single.

Warum ein Proxy-Aufruf fehlschlug

Download maxTry limit reached sieht unabhängig vom Ausgang der Versuche gleich aus, daher enthält jede fehlgeschlagene Proxy-Response neben dem Fehler ein attemptReport:

{
  "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
}
Feld Typ Beschreibung
total integer Durchgeführte Versuche
noResponse integer Der Exit hat nie geantwortet, die Website wurde also nie erreicht
defense integer Die Website hat geantwortet und bei dieser Antwort wurde ein Bot-Check erkannt
contentRejected integer HTTP 200, kein Bot-Check, nur durch deine validate.data abgelehnt
statusRejected integer Die Website hat geantwortet, kein Bot-Check, durch deine validate.status abgelehnt
other integer Beantwortet und keines der oben genannten
vendors string[] Bot-Check-Anbieter, die an beliebiger Stelle im Task erkannt wurden
profilesTried string[] Browser-Profile, die der Task gesendet hat, in der Reihenfolge der ersten Verwendung. default bedeutet, dass dein Request unverändert gesendet wurde.
summary string Ein aus den Zählern erstellter Satz, sicher zu loggen

Der String error bleibt unverändert, sodass ein Client, der darauf matcht, weiterhin funktioniert. Was bei jedem Zähler zu tun ist: Warum ein Proxy-Request keine Versuche mehr übrig hatte.

exitClass

Manche Ziele lehnen die Exits im Standard-Pool ab, egal wie viele probiert werden. exitClass: premium teilt Proxy mit, dass ein solcher Request zusätzlich zum Standard-Pool zu einem Premium-Exit eskaliert werden darf, anstatt nur innerhalb dieses Pools zu rotieren.

{
  "exitClass": "premium",
  "request": { "method": "GET", "url": "https://example.com/report" }
}

Drei Dinge solltest du wissen, bevor du den Request sendest.

Es ist ein Kontingent, keine Anweisung. Der Standard-Pool versucht weiterhin zuerst zu antworten und gewinnt meistens. Ein Premium-Exit schaltet sich erst ein, wenn der Pool ein kurzes Zeitbudget für den Request aufgebraucht hat oder das Ziel ihn sichtbar abgelehnt hat. Ein Request, den der Standard-Pool beantwortet, bevor ein Premium-Exit versucht wurde, gilt als normaler Erfolg und kostet dich keinen Premium-Traffic. Sobald ein Premium-Exit versucht wurde, zählt dessen Traffic wie unten beschrieben.

Die Response zeigt dir, was dich tatsächlich bedient hat. Wenn du eine Klasse angibst, liefert die Response exitClass zurück:

{
  "status": 200,
  "exitClass": "premium",
  "proxy": "Y2QXVK",
  "data": "..."
}

premium bedeutet, dass ein Premium-Exit den Body zurückgegeben hat. standard bedeutet, dass der Standard-Pool dies getan hat. Das ist auch die Antwort, wenn kein Premium-Exit bezogen werden konnte oder das in deinem Plan enthaltene Premium-Traffic-Kontingent (plus zusätzlich gekaufte Mengen) für den Abrechnungszeitraum aufgebraucht ist. Beides ist kein Fehler, und du kannst deinen Premium-Traffic pro Request statt über Monatswerte abgleichen. Derselbe Wert wird im X-FourA-Exit-Class Response-Header übertragen (siehe Response Headers).

Premium-Traffic wird auf Netzwerkebene gemessen. Ein Premium-Versuch zählt die gesendeten und empfangenen Bytes während der Übertragung über das Netzwerk, komprimiert und verschlüsselt, unabhängig davon, ob deine Seite zurückgegeben wurde. Ein Versuch, der noch lief, als ein anderer Exit geantwortet hat, wird sofort gestoppt und nicht gezählt. Premium-Traffic zählt zu deinem Premium-Kontingent und zu deiner gesamten Bandbreite: dieselben Bytes, doppelt ausgewiesen, nie summiert. Wenn ein Premium-Exit die Seite geliefert hat, entspricht sein Traffic dem gesamten Traffic des Requests, sodass die Seite nicht noch einmal als Standard-Traffic gezählt wird. Deine Seite Usage & Limits zeigt den Gesamttraffic, den Premium-Anteil daran und das Premium-Kontingent, an dem du gemessen wirst.

Das Weglassen des Felds ist nicht dasselbe wie das Senden von standard. Weglassen lässt die Entscheidung offen; das Senden von standard legt explizit fest, dass dieser Request niemals eskalieren darf. So hältst du einen bestimmten Job vollständig von Premium-Traffic fern.

Das Aufbrauchen des Kontingents ist kein Fehler. Ein Request mit premium funktioniert nach Verbrauch des Kontingents weiter: Der Standard-Pool bedient ihn und die Response meldet standard. Kein Job bricht wegen eines aufgebrauchten Kontingents ab.

exitClass: premium erfordert einen Plan mit Premium-Exits. In einem Plan ohne Premium-Exits verbraucht der Request niemals einen Premium-Exit: Er wird entweder mit 403 und X-FourA-Limit: plan_limit_premium abgelehnt (siehe Rate Limits) oder aus dem Standard-Pool mit exitClass: standard in der Response bedient. Fange beides ab.

Browser Profile Rotation

Proxy rotiert Exits. Wenn eine Website den von FourA präsentierten Browser statt des Exits ablehnt, wechselt Proxy zudem zu einer anderen Browser-Familie aus dem Katalog. Dabei wird kein zusätzlicher Versuch erzeugt: Die Rotation ändert nur, was ein Retry sendet, nicht, ob einer stattfindet.

Proxy speichert zudem temporär die Browser-Familie, die eine Website zuletzt akzeptiert hat. Ein späterer Aufruf derselben Website kann so direkt mit dieser Familie statt mit dem Standard beginnen. Die Response nennt sie in profile, genau wie jede durch die Rotation gewählte Familie.

Ein explizites profile, browser, os oder version in deinem inneren request wird nie überschrieben. Das gilt auch für Requests mit eigenem User-Agent- oder Cookie-Header, da eine Freigabe an die Signatur gebunden ist, mit der sie erlangt wurde.


Browser Request

POST /api/browser/

Öffnet deine URL in einer Chrome-Browser-Instanz. Die Seite lädt, JavaScript wird ausgeführt und du erhältst das vollständig gerenderte HTML sowie den Cookie-Jar.

Request Body

Parameter Typ Erforderlich Standard Beschreibung
url string Ja - Ziel-URL
headers object Nein - Benutzerdefinierte Header als Key-Value-Paare
cookies array Nein - Zu setzende Cookies: [{name, value, domain?}]
userAgent string Nein - Benutzerdefinierter User-Agent-String
unblocker boolean Nein true Schließt die Prüfung ab, die eine Seite vor dem Laden verlangt (eine Challenge-Seite oder ein ähnliches Gate). Standardmäßig aktiviert. Setze false, um die Rückgabe der Seite inklusive einer Challenge-Seite unverändert zu rendern.
proxy string Nein - Proxy-ID aus einer früheren Response, um denselben Exit beizubehalten. Übergib den opaken String unverändert zurück. Eine reine Proxy-Adresse wird mit 400 Invalid proxy format abgewiesen.
exitCountry string Nein - Zwei-Buchstaben-Ländercode (ISO 3166-1 alpha-2) des Landes, über das der Request ausgeht. Setzt die Browser-Uhr auf eine passende Zeitzone. Siehe Browser-Uhr an den Exit anpassen.
timeout_ms number Nein 30000 Timeout für das Laden der Seite in ms (max: 120000)
checkStatus number Nein - Erwarteter HTTP-Status (Request schlägt fehl, falls abweichend)
checkText string Nein - Text, der auf der gerenderten Seite vorkommen muss

Browser-Uhr an den Exit anpassen

Eine Seite kann die Zeitzone des Browsers auslesen und mit dem Land der erkannten IP abgleichen. Eine Abweichung ist eines der einfachsten Signale für einen Bot-Detektor, und es kostet dich nichts, sie zu vermeiden.

Setze exitCountry auf das Land, über das dein Traffic ausgeht, und der Browser meldet eine dazu passende Zeitzone:

{
  "url": "https://example.com",
  "proxy": "A1B2C3",
  "exitCountry": "BR"
}

Regeln:

  • Der Wert ist das Exit-Land, also das Land, das das Ziel sieht, nicht der Host-Standort des Proxys. Beide weichen oft genug voneinander ab.
  • Wenn du ihn weglässt, nutzt FourA das Exit-Land, sofern bekannt. Andernfalls bleibt die Browser-Uhr unverändert, anstatt zu raten.
  • Ein Ländercode, den FourA nicht erkennt, wird wie ein weggelassenes Feld behandelt. Das ist kein Fehler.
  • Nur die Uhr folgt dem Land. Accept-Language und der vom Server gelieferte Inhalt bleiben unberührt, sodass die Seite nicht unerwartet die Sprache wechselt.

Der Parameter userAgent

Sende userAgent und genau dieser String wird der Seite, ihren Workern und dem Ziel bereitgestellt. FourA leitet daraus auch die passenden Client Hints ab (sec-ch-ua, sec-ch-ua-platform, navigator.platform sowie die High-Entropy-Werte, die ein Detector namentlich abfragt). So behauptet der Request nicht einen Browser im Header und einen anderen in JavaScript.

Der userAgent in der Response ist der tatsächlich verwendete. Das ist wichtig beim Replay einer Clearance: Ein cf_clearance-Cookie ist an den Exit und den User-Agent gebunden, der ihn erhalten hat. Sende daher genau den String zurück, den die Response gemeldet hat, nicht den, von dem du glaubst, dass er verwendet wurde. Siehe Site checks.

Sendest du einen Nicht-Chromium-String (etwa einen Firefox-User-Agent), wird er unverändert übergeben, ohne angehängte Chromium-Brand-Liste.

Beispiel

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"
  }'

Response:

{
  "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"
}
Feld Typ Beschreibung
status number HTTP-Statuscode vom Ziel
headers object Response-Header
body string or object Vollständig gerenderter Seiteninhalt. String-HTML, wenn Content-Type HTML ist; Objekt, wenn die Seite JSON zurückgegeben hat und dieses automatisch geparst wurde.
cookies array Vollständige Cookie-Objekte der Seite. Jedes Cookie enthält name, value, domain, path, expires, httpOnly, secure, sameSite und weitere Cookie-Eigenschaften.
userAgent string Verwendeter Browser-User-Agent
defenseSolved boolean true, wenn bei diesem Aufruf ein Bot-Schutz erkannt und erfolgreich überwunden wurde. Andernfalls nicht vorhanden. Bestimmt, ob der Aufruf 5 oder 10 Credits kostet.
defenses object present listet alle beim Laden der Seite erkannten Anbieter auf, cleared listet diejenigen auf, deren Freigabe die finale Seite behält. Ein Anbieter kann in present auftauchen und nie in cleared. Siehe Site checks.
proxy string Encodierte ID des Proxys, über den der Request lief (nur wenn beim Request ein proxy übergeben wurde). Verwende sie bei Folgeaufrufen wieder, um denselben Exit beizubehalten.
error string Fehlermeldung, falls der Request fehlgeschlagen ist

Einen Exit anheften

Ein proxy-Wert bei einem Single- oder Browser-Request heftet den Exit an, den ein vorheriger Aufruf verwendet hat. Übergib die opaque ID exakt so zurück, wie sie empfangen wurde, niemals eine Proxy-Adresse.

Drei Werte werden abgelehnt, alle mit einem 400:

Fehler Bedeutung
Invalid proxy format Der Wert ist keine von FourA ausgestellte ID. Eine reine Proxy-Adresse führt hierher.
Proxy not found Die ID wurde dekodiert, verweist aber nicht mehr auf einen aktiven Exit. Hole dir einen neuen über einen frischen Aufruf.
Managed exit: this proxy id cannot be pinned to a request Der Exit existiert, wird von FourA aber nicht für einen benannten Request offengehalten. Die ID eines Premium-Exits führt hierher, wenn dein Plan kein Premium-Guthaben mehr hat. Verwende die Session wieder, mit der er zurückkam, oder führe den Aufruf über POST /api/proxy/ aus und nimm den Exit, der automatisch gewählt wird.

Ein angehefteter Premium-Exit wird als Premium-Traffic abgerechnet. Die Response enthält X-FourA-Exit-Class: premium, damit du dies pro Request einsehen kannst, und der über den Exit geführte Traffic zählt sowohl für den Premium-Traffic auf deiner Seite Usage & Limits als auch für deine gesamte Bandbreite, unabhängig davon, ob die Website die gewünschte Seite zurückgegeben hat. Das Anheften erfordert Premium-Exits in deinem Plan sowie verbleibendes Kontingent; andernfalls wird die ID mit dem oben genannten Managed-Exit-400 abgelehnt.

HTTP-Statuscodes

Code Bedeutung
200 Request abgeschlossen (prüfe inneres status auf Ziel-Response)
400 Ungültiger Request-Body, Parameter, Ziel-IP in einem privaten/reservierten Bereich oder eine Proxy-ID, die nicht gepinnt werden kann
401 Fehlender oder ungültiger API-Key
403 Der Endpoint oder ein Parameter ist nicht in deinem Plan enthalten. X-FourA-Limit nennt ihn: plan_limit_feature oder plan_limit_premium.
404 Not Found: Unter diesem Pfad existiert kein Endpoint.
413 Der JSON-Request-Body ist größer als 100 KB. Die Antwort ist kein JSON und enthält kein X-FourA-Request-Id.
429 Ein Plan-Limit (X-FourA-Limit gesetzt) oder das geteilte Minutenkontingent der Plattform (kein Header)
500 Interner Serverfehler
502 Upstream unavailable. FourA hat seine Engine erreicht, aber die Antwort war unbrauchbar. Erneut versuchen.
503 Service vorübergehend deaktiviert oder ausgelastet, oder Backend service unavailable während eines Engine-Neustarts
504 Upstream timeout. Die Engine wurde nicht innerhalb des Zeitlimits für diesen Request fertig. Erhöhe timeout_ms oder versuche es erneut.

Nächste Schritte

Aktualisiert: 30. September 2026