Häufige Probleme

Lösungen für die häufigsten Probleme bei der Nutzung der FourA API.

Leerer oder unvollständiger Inhalt

Symptom: Die API gibt einen Status 200 zurück, aber das Feld data ist leer oder enthält nicht den erwarteten Inhalt.

Ursache: Die Zielseite verwendet JavaScript, um Inhalte nach dem initialen Laden der Seite zu rendern.

Lösung: Wechsle vom Single-Endpoint zum Browser-Endpoint. Verwende checkText, um zu prüfen, ob der Inhalt geladen wurde:

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/products",
    "timeout_ms": 15000,
    "checkText": "product-list"
  }'

Hinweis: Der Browser-Endpoint gibt Inhalte im Feld body zurück (nicht data).

403 Forbidden oder Verifizierungsseiten

Symptom: Die API gibt HTML zurück, das eine Verifizierungsseite oder eine Seite mit Zugriffsverweigerung enthält.

Ursache: Die Zielseite hat die Request als automatisiert erkannt und blockiert.

Lösung: Nutze den Proxy-Endpoint für automatische IP-Rotation:

curl -X POST https://eu.api.foura.ai/api/proxy/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "maxTries": 5,
    "request": {
      "method": "GET",
      "url": "https://example.com/prices",
      "unblocker": true
    }
  }'

Wenn das Problem weiterhin besteht, erhöhe maxTries, um der Proxy-Rotation mehr Versuche zu geben.

Ein vom Ziel zurückgegebener 403-Fehler kommt als HTTP 200 mit status: 403 im Body an. Ein 403 beim Call selbst mit einem X-FourA-Limit-Header ist etwas anderes: siehe 403 Not in Your Plan.

Timeout-Fehler

Symptom: Requests schlagen mit einem Timeout-Fehler fehl.

Ursache: Die Zielseite braucht länger zum Laden als das konfigurierte Timeout.

Lösung: Erhöhe timeout_ms (Standard ist 15s für Single, 30s für Browser, 45s für Proxy):

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://slow-site.com",
    "timeout_ms": 60000
  }'

Prüfe bei Browser-Requests auch, ob dein checkText-Wert tatsächlich auf der Seite vorkommt. Ein Tippfehler lässt den Call mit checkText:<your text> not found fehlschlagen.

403 Not in Your Plan

Symptom: Die API gibt 403 mit einem X-FourA-Limit-Header und einem reason von plan_limit_feature oder plan_limit_premium zurück.

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

Ursache: Dein Plan enthält den aufgerufenen Endpoint oder den gesendeten Parameter nicht. plan_limit_feature deckt einen ausgeschlossenen Endpoint und exitCountries ohne Geo-Targeting ab; plan_limit_premium deckt exitClass: premium ohne Premium-Exits ab. Das Ziel wurde nie kontaktiert und es wurde nichts verbraucht.

Lösung: Entferne den Parameter, rufe einen in deinem Plan enthaltenen Endpoint auf oder führe ein Upgrade durch. Der Tab Limits & Features unter Usage & Limits listet auf, was dein Plan beinhaltet. Wiederhole den Request nicht unverändert: Es ist kein Retry-After gesetzt, da Warten das Ergebnis nicht ändert.

429 Too Many Requests

Symptom: Die API gibt 429 zurück.

Ursache: Eine von zwei Prüfungen hat den Call abgelehnt, und die Response zeigt dir, welche. Wenn sie einen X-FourA-Limit-Header enthält, wurde eines der Limits deines Plans erreicht: gleichzeitige Requests oder Requests pro Minute auf diesem Endpoint, Browser-Requests für den Tag oder die Credits bzw. Bandbreite für den Abrechnungszeitraum. Wenn kein solcher Header vorhanden ist, war das geteilte Minutenkontingent der Plattform für diesen Dienst voll, was am FourA-Traffic liegt und nicht an deinem.

Lösung: Lies zuerst X-FourA-Limit. Warte, wenn das Limit nur Sekunden entfernt ist, und brich ab, wenn dies nicht der Fall ist. Bei Plan-Limits, die sich durch Warten zurücksetzen, stehen die Sekunden im Retry-After-Header und in retry_after_seconds; das geteilte Limit setzt sie in retryAfter:

import time
import requests

# Plan limits that come back in hours or days, not seconds.
STOP_ON = {"plan_limit_browser_daily", "plan_limit_credits", "plan_limit_bandwidth"}

def make_request(endpoint_url, payload, retries=3):
    for i in range(retries):
        resp = requests.post(
            endpoint_url,
            headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
            json=payload
        )
        if resp.status_code == 429:
            limit = resp.headers.get("X-FourA-Limit")
            if limit in STOP_ON:
                raise Exception(f"stopped by {limit}: {resp.json().get('error')}")
            header = resp.headers.get("Retry-After")
            body = resp.json()
            wait = (
                int(header) if header and header.isdigit()
                else body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** i
            )
            time.sleep(wait)
            continue
        return resp
    raise Exception("Rate limit not resolved after retries")

# Example: single request
make_request(
    "https://eu.api.foura.ai/api/single/",
    {"method": "GET", "url": "https://example.com"}
)

Wenn der Header plan_limit_concurrency oder plan_limit_rate enthielt, besteht die Lösung darin, die Anzahl der offenen Aufrufe sowie die Anzahl der pro Minute gestarteten Aufrufe zu begrenzen, anstatt aggressiver zu wiederholen. Das sofortige erneute Senden eines abgelehnten Batches führt dazu, dass der gesamte Batch erneut abgelehnt wird. Abgelehnte Aufrufe zählen nicht zu deinem Limit pro Minute. Wenn sie jedoch weiterhin mit mehr als dem Doppelten dieses Limits eingehen, führen die Ablehnungen zu einem Cooldown: Der 429-Body enthält cooldown: true und fordert dich auf, für 30 Sekunden zu pausieren (retry_after_seconds: 30). Run Requests in Parallel beschreibt das Muster, und unter Usage & Limits im Dashboard siehst du deine Live-Zähler neben deinen Limits.

503 Service Unavailable

Symptom: Die API gibt den Status 503 zurück.

Ursache: Dies geschieht in zwei Fällen:

  1. Der Dienst ist ausgelastet. FourA führt auf dieser Engine bereits so viele Requests gleichzeitig aus, wie maximal zulässig sind, gezählt über den gesamten Traffic und nicht nur deinen. Service at capacity im Feld error. Dies löst sich normalerweise innerhalb von Sekunden auf.
  2. Dienst vorübergehend deaktiviert. Ein Wartungsfenster ist aktiv. Service disabled im Feld error.

Beide Fälle enthalten ein Feld retryAfter in der Response. Keiner von beiden ist ein Plan-Limit: Die Limits deines eigenen Plans antworten immer mit einem X-FourA-Limit-Header bei einem 403 oder 429, niemals mit 503.

Lösung: Warte retryAfter Sekunden und versuche es dann erneut:

import time
import requests

def make_request_with_retry(endpoint_url, payload, retries=3):
    for i in range(retries):
        resp = requests.post(
            endpoint_url,
            headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
            json=payload
        )
        if resp.status_code in (429, 503):
            header = resp.headers.get("Retry-After")
            body = resp.json()
            wait = (
                int(header) if header and header.isdigit()
                else body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** i
            )
            time.sleep(wait)
            continue
        return resp
    raise Exception("Request not resolved after retries")

Ein 503 bei voller Auslastung bedeutet, dass FourA ausgelastet ist. Backoff und Retry sind hier die Lösung. Wenn du stattdessen mit 429 und X-FourA-Limit abgelehnt wirst, liegt das an dir: Reduziere die Anzahl paralleler Requests in deiner Pipeline.

504 Upstream Timeout

Symptom: Die API gibt 504 mit {"error": "Upstream timeout"} zurück.

Ursache: Die Verarbeitung wurde nicht innerhalb des Zeitbudgets abgeschlossen, das du für den Request angegeben hast. Ein langsames Ziel, das Lösen einer Challenge ohne Cache oder eine sehr große Seite können dazu führen. Es liegt nicht an deinem Key, deinen Parametern oder deinem Proxy.

Lösung: Gib dem Aufruf mehr Zeit oder versuche es erneut. FourA wartet die Dauer von timeout_ms plus einer kleinen Marge, eine Erhöhung verlängert die Wartezeit also tatsächlich:

{
  "url": "https://slow-site.com/report",
  "timeout_ms": 90000
}

Für /api/auto/ auf einem geschützten Ziel kann ein erster Cold-Call mehrere zehn Sekunden dauern. Sein timeout_ms deckt die gesamte Kette ab und akzeptiert bis zu 180000.

Wenn /api/auto/ dieses Budget selbst erschöpft, antwortet der Call dennoch mit HTTP 200. Der Body enthält ein error, das mit time budget exhausted beginnt, und status ist gewöhnlich 504 (ein früherer fehlgeschlagener Versuch kann stattdessen seinen eigenen Status dort hinterlassen). Erhöhe timeout_ms oder versuche es erneut.

502 Upstream nicht verfügbar

Symptom: Die API gibt 502 mit {"error": "Upstream unavailable"} oder 503 mit {"error": "Backend service unavailable"} zurück.

Ursache: FourA hat seine eigene Engine erreicht, konnte die Antwort aber nicht verwenden, meist weil eine Instanz neu gestartet wurde.

Lösung: Wiederhole den Request mit einem kurzen Backoff. Beide gelten als service_error, und nur success wird abgerechnet, ein erneuter Versuch kostet dich also nichts extra. Wenn es länger als ein oder zwei Minuten dauert, prüfe die Statusseite.

401 Authentifizierungsfehler

Symptom: Jeder Request gibt 401 Unauthorized zurück.

Checkliste:

  1. Überprüfe, ob der Header X-API-Key: YOUR_API_KEY ist (nicht Authorization: Bearer oder Api-Key)
  2. Prüfe deinen API-Key auf überflüssige Leerzeichen oder Zeilenumbrüche
  3. Erstelle einen neuen Key im Dashboard, falls der aktuelle kompromittiert sein könnte

400 Ziel löst auf eine private oder reservierte IP auf

Symptom: Die API gibt 400 mit Refusing to fetch <target>: target resolves to a private or reserved IP range zurück, bevor der Request FourA verlässt.

Ursache: Deine url löst auf einen privaten, Loopback- oder reservierten IP-Bereich auf (RFC 5735, RFC 6598 oder reservierte IPv6-Blöcke). FourA lehnt diese Ziele ab, damit sein Netzwerk nicht genutzt werden kann, um interne Hosts zu erreichen.

Lösung: Rufe eine öffentliche URL ab. Wenn du testest, nutze ein öffentliches Ziel wie https://example.com oder https://httpbin.org/get. Wenn dein Ziel ein eigener Dienst ist, mache ihn zuerst über einen öffentlichen Hostnamen erreichbar.

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

Ein Hostname, der nicht aufgelöst werden kann, wird nicht abgelehnt. Der Aufruf wird als HTTP 200 mit status: 0 und dem Grund (could not resolve <host>: <reason>) zurückgegeben, wie bei jedem Ziel, das FourA nicht erreichen kann, und wird nicht abgerechnet.

no_eligible_proxy bei der Verwendung von exitCountries

Symptom: Ein /api/proxy/-Aufruf mit exitCountries gibt HTTP 200 mit einem JSON-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
}

Ursache: Der aktuelle Proxy-Pool hat keinen funktionierenden Exit, dessen für das Ziel sichtbares Land mit deiner Allowlist übereinstimmt. FourA weicht niemals auf ein nicht angefordertes Land aus, wenn du exitCountries setzt.

Lösung: Behalte den angeforderten Scope bei und versuche es später erneut. Der Pool wird etwa alle zehn Minuten aktualisiert, sodass ein Land ohne Treffer oft innerhalb einer Stunde wieder verfügbar ist.

import time, requests

def fetch_scoped(url, countries, max_attempts=6, wait_sec=600):
    for _ in range(max_attempts):
        r = requests.post("https://eu.api.foura.ai/api/proxy/",
            headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
            json={"maxTries": 5, "exitCountries": countries,
                  "request": {"method": "GET", "url": url}}).json()
        if r.get("code") == "no_eligible_proxy":
            time.sleep(wait_sec)
            continue
        return r
    raise RuntimeError(f"no eligible exit in {countries} after {max_attempts} attempts")

Erweitere die Länderliste nur, wenn sich die Länderanforderung deines Workflows tatsächlich geändert hat. Stille Fallbacks auf andere Länder können nachgelagerte geo-abhängige Logik beschädigen.

Response-Body wird als Zeichensalat zurückgegeben

Symptom: Die Response data (oder body) enthält Mojibake oder unlesbare Zeichen, wenn das Ziel ein Nicht-UTF-8-Charset verwendet.

Ursache: Standardmäßig decodiert FourA Response-Bodies automatisch nach UTF-8, basierend auf dem Content-Type-Header des Ziels oder einem HTML-<meta charset>-Tag. Wenn das Ziel falsche Angaben zu seinem Charset macht, erhältst du Zeichensalat.

Lösung: Setze für binäre Payloads (Bilder, Protobuf, rohes Audio) returnBuffer: true im Request. Single und Proxy geben data dann als Objekt zurück, das die Rohbytes enthält, {"type": "Buffer", "data": [<byte values>]}, ohne dass eine Charset-Transcodierung angewendet wird.

{
  "method": "GET",
  "url": "https://example.com/image.png",
  "returnBuffer": true
}

Dekodiere die Raw Bytes bei Textzielen selbst, die ihr Charset falsch deklarieren: Rufe den Content mit returnBuffer: true ab, lies die Bytewerte in data.data aus und dekodiere sie mit dem korrekten Charset.

Unerwartetes HTML statt JSON

Symptom: Du hast JSON von der Zielseite erwartet, aber HTML erhalten.

Ursache: Die Zielseite liefert je nach Headers möglicherweise unterschiedliche Inhalte aus.

Lösung: Füge einen Accept Header hinzu und aktiviere unblocker für realistische Browser-Headers:

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://api.example.com/data",
    "headers": [["Accept", "application/json"]],
    "unblocker": true
  }'

Du kannst auch tryJsonData auf true setzen, damit FourA JSON-Antworten automatisch parst.

Der Body ist eine Challenge-Seite, kein Inhalt

Symptom: Der Aufruf war erfolgreich, status ist 200, aber data (oder body) ist eine Bot-Prüfung statt der gewünschten Seite.

Ursache: Das Ziel hat eine Bot-Prüfung durchgeführt, die FourA vorgefunden, aber nicht gelöst hat. Die Response zeigt das an: Single und Proxy geben defense mit solved: false zurück, und Browser gibt defenseSolved: false mit dem Vendor in defenses.present zurück.

Lösung: Prüfe zuerst defense.vendor und eskaliere dann. Versuche ein anderes Browser-Profil auf Single, wechsle zu Proxy für einen anderen Exit oder nutze Browser, damit JavaScript ausgeführt wird. Vollständige Feldreferenz und Vendor-Liste: Site-Checks.

Füge einen validate.data.accept-Substring hinzu, den nur die echte Seite enthält. Eine Challenge-Seite, die FourA erkennt, ist nie ein Erfolg: Sie wird mit einem X-FourA-Check-Page-Header zurückgegeben und nicht abgerechnet. Ohne validate gilt eine nicht erkannte Challenge-Seite mit HTTP 200 als Erfolg, und du bemerkst es erst downstream statt beim Aufruf.

Immer noch blockiert?

Wenn keine der obigen Lösungen hilft:

  1. Prüfe die Statusseite auf laufende Vorfälle
  2. Überprüfe deine Request-Metriken im Dashboard
  3. Kontaktiere den Support unter support@foura.ai mit deinen Request-Details (inklusive der X-FourA-Request-Id aus der fehlgeschlagenen Response)

Nächste Schritte

Aktualisiert: 30. September 2026