Rate Limit

Mỗi request API FourA đều trải qua ba bước kiểm tra trước khi đến được engine: giới hạn gói của chính bạn, tiếp theo là hạn mức dùng chung của nền tảng cho endpoint bạn đã gọi, sau đó là hạn mức dùng chung của nền tảng cho toàn bộ lưu lượng. Mỗi bước kiểm tra có thể tự từ chối request và mỗi bước sẽ phản hồi với một body khác nhau.

Ba bước kiểm tra theo thứ tự

  1. Giới hạn gói. Những gì gói của chính bạn cho phép: bao gồm các endpoint và tham số nào, bao nhiêu request có thể chạy đồng thời trên mỗi endpoint, bao nhiêu request mỗi phút, bao nhiêu browser request mỗi ngày, cùng với số credit và băng thông khả dụng trong chu kỳ thanh toán.
  2. Giới hạn nền tảng toàn cục. Mọi thứ mà host API bạn gọi đang xử lý tại thời điểm đó, bất kể lưu lượng truy cập tới endpoint nào. Việc từ chối tại đây sẽ trả về "service": "api".
  3. Giới hạn nền tảng theo từng endpoint. Lưu lượng trên dịch vụ single, proxy, hoặc browser mà bạn đã gọi.

Gói của chính bạn được đánh giá đầu tiên, và thứ tự đó là cam kết dịch vụ chứ không phải chi tiết triển khai ngẫu nhiên. Các hạn mức dùng chung là tài nguyên chung, vì vậy một request mà nền tảng chắc chắn sẽ từ chối không được phép tiêu tốn chúng trên đường bị từ chối. Một tài khoản gửi vượt quá mức gói cho phép sẽ bị chặn trước khi nó chạm tới bất kỳ tài nguyên nào mà người khác đang dùng.

Bước kiểm tra 2 và 3 tính tổng lưu lượng của FourA, không phải của bạn. Hãy hiểu việc từ chối từ một trong hai bước này là "FourA đang bận", không phải "bạn đã gửi quá nhiều". Bước kiểm tra 1 chỉ dành riêng cho tài khoản của bạn và không có gì khác trên nền tảng làm thay đổi nó.

Việc từ chối từ một trong hai bước kiểm tra dùng chung sẽ hoàn trả lại tài khoản của bạn toàn bộ những gì đã tính khi tiếp nhận, cả bucket theo phút lẫn slot browser theo ngày, vì request chưa từng đến backend. Nó cũng không tính vào thời gian tạm dừng thử lại được mô tả trong Requests per minute: dung lượng của FourA đã từ chối nó, không phải gói của bạn.

POST /api/auto/ không giữ slot riêng. Các lệnh gọi phụ Single, Proxy và Browser mà nó thực hiện thay bạn đều trải qua cả ba bước kiểm tra như mọi request khác, vì vậy một đợt gọi auto song song sẽ tính vào gói của bạn thông qua các lệnh gọi phụ của nó. (Số lượng request và tỷ lệ thành công của bạn tính chính lệnh gọi auto đó một lần; các lệnh gọi phụ được hiển thị dưới dạng các lần thử của nó.)

Giới hạn gói

Giới hạn gói phản hồi với header X-FourA-Limit chỉ rõ giới hạn nào đã từ chối lệnh gọi. Mã tương tự nằm trong body dưới key reason, do đó bạn có thể phân nhánh xử lý mà không cần đọc header. Mọi body khi chạm giới hạn gói đều chứa error, reason và documentation; các trường còn lại tùy thuộc vào từng loại giới hạn.

X-FourA-Limit Trạng thái Giới hạn bị vượt
plan_limit_feature 403 Endpoint bạn gọi, hoặc tham số exitCountries, không có trong gói của bạn
plan_limit_premium 403 exitClass: premium không có trong gói của bạn
plan_limit_concurrency 429 Số request đồng thời trên endpoint đó
plan_limit_rate 429 Số request mỗi phút trên endpoint đó
plan_limit_browser_daily 429 Số request trình duyệt trong ngày
plan_limit_credits 429 Credit tính phí trong chu kỳ thanh toán
plan_limit_bandwidth 429 Băng thông trong chu kỳ thanh toán

Các con số cụ thể cho từng giới hạn phụ thuộc vào gói của bạn, và tab Limits & Features trong Usage & Limits sẽ liệt kê chúng bên cạnh mức sử dụng trực tiếp. Không hardcode các giá trị này: mỗi phản hồi từ chối đều chứa ngưỡng giới hạn đã từ chối request đó.

Request bị từ chối sẽ không tốn chi phí. Kết quả trả về là rate_limit, và chỉ success mới bị tính phí.

Endpoint hoặc tham số không có trong gói

Mã lỗi 403 với plan_limit_feature nghĩa là lệnh gọi yêu cầu tài nguyên không nằm trong gói. Việc kiểm tra diễn ra trước khi tính toán hạn mức, vì vậy lệnh gọi bị từ chối không ảnh hưởng đến bộ đếm rate limit hoặc bộ đếm hàng ngày của bạn.

{
  "error": "The browser endpoint is not included in your plan (Free). Upgrade to use it.",
  "reason": "plan_limit_feature",
  "documentation": "https://foura.ai/prices"
}

Cùng mã và trạng thái này sẽ phản hồi một lệnh gọi POST /api/proxy/ thiết lập exitCountries trên gói không có định vị geo. Chuỗi error chỉ định rõ tham số:

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

plan_limit_premium có cùng cấu trúc cho exitClass: premium trên gói không có premium exit. FourA có thể phân phát request như vậy từ standard pool và trả về exitClass: standard trong response, vì vậy hãy xử lý cả hai trường hợp. Cả hai đều không tiêu tốn premium exit. Xem exitClass.

Cả hai mã 403 đều không thiết lập Retry-After. Chờ đợi sẽ không làm thay đổi kết quả.

Simultaneous requests

Concurrency được tính theo từng endpoint: gói của bạn có một giới hạn trần cho Single, một cho Proxy và một cho Browser. Request vượt quá giới hạn sẽ trả về 429 cùng Retry-After: 1:

{
  "error": "Concurrency limit reached: your plan allows 50 simultaneous proxy request(s). Retry when an in-flight request finishes.",
  "reason": "plan_limit_concurrency",
  "documentation": "https://foura.ai/prices",
  "limit": 50,
  "in_flight": 51,
  "retry_after_seconds": 1
}

in_flight cũng tính cả request bị từ chối, vì vậy nó sẽ hiển thị nhiều hơn ít nhất một giá trị so với limit.

Cách khắc phục là giới hạn mức độ song song của bạn thay vì thử lại dồn dập hơn. Việc phản hồi lại lỗi 429 bằng cách gửi lại ngay lập tức cùng một batch sẽ tạo ra thêm một lỗi 429 cho mỗi lệnh gọi trong đó. Xem Run Requests in Parallel để biết mô hình mẫu.

Requests per minute

Single và Proxy áp dụng hạn mức theo phút, được đo lường qua một khoảng thời gian một phút trượt (sliding minute). Chỉ các request được chấp nhận mới được tính vào hạn mức: một request bị từ chối sẽ được loại bỏ ra, do đó tài khoản gửi yêu cầu đều đặn vượt nhẹ hạn mức vẫn được phục vụ đúng mức cho phép thay vì bị từ chối gần như toàn bộ.

{
  "error": "Rate limit reached: your plan allows 600 single requests per minute. Cool down and retry.",
  "reason": "plan_limit_rate",
  "documentation": "https://foura.ai/prices",
  "limit_per_minute": 600,
  "current_rate": 613,
  "retry_after_seconds": 17
}

retry_after_seconds là khoảng thời gian cho đến khi một request tiếp theo được chấp nhận, nếu bạn không gửi thêm gì khác ở giữa: tối thiểu 1 giây và tối đa 120 giây. Header Retry-After chứa cùng một giá trị.

Thử lại các request bị từ chối nhanh hơn khoảng thời gian đó sẽ áp dụng một quy tắc riêng. Khi số lượng request bị hạn mức này từ chối trong sliding minute vượt quá hai lần hạn mức, lệnh gọi sẽ bị từ chối với thời gian tạm dừng 30 giây thay thế:

{
  "error": "Rate limit cooldown: 1250 requests over your plan's 600 single requests per minute were refused in the last minute and kept arriving. Pause for 30 seconds.",
  "reason": "plan_limit_rate",
  "documentation": "https://foura.ai/prices",
  "limit_per_minute": 600,
  "current_rate": 540,
  "refused_last_minute": 1250,
  "cooldown": true,
  "retry_after_seconds": 30
}

Các yêu cầu bị từ chối trong thời gian tạm dừng không được tính, do đó trạng thái tạm dừng sẽ tự động kết thúc khi bước sang phút tiếp theo, ngay cả đối với client liên tục thử lại. Để phân biệt trạng thái tạm dừng với định mức thông thường, hãy đọc cooldown thay vì văn bản error.

Yêu cầu Browser mỗi ngày

Browser không có định mức theo phút. Giới hạn gói dịch vụ là số lượng browser request mỗi ngày, được tính từ nửa đêm theo giờ UTC, và bộ đếm sẽ tính mọi browser request được tiếp nhận, không chỉ riêng các yêu cầu thành công.

{
  "error": "Daily browser limit reached: your plan allows 300 browser requests per day (resets at midnight UTC).",
  "reason": "plan_limit_browser_daily",
  "documentation": "https://foura.ai/prices",
  "limit_per_day": 300,
  "used_today": 301
}

Từ chối này không mang header retry_after_seconds và Retry-After, vì thời gian chờ tính bằng giờ thay vì giây. Hãy coi đây là lệnh dừng và lên lịch cho lần chạy tiếp theo vào nửa đêm UTC.

Credit cho kỳ thanh toán

Chỉ tính credit đã tính phí, nghĩa là chỉ các request thành công. Khi tổng số đã tính phí đạt đến giới hạn credit khả dụng của bạn trong kỳ này, các request tiếp theo sẽ bị từ chối cho đến khi kỳ mới được đặt lại hoặc bạn mua thêm.

{
  "error": "Credit limit reached: 75,000 of 75,000 credits used this billing period. Upgrade your plan or wait for the reset.",
  "reason": "plan_limit_credits",
  "documentation": "https://foura.ai/prices",
  "used": 75000,
  "hard_stop": 75000,
  "retry_after_seconds": 86400,
  "resets_at": "2026-10-01T00:00:00.000Z"
}

hard_stop là số lượng credit đã thanh toán mà tại đó các request sẽ dừng lại trong chu kỳ này. Hãy đọc giá trị này từ body thay vì tự tính toán: giá trị đã bao gồm mọi credit bạn đã mua thêm ngoài gói đăng ký.

Băng thông cho chu kỳ thanh toán

Các gói có giới hạn băng thông sẽ từ chối request khi lưu lượng chuẩn trong chu kỳ này đạt mức giới hạn. Lưu lượng premium có hạn mức riêng và không tính vào giới hạn này. Băng thông mua thêm được tính tương tự như băng thông đi kèm trong gói, và chuỗi error biểu thị dung lượng khả dụng cho bạn, không phải chỉ riêng phần bao gồm trong gói.

{
  "error": "Bandwidth limit reached: 50 GB is available to you this billing period.",
  "reason": "plan_limit_bandwidth",
  "documentation": "https://foura.ai/prices",
  "used_bytes": 53687091200,
  "limit_bytes": 53687091200,
  "retry_after_seconds": 86400,
  "resets_at": "2026-10-01T00:00:00.000Z"
}

Đối với cả hai giới hạn chu kỳ, retry_after_seconds được giới hạn tối đa là 24 giờ; resets_at là thời điểm chính xác chu kỳ được làm mới.

Các trường giới hạn gói dịch vụ

Trường Kiểu dữ liệu Xuất hiện ở Mô tả
error string tất cả Thông báo dễ đọc cho người dùng, bao gồm cả số lượng giới hạn áp dụng cho bạn
reason string tất cả plan_limit_ kèm theo tên giới hạn. Cùng giá trị với header X-FourA-Limit.
documentation string tất cả Liên kết đến trang các gói dịch vụ
retry_after_seconds number concurrency, rate, credits, bandwidth Thời gian cần chờ. Cùng giá trị với header Retry-After.
limit number concurrency Số lượng request đồng thời mà gói dịch vụ cho phép trên endpoint đó
in_flight number concurrency Số lượng request đang chạy trên endpoint đó của tài khoản bạn, bao gồm cả request bị từ chối
limit_per_minute number rate Số lượng request mỗi phút mà gói dịch vụ cho phép trên endpoint đó
current_rate number rate Số lượng request được tính trong 1 phút trượt, bao gồm cả request bị từ chối
refused_last_minute number rate pause Số lượng request bị hạn mức mỗi phút từ chối trong 1 phút trượt. Chỉ xuất hiện khi tạm dừng 30 giây.
cooldown boolean rate pause true khi tạm dừng 30 giây do thử lại quá nhanh. Không xuất hiện khi bị từ chối theo phút thông thường.
limit_per_day number browser daily Số lượng browser request mà gói dịch vụ cho phép mỗi ngày
used_today number browser daily Số lượng browser request đã tính trong ngày hôm nay, bao gồm cả request bị từ chối
used number credits Số credit đã tính phí cho đến thời điểm hiện tại trong chu kỳ này
hard_stop number credits Mức credit tính phí mà tại đó các request sẽ bị dừng trong chu kỳ này
used_bytes number bandwidth Lưu lượng truy cập tiêu chuẩn cho đến thời điểm hiện tại trong chu kỳ này, tính bằng byte. Không bao gồm lưu lượng truy cập cao cấp.
limit_bytes number bandwidth Số byte khả dụng trong chu kỳ này
resets_at string credits, bandwidth Dấu thời gian ISO 8601 của thời điểm kết thúc chu kỳ

Giới hạn gói dịch vụ sử dụng retry_after_seconds. Các giới hạn nền tảng bên dưới sử dụng retryAfter. Trình hỗ trợ thử lại (retry helper) cần đọc cả hai, hoặc đọc header Retry-After chỉ do giới hạn gói dịch vụ thiết lập.

Giới hạn nền tảng

Các bước kiểm tra nền tảng theo dõi hai yếu tố trên mỗi dịch vụ và thêm một yếu tố trên toàn bộ hệ thống:

  • Concurrency: số lượng request FourA đang xử lý cùng một thời điểm.
  • RPM: số lượng request FourA đã nhận trong 60 giây qua.

Cả hai bộ đếm đều được chia sẻ giữa mọi người dùng dịch vụ đó. current và limits trong các response bên dưới mô tả trạng thái của nền tảng, không phải của tài khoản bạn. Nếu bạn muốn kiểm tra số lượng của riêng mình, hãy đọc in_flight từ response giới hạn gói dịch vụ, hoặc mở Usage & Limits trong bảng điều khiển.

429: Vượt quá RPM

{
  "error": "Rate limit exceeded",
  "status": 429,
  "service": "single",
  "retryAfter": 5,
  "current": {
    "concurrency": 12,
    "rpm": 3000
  },
  "limits": {
    "maxConcurrency": 500,
    "maxRpm": 3000
  }
}

Dịch vụ đã nhận đủ số lượng request được phép trong một phút qua. Hãy đợi retryAfter giây.

503: Vượt quá giới hạn đồng thời (Concurrency Exceeded)

{
  "error": "Service at capacity",
  "status": 503,
  "service": "proxy",
  "retryAfter": 2,
  "current": {
    "concurrency": 500,
    "rpm": 1200
  },
  "limits": {
    "maxConcurrency": 500,
    "maxRpm": 3000
  }
}

Dịch vụ đang xử lý số lượng request tối đa được phép cùng lúc. Tình trạng này sẽ hết sau vài giây.

Dịch vụ bị vô hiệu hóa

Khi một dịch vụ tạm thời offline để bảo trì, API sẽ trả về mã 503 kèm thông báo lỗi khác:

{
  "error": "Service disabled",
  "status": 503,
  "service": "single",
  "retryAfter": 60,
  "current": { "concurrency": 0, "rpm": 0 },
  "limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}

Đây không phải là rate limit. Dịch vụ tạm thời không khả dụng. Hãy kiểm tra giá trị retryAfter và thử lại sau số giây đó. Tình trạng này thường được xử lý xong trong vài phút.

Cả hai dạng phản hồi 503 đều chứa các key giống nhau, vì vậy hãy rẽ nhánh dựa trên chuỗi error và không bao giờ dựa vào việc các trường nào xuất hiện. Service disabled là bảo trì, Service at capacity là giới hạn đồng thời (concurrency).

Ở dạng phản hồi bảo trì, current.concurrency và current.rpm luôn là 0: request đã bị từ chối trước khi có bất kỳ đo lường nào diễn ra.

Platform Limit Fields

Field Type Description
error string Thông báo lỗi dễ đọc cho người dùng
status number HTTP status code (429 hoặc 503)
service string Dịch vụ đã từ chối lệnh gọi: single, proxy, browser, hoặc api
retryAfter number Thời gian chờ đề xuất tính bằng giây trước khi thử lại
current.concurrency number Số lượng request dịch vụ đang xử lý trên toàn nền tảng khi từ chối
current.rpm number Số lượng request dịch vụ đã nhận trên toàn nền tảng trong 60 giây qua
limits.maxConcurrency number Mức giới hạn đồng thời trên toàn nền tảng của dịch vụ
limits.maxRpm number Mức giới hạn mỗi phút trên toàn nền tảng của dịch vụ

Handling Every Refusal With One Helper

Retry-After được thiết lập trên các giới hạn gói đáng để chờ, retry_after_seconds nằm trong body của chúng, và retryAfter nằm trong body của nền tảng. Hãy đọc cả ba theo thứ tự đó, và dừng lại ở các giới hạn gói mà việc chờ đợi sẽ không thể giải quyết được:

import time
import requests

# Plan limits that a short wait never clears.
STOP_ON = {
    "plan_limit_feature",
    "plan_limit_premium",
    "plan_limit_browser_daily",
    "plan_limit_credits",
    "plan_limit_bandwidth",
}

def wait_seconds(resp, attempt):
    header = resp.headers.get("Retry-After")
    if header and header.isdigit():
        return int(header)
    try:
        body = resp.json()
    except ValueError:
        return 2 ** attempt
    return body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** attempt

def fetch(url, api_key, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.post(
            "https://eu.api.foura.ai/api/single/",
            headers={"X-API-Key": api_key, "Content-Type": "application/json"},
            json={"method": "GET", "url": url},
        )

        limit = resp.headers.get("X-FourA-Limit")
        if limit in STOP_ON:
            raise RuntimeError(f"stopped by plan limit {limit}: {resp.json().get('error')}")

        if resp.status_code in (429, 503):
            time.sleep(wait_seconds(resp, attempt))
            continue

        return resp

    raise RuntimeError("Max retries exceeded")

Hạn mức theo ngày không hồi phục trong nhiều giờ, và hạn mức theo chu kỳ không hồi phục trong nhiều ngày, vì vậy hãy xem chúng là lệnh dừng thay vì trạng thái chờ. Đọc resets_at từ phần body nếu bạn muốn lên lịch cho lần chạy tiếp theo.

Mẹo

  • Giới hạn số lượng request đồng thời đang xử lý thay vì retry một loạt request bị từ chối. Bão retry sẽ biến một lỗi 429 thành nhiều lỗi.
  • Đọc X-FourA-Limit trước. Giá trị này cho bạn biết qua một chuỗi duy nhất xem giới hạn thuộc về bạn hay của nền tảng, và không có sự từ chối nào từ nền tảng thiết lập giá trị này.
  • Không hardcode các con số. Mỗi response chạm giới hạn gói đều chứa mức trần đã từ chối nó, và Usage & Limits hiển thị toàn bộ các giới hạn này.
  • retryAfter trên các giới hạn nền tảng được cố định theo từng loại: 2 giây cho concurrency, 5 giây cho RPM, 60 giây cho bảo trì.
  • Khớp theo error để phân biệt hai loại lỗi 503. Cả hai định dạng đều chứa current và limits, do đó việc kiểm tra "các trường đó có tồn tại không?" sẽ hiểu nhầm việc bảo trì thành vấn đề concurrency.
  • Mã 403 với X-FourA-Limit liên quan đến gói của bạn, không phải về trang đích. Trang đích chưa từng phản hồi.

Cổng Proxy có các thông số riêng

Mọi thông tin phía trên đều áp dụng cho JSON API. Lưu lượng bạn gửi qua proxy.foura.ai áp dụng một bộ thông số gói riêng, với đơn vị khác: số tunnel mở cùng lúc, số lần mở tunnel mỗi phút, và lưu lượng chuẩn cho chu kỳ thanh toán. Những trường hợp từ chối đó trả về dưới dạng HTTP status kèm theo header X-Foura-Error thay vì JSON body, vì CONNECT không có phần body để chứa thông tin. Xem Proxy Port để biết bảng status và How Your Plan Is Metered để biết dung lượng gigabyte của cổng được trừ từ nguồn nào.

Liên quan

Cập nhật: 30 tháng 9, 2026