Các vấn đề thường gặp

Các giải pháp cho những sự cố phổ biến nhất khi sử dụng FourA API.

Nội dung trống hoặc không đầy đủ

Triệu chứng: API trả về trạng thái 200 nhưng trường data bị trống hoặc thiếu nội dung mong đợi.

Nguyên nhân: Trang đích sử dụng JavaScript để hiển thị nội dung sau lần tải trang ban đầu.

Giải pháp: Chuyển từ endpoint đơn lẻ sang browser endpoint. Sử dụng checkText để xác minh nội dung đã tải:

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

Lưu ý: endpoint trình duyệt trả về nội dung trong trường body (không phải data).

Lỗi 403 Forbidden hoặc các trang CAPTCHA

Triệu chứng: API trả về HTML chứa thử thách CAPTCHA hoặc trang từ chối truy cập.

Nguyên nhân: Trang web đích phát hiện request là tự động và đã chặn nó.

Giải pháp: Sử dụng proxy endpoint để xoay vòng IP tự động:

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

Nếu sự cố vẫn tiếp diễn, hãy tăng maxTries để proxy luân phiên có thêm nhiều lần thử.

Lỗi Timeout

Triệu chứng: Request thất bại với lỗi timeout.

Nguyên nhân: Trang đích mất nhiều thời gian tải hơn timeout đã cấu hình.

Giải pháp: Tăng timeout_ms (mặc định là 15s cho single, 30s cho browser, 45s cho 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
  }'

Đối với các request trình duyệt, hãy cũng xác minh rằng giá trị checkText của bạn thực sự xuất hiện trên trang. Lỗi chính tả sẽ luôn gây ra lỗi timeout.

429 Too Many Requests (Giới hạn RPM)

Triệu chứng: API trả về trạng thái 429 kèm theo thông báo "rate limit exceeded".

Nguyên nhân: Bạn đã vượt quá giới hạn request mỗi phút (RPM). Điều này khác với giới hạn đồng thời (xem 503 bên dưới).

Giải pháp: Sử dụng trường retryAfter từ response để chờ một khoảng thời gian phù hợp trước khi thử lại:

import time
import requests

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:
            body = resp.json()
            wait = body.get("retryAfter", 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"}
)

Kiểm tra mức sử dụng hiện tại của bạn trong Dashboard để xem các rate limit của bạn.

503 Service Unavailable

Triệu chứng: API trả về trạng thái 503.

Nguyên nhân: Điều này xảy ra trong hai trường hợp:

  1. Đạt giới hạn đồng thời. Bạn có quá nhiều request đang chạy cùng lúc. Lỗi này khác với 429, giới hạn số request mỗi phút. Với 503, bạn chưa vượt quá RPM, nhưng bạn đã đạt mức tối đa số request có thể chạy cùng một lúc.
  2. Dịch vụ tạm thời bị vô hiệu hóa. Quá trình bảo trì đang diễn ra.

Cả hai trường hợp đều bao gồm một trường retryAfter trong response.

Giải pháp: Đợi retryAfter giây, sau đó thử lại:

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):
            body = resp.json()
            wait = body.get("retryAfter", 2 ** i)
            time.sleep(wait)
            continue
        return resp
    raise Exception("Request not resolved after retries")

Nếu bạn thường xuyên gặp lỗi 503 concurrency limit, hãy giảm số lượng request song song trong pipeline scraping của bạn, hoặc kiểm tra concurrency limit của gói dịch vụ trong Dashboard.

504 Upstream Timeout

Triệu chứng: API trả về mã 504 với {"error": "Upstream timeout"}.

Nguyên nhân: Công việc không hoàn thành trong khoảng thời gian bạn đã khai báo cho request. Nguyên nhân có thể do target chậm, giải quyết cold challenge hoặc trang quá lớn. Đây không phải là vấn đề với key, tham số hoặc proxy của bạn.

Giải pháp: Tăng thêm thời gian cho request hoặc thử lại. FourA sẽ chờ theo timeout_ms của bạn cộng thêm một khoảng biên nhỏ, do đó việc tăng giá trị này sẽ thực sự kéo dài thời gian chờ:

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

Đối với /api/auto/ trên một mục tiêu được bảo vệ, cuộc gọi đầu tiên (cold call) có thể mất hàng chục giây. timeout_ms của nó bao phủ toàn bộ chuỗi và chấp nhận lên đến 180000.

502 Upstream Unavailable

Triệu chứng: API trả về 502 với {"error": "Upstream unavailable"}, hoặc 503 với {"error": "Backend service unavailable"}.

Nguyên nhân: FourA đã tiếp cận engine của riêng nó nhưng không thể sử dụng phản hồi, thường là do một instance đang khởi động lại.

Giải pháp: Thử lại với thời gian chờ (backoff) ngắn. Cả hai đều được phân loại là service_error, và chỉ success mới bị tính phí, vì vậy việc thử lại không tốn thêm chi phí. Nếu tình trạng kéo dài hơn một hoặc hai phút, hãy kiểm tra trang trạng thái.

Lỗi xác thực 401

Triệu chứng: Mọi request đều trả về 401 Unauthorized.

Danh sách kiểm tra:

  1. Xác minh header là X-API-Key: YOUR_API_KEY (không phải Authorization: Bearer hay Api-Key)
  2. Kiểm tra các khoảng trắng thừa hoặc ký tự xuống dòng trong khóa API của bạn
  3. Tạo một khóa mới từ Dashboard nếu khóa hiện tại có thể bị lộ

400 Mục tiêu phân giải thành IP Private/Reserved

Triệu chứng: API trả về 400 với Target <ip> resolves to a private/reserved IP trước khi request rời khỏi FourA.

Nguyên nhân: url của bạn phân giải thành dải IP private, loopback hoặc reserved (RFC 5735, RFC 6598 hoặc các khối dành riêng cho IPv6). FourA từ chối các mục tiêu này nên mạng của nó không thể được dùng để truy cập các host nội bộ.

Giải pháp: Fetch một URL public. Nếu bạn đang thử nghiệm, hãy sử dụng một mục tiêu public như https://example.com hoặc https://httpbin.org/get. Nếu mục tiêu dự định của bạn là một dịch vụ bạn đang chạy, hãy đưa nó ra public hostname trước.

{ "error": "Target <ip> resolves to a private/reserved IP" }

no_eligible_proxy khi sử dụng exitCountries

Triệu chứng: Yêu cầu /api/proxy/ với exitCountries trả về HTTP 200 kèm theo đối tượng lỗi JSON:

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

Nguyên nhân: Pool proxy hiện tại không có exit nào hoạt động mà quốc gia hiển thị với mục tiêu khớp với allowlist của bạn. FourA không bao giờ chuyển sang một quốc gia không được yêu cầu khi bạn thiết lập exitCountries.

Giải pháp: Giữ nguyên phạm vi được yêu cầu và thử lại sau. Pool được làm mới khoảng mười phút một lần, vì vậy một quốc gia hiện không có kết nối phù hợp thường sẽ có kết nối trong vòng một giờ.

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

Chỉ mở rộng danh sách quốc gia nếu yêu cầu về quốc gia của luồng công việc thực sự thay đổi. Việc âm thầm chuyển dự phòng sang các quốc gia khác có thể phá vỡ logic phụ thuộc vào vị trí địa lý ở các bước sau.

Response Body trả về văn bản bị lỗi hiển thị

Triệu chứng: Response data (hoặc body) chứa các ký tự bị lỗi (mojibake) hoặc không thể đọc được khi máy chủ đích sử dụng charset không phải UTF-8.

Nguyên nhân: Theo mặc định, FourA tự động giải mã response body sang UTF-8 dựa trên header Content-Type của máy chủ đích hoặc thẻ <meta charset> trong HTML. Nếu máy chủ đích khai báo sai về charset của nó, bạn sẽ nhận được văn bản bị lỗi.

Giải pháp: Đối với các payload dạng nhị phân (hình ảnh, protobuf, âm thanh gốc), hãy thiết lập returnBuffer: true trên request. Body sẽ được trả về dưới dạng buffer base64 mà không áp dụng bất kỳ quá trình chuyển mã charset nào.

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

Đối với các mục tiêu văn bản khai báo sai charset, hãy tự giải mã các byte thô: fetch bằng returnBuffer: true, base64-decode, sau đó áp dụng charset chính xác.

HTML không mong muốn thay vì JSON

Triệu chứng: Bạn mong đợi JSON từ trang web mục tiêu nhưng lại nhận được HTML.

Nguyên nhân: Trang mục tiêu có thể trả về nội dung khác nhau dựa trên các header.

Giải pháp: Thêm một header Accept và bật unblocker để có các header trình duyệt thực tế:

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

Bạn cũng có thể đặt tryJsonData thành true để FourA tự động phân tích cú pháp các phản hồi JSON.

Body là một trang Challenge, không phải Content

Triệu chứng: Lời gọi thành công, status là 200, nhưng data (hoặc body) là một bài kiểm tra bot thay vì trang bạn muốn.

Nguyên nhân: Đích đến đã chạy một bài kiểm tra bot mà FourA gặp phải nhưng không thể vượt qua. Phản hồi cho biết: Single và Proxy trả về defense với solved: false, và Browser trả về defenseSolved: false với vendor trong defenses.present.

Giải pháp: Kiểm tra defense.vendor trước, sau đó leo thang. Thử một profile trình duyệt khác trên Single, chuyển sang Proxy cho một exit khác, hoặc sử dụng Browser để JavaScript có thể chạy. Tham chiếu trường đầy đủ và danh sách vendor: Phòng thủ Anti-Bot.

Thêm một chuỗi con validate.data.accept mà chỉ trang thật mới có. Nếu không có nó, một trang challenge được trả về với HTTP 200 sẽ được tính là thành công, và bạn sẽ phát hiện ra điều đó ở giai đoạn sau thay vì ngay tại lời gọi.

Vẫn gặp sự cố?

Nếu không có giải pháp nào ở trên hoạt động:

  1. Kiểm tra trang trạng thái đối với bất kỳ sự cố nào đang diễn ra
  2. Xem lại các số liệu request của bạn trong Bảng điều khiển (Dashboard)
  3. Liên hệ với bộ phận hỗ trợ tại support@foura.ai kèm theo chi tiết request của bạn (bao gồm X-FourA-Request-Id từ phản hồi bị lỗi)

Các bước tiếp theo

Cập nhật: 12 tháng 8, 2026