よくある問題

FourA APIの使用時によくある問題の解決策です。

コンテンツが空、または不完全

現象: APIはステータス200を返しますが、dataフィールドが空であるか、期待されるコンテンツが含まれていません。

原因: ターゲットページがJavaScriptを使用して、初期ページ読み込み後にコンテンツをレンダリングしています。

解決策: single endpointからbrowser endpointに切り替えます。checkTextを使用してコンテンツが読み込まれたことを確認してください。

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

注意: browser endpoint はコンテンツを body フィールドに返します (data ではありません)。

403 Forbidden または認証ページ

現象: API が認証ページまたはアクセス拒否ページを含む HTML を返す。

原因: ターゲットサイトがリクエストを自動化されたものと検知し、ブロックした。

解決策: 自動 IP ローテーションを利用するには proxy endpoint を使用してください:

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

問題が解決しない場合は、maxTries を増やして proxy ローテーションの試行回数を増やしてください。

ターゲットが返した 403 は、body 内に status: 403 を含む HTTP 200 として返されます。呼び出し自体に対する 403(X-FourA-Limit header 付き)は別のエラーです。詳細は 403 Not in Your Plan を参照してください。

Timeout Errors

症状: request がタイムアウトエラーで失敗します。

原因: ターゲットページの読み込みに、設定されたタイムアウト以上の時間がかかっています。

解決策: timeout_ms を増やしてください(デフォルトは single が 15 秒、browser が 30 秒、proxy が 45 秒):

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

ブラウザリクエストの場合は、checkTextの値が実際にページ上に存在することも確認してください。タイプミスがあると、checkText:<your text> not foundで呼び出しが失敗します。

403 Not in Your Plan

症状: APIがX-FourA-Limitヘッダーとともに403を返し、reasonがplan_limit_featureまたはplan_limit_premiumになります。

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

原因: ご利用のプランには、呼び出した endpoint または送信したパラメータが含まれていません。plan_limit_feature は対象外の endpoint や geo targeting なしの exitCountries に該当し、plan_limit_premium は premium exits なしの exitClass: premium に該当します。ターゲットへの接続は行われず、消費も発生していません。

解決策: パラメータを削除するか、プランに含まれる endpoint を呼び出すか、アップグレードしてください。Usage & Limits の Limits & Features タブに、プランに含まれる内容が記載されています。待機しても結果は変わらないため、Retry-After は設定されておらず、変更なしでの再試行は行わないでください。

429 Too Many Requests

症状: API が 429 を返します。

原因: 2つのチェックのいずれかによって呼び出しが拒絶されました。どちらであるかは response で確認できます。X-FourA-Limit header が含まれている場合、プランの制限(その endpoint での同時 request 数または1分あたりの request 数、1日あたりの Browser request 数、あるいは請求期間のクレジットまたは帯域幅)のいずれかに達しています。この header がない場合は、そのサービスに対するプラットフォーム共有の1分あたりの許容量が上限に達しており、お客様ではなく FourA 全体のトラフィックに起因します。

解決策: まず X-FourA-Limit を確認してください。制限解除まで数秒の場合は待機し、そうでない場合は処理を停止してください。待機で解除されるプラン制限の場合、待機秒数は Retry-After header および retry_after_seconds に格納されます。共有制限の場合は 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"}
)

ヘッダーに plan_limit_concurrency または plan_limit_rate と示されている場合、解決策はリトライを繰り返すことではなく、開いたままにする呼び出し数および1分あたりに開始する呼び出し数を制限することです。拒絶されたバッチをすぐに再送信すると、バッチ全体が再度拒絶されます。拒絶された呼び出しは1分あたりの制限にはカウントされませんが、その制限の2倍以上の頻度で届き続けると、拒絶はクールダウンに移行します。429 の body に cooldown: true が含まれ、30秒間の一時停止(retry_after_seconds: 30)を求められます。リクエストを並列実行 に実装パターンが記載されており、ダッシュボード の Usage & Limits では上限と現在のカウンターを並べて確認できます。

503 Service Unavailable

症状: API が 503 ステータスを返します。

原因: これは次の2つのケースで発生します。

  1. サービスがキャパシティの上限に達している。 FourA が該当エンジンで同時に実行できるリクエスト数の上限に達しています(お客様のトラフィック単体ではなく、全体のトラフィックでカウントされます)。error フィールドに Service at capacity が入ります。通常は数秒で解消します。
  2. サービスが一時的に無効化されている。 メンテナンス期間が進行中です。error フィールドに Service disabled が入ります。

どちらのケースでも、response に retryAfter フィールドが含まれます。いずれもプラン制限ではありません。お客様ご自身のプラン制限では、403 または 429 に X-FourA-Limit ヘッダーが付与されて返され、503 が返されることはありません。

解決策: retryAfter 秒待機してからリトライしてください。

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

キャパシティによる 503 は FourA 側が高負荷であることを示しているため、バックオフして再試行することが唯一の対処法です。代わりに 429 および X-FourA-Limit で拒否されている場合、原因はクライアント側にあります。パイプライン内の並行リクエスト数を減らしてください。

504 Upstream Timeout

症状: API が {"error": "Upstream timeout"} とともに 504 を返します。

原因: リクエストに指定されたタイムバジェット内に処理が完了しませんでした。ターゲットの応答遅延、コールド状態からのチャレンジ解決、または非常に大きなページサイズが原因となります。API キー、パラメータ、プロキシの問題ではありません。

解決策: 呼び出しの制限時間を延ばすか、再試行してください。FourA は指定された timeout_ms にわずかなマージンを加えた時間待機するため、この値を増やすと実際の待機時間が延長されます:

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

保護されたターゲットに対する /api/auto/ では、コールド状態からの初回呼び出しに数十秒かかる場合があります。その timeout_ms は全体のラダーをカバーし、最大 180000 まで指定可能です。

/api/auto/ 自体がそのバジェットを使い切った場合でも、呼び出しは HTTP 200 を返します。本文には time budget exhausted で始まる error が含まれ、status は通常 504 になります(それ以前の失敗した試行のステータスが代わりに残ることもあります)。timeout_ms を増やすか、再試行してください。

502 Upstream Unavailable

症状: API が {"error": "Upstream unavailable"} とともに 502 を返すか、{"error": "Backend service unavailable"} とともに 503 を返します。

原因: FourA は自社エンジンに到達したものの、通常はインスタンスの再起動などが原因で応答を利用できませんでした。

解決策: 短いバックオフを挟んで再試行してください。どちらも service_error として分類され、課金対象は success のみなため、再試行に追加費用はかかりません。問題が 1、2 分以上続く場合は、ステータスページを確認してください。

401 Authentication Errors

症状: すべての request が 401 Unauthorized を返します。

チェックリスト:

  1. header が X-API-Key: YOUR_API_KEY であることを確認します(Authorization: Bearer や Api-Key ではありません)
  2. API key に余分な空白や改行が含まれていないか確認します
  3. 現在のキーが漏洩している可能性がある場合は、ダッシュボードから新しいキーを作成します

400 Target Resolves to a Private or Reserved IP

症状: request が FourA から送信される前に、API が Refusing to fetch <target>: target resolves to a private or reserved IP range とともに 400 を返します。

原因: url がプライベート、ループバック、または予約済み IP 範囲(RFC 5735、RFC 6598、または IPv6 予約ブロック)に解決されます。FourA のネットワークが内部ホストへのアクセスに利用されるのを防ぐため、FourA はこれらのターゲットを拒否します。

解決策: パブリック URL を取得してください。テスト中の場合は、https://example.com や https://httpbin.org/get などのパブリックターゲットを使用してください。対象のターゲットが自身で運用しているサービスの場合は、まずパブリックなホスト名で公開してください。

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

名前解決ができないホスト名は拒否されません。FourAが到達できない他のターゲットと同様に、呼び出しはHTTP 200でstatus: 0および理由(could not resolve <host>: <reason>)を返し、請求対象にはなりません。

exitCountries使用時のno_eligible_proxy

現象: exitCountriesを指定した/api/proxy/の呼び出しが、JSONエラーエンベロープを含むHTTP 200を返します:

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

原因: 現在の proxy プール内に、ターゲットから認識される国が allowlist に一致する有効な exit が存在しません。FourA では、exitCountries を設定した場合に要求されていない国へフォールバックすることはありません。

解決策: 要求されたスコープを維持したまま、後で再試行してください。プールは約10分ごとに更新されるため、現在一致するものがない国でも、通常1時間以内に利用可能になります。

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

ワークフローの国要件が実際に変更された場合にのみ、対象国のリストを広げてください。他の国へのサイレントフォールバックは、後続の地域依存ロジックを破壊する可能性があります。

レスポンスボディが文字化けして返される

症状: ターゲットが非UTF-8文字セットを使用している場合、レスポンスのdata(またはbody)に文字化けや判読不能な文字が含まれる。

原因: デフォルトでは、FourAはターゲットのContent-TypeヘッダーまたはHTMLの<meta charset>タグに基づいて、レスポンスボディをUTF-8に自動デコードします。ターゲットが文字セットについて不正確な情報を返している場合、テキストが文字化けします。

解決策: バイナリペイロード(画像、protobuf、rawオーディオなど)の場合は、リクエストでreturnBuffer: trueを設定します。これにより、SingleおよびProxyは文字セットの変換を行わずに、rawバイトを保持するオブジェクトとしてdata({"type": "Buffer", "data": [<byte values>]})を返します。

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

文字コードを誤って宣言しているテキストターゲットの場合は、rawバイトを独自にデコードしてください。returnBuffer: trueで取得し、data.dataのバイト値を読み取ってから、正しい文字コードでデコードします。

JSONではなく予期しないHTMLが返される

症状: ターゲットサイトからJSONを期待していたが、HTMLが返された。

原因: ターゲットページがヘッダーに基づいて異なるコンテンツを返している可能性があります。

解決策: Acceptヘッダーを追加し、unblockerを有効にしてリアルなブラウザヘッダーを送信します:

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

また、tryJsonData を true に設定すると、FourA が JSON レスポンスを自動的にパースします。

ボディがコンテンツではなくチャレンジページになる

症状: 呼び出しは成功し、status は 200 ですが、data(または body)が目的のページではなくボットチェックになっています。

原因: ターゲットがボットチェックを実行し、FourA が到達したもののクリアできませんでした。レスポンスにその旨が示されます。Single および Proxy は defense と solved: false を返し、Browser は defenseSolved: false を返し、ベンダー名を defenses.present に含めます。

解決策: まず defense.vendor を確認し、必要に応じてエスカレーションします。Single で別のブラウザプロファイルを試す、Proxy に移行して別の出口を使用する、または JavaScript が実行される Browser を使用します。完全なフィールドリファレンスとベンダーリスト: サイトチェック。

実際のページにのみ存在する validate.data.accept 部分文字列を追加します。FourA が認識したチェックページは成功として扱われません。X-FourA-Check-Page ヘッダー付きで返され、課金対象外となります。validate がないと、FourA が認識できない HTTP 200 で返されたチェックページが成功としてカウントされ、呼び出し時ではなくダウンストリームで発覚することになります。

解決しない場合

上記の解決策で問題が解決しない場合:

  1. ステータスページ で進行中のインシデントを確認する
  2. ダッシュボード でリクエストのメトリクスを確認する
  3. リクエストの詳細(失敗したレスポンスの X-FourA-Request-Id を含む)を添えて support@foura.ai までサポートにお問い合わせください

次のステップ

最終更新日: 2026年9月30日