Частые проблемы
Решения наиболее распространенных проблем при использовании FourA API.
Пустой или неполный контент
Симптом: API возвращает статус 200, но поле data пустое или не содержит ожидаемого контента.
Причина: Целевая страница использует JavaScript для рендеринга контента после начальной загрузки страницы.
Решение: Переключитесь с одиночного endpoint на браузерный 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 со страницей проверки или отказа в доступе.
Причина: целевой сайт распознал автоматический request и заблокировал его.
Решение: используйте proxy endpoint для автоматической ротации IP:
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, возвращенная целевым ресурсом, приходит как HTTP 200 с status: 403 внутри тела ответа. Ошибка 403 самого вызова с заголовком X-FourA-Limit, это другой случай: см. 403 Not in Your Plan.
Ошибки таймаута
Симптом: запросы завершаются с ошибкой по таймауту.
Причина: целевая страница загружается дольше настроенного таймаута.
Решение: увеличьте timeout_ms (по умолчанию 15s для single, 30s для browser, 45s для 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
}'
Для запросов из браузера также убедитесь, что значение checkText действительно присутствует на странице. Опечатка приведет к сбою вызова с ошибкой checkText:<your text> not found.
403 Not in Your Plan
Симптом: API возвращает 403 с заголовком X-FourA-Limit и 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 и exitCountries без geo targeting; plan_limit_premium относится к exitClass: premium без premium exits. Обращение к целевому ресурсу не выполнялось, списаний не было.
Решение: удалите параметр, вызовите входящий в тариф endpoint или повысьте тариф. Вкладка Limits & Features на странице Usage & Limits содержит список возможностей вашего тарифа. Не повторяйте запрос без изменений: заголовок Retry-After отсутствует, так как ожидание не изменит результат.
429 Too Many Requests
Симптом: API возвращает 429.
Причина: запрос отклонен одной из двух проверок, и ответ указывает на конкретную причину. Если присутствует заголовок X-FourA-Limit, достигнут один из лимитов вашего тарифа: число одновременных запросов, число запросов в минуту к этому endpoint, дневной лимит запросов Browser либо лимит кредитов или трафика на расчетный период. Если такого заголовка нет, исчерпан общий поминутный лимит платформы для этого сервиса, что связано с общей нагрузкой FourA, а не с вашим трафиком.
Решение: сначала проверьте X-FourA-Limit. Подождите, если до сброса лимита осталось несколько секунд, и остановите запросы, если это не так. Лимиты тарифа, сбрасываемые ожиданием, передают время в секундах в заголовке Retry-After и в 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, решением будет ограничение числа одновременно открытых вызовов и количества запусков в минуту, а не повторные попытки с повышенной частотой. Немедленная повторная отправка отклоненного пакета приведет к его повторному отклонению целиком. Отклоненные вызовы не учитываются в лимите за минуту, но если они продолжают поступать с частотой, превышающей этот лимит более чем в два раза, отказы переходят в режим cooldown: тело ответа 429 содержит cooldown: true и требует сделать паузу на 30 секунд (retry_after_seconds: 30). Паттерн описан в разделе Параллельное выполнение запросов, а раздел Usage & Limits в Dashboard отображает текущие счетчики рядом с вашими лимитами.
503 Service Unavailable
Симптом: API возвращает статус 503.
Причина: Это происходит в двух случаях:
- Сервис перегружен. FourA уже выполняет максимально допустимое количество одновременных запросов на этом движке для суммарного трафика всех пользователей, а не только вашего.
Service at capacityв полеerror. Обычно это проходит за несколько секунд. - Сервис временно отключен. Проводятся технические работы.
Service disabledв полеerror.
В обоих случаях ответ содержит поле retryAfter. Ни один из случаев не связан с лимитом тарифного плана: лимиты вашего тарифа всегда возвращают заголовок X-FourA-Limit со статусом 403 или 429, но никогда с 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 at capacity означает высокую нагрузку на FourA, поэтому решение заключается в паузе (backoff) и повторе запроса. Если возвращается 429 и X-FourA-Limit, ограничение на вашей стороне: уменьшите количество параллельных requests в пайплайне.
504 Upstream Timeout
Симптом: API возвращает 504 с {"error": "Upstream timeout"}.
Причина: Выполнение задачи не уложилось в заданный лимит времени для request. Причиной может быть медленный целевой сервер, холодный запуск решения challenge или слишком тяжелая страница. Это не связано с вашим ключом, параметрами или proxy.
Решение: Увеличьте таймаут вызова или повторите попытку. FourA ожидает в течение вашего timeout_ms плюс небольшой запас, поэтому увеличение значения действительно продлевает ожидание:
{
"url": "https://slow-site.com/report",
"timeout_ms": 90000
}
Для /api/auto/ на защищенном целевом ресурсе первый холодный вызов может занять десятки секунд. Его timeout_ms охватывает всю цепочку и принимает значения до 180000.
Когда у самого /api/auto/ исчерпывается этот лимит времени, вызов все равно возвращает HTTP 200. В теле ответа содержится error, начинающийся с time budget exhausted, а status обычно равен 504 (предыдущая неудавшаяся попытка может оставить вместо него свой статус). Увеличьте timeout_ms или повторите попытку.
502 Upstream Unavailable
Симптом: API возвращает 502 с кодом {"error": "Upstream unavailable"} или 503 с кодом {"error": "Backend service unavailable"}.
Причина: FourA связался со своим движком, но не смог использовать ответ, обычно из-за перезапуска инстанса.
Решение: Повторите запрос с небольшой задержкой. Оба случая классифицируются как service_error, а тарифицируется только success, поэтому повторная попытка не потребует дополнительных затрат. Если проблема длится дольше одной-двух минут, проверьте страницу статуса.
Ошибки аутентификации 401
Симптом: Каждый запрос возвращает 401 Unauthorized.
Чек-лист:
- Убедитесь, что заголовок указан как
X-API-Key: YOUR_API_KEY(а неAuthorization: BearerилиApi-Key) - Проверьте ваш API key на наличие лишних пробелов или символов перевода строки
- Создайте новый ключ в Dashboard, если текущий ключ мог быть скомпрометирован
400 Target Resolves to a Private or Reserved IP
Симптом: API возвращает 400 с кодом Refusing to fetch <target>: target resolves to a private or reserved IP range до того, как запрос покидает FourA.
Причина: Ваш url разрешается в частный, loopback или зарезервированный диапазон IP-адресов (RFC 5735, RFC 6598 или зарезервированные блоки IPv6). 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." }
Хост, имя которого не удается разрешить, не отклоняется. Вызов возвращает HTTP 200 с status: 0 и причиной (could not resolve <host>: <reason>), как и для любой другой цели, недоступной для FourA, и тарификация за него не списывается.
no_eligible_proxy при использовании exitCountries
Симптом: вызов /api/proxy/ с exitCountries возвращает HTTP 200 с JSON оберткой ошибки:
{
"error": "No eligible proxy found for exit countries: CZ, GB",
"code": "no_eligible_proxy",
"details": { "exitCountries": ["CZ", "GB"] },
"total": 0.084
}
Причина: в текущем пуле proxy нет работающих выходных узлов, чья видимая целевым сервером страна совпадает с вашим списком разрешенных. FourA никогда не переключается на незапрошенную страну, если задан exitCountries.
Решение: сохраните запрошенный диапазон и повторите попытку позже. Пул обновляется примерно каждые десять минут, поэтому страна, недоступная сейчас, часто появляется в течение часа.
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")
Расширяйте список стран только в том случае, если требования к стране в вашем рабочем процессе действительно изменились. Скрытые переключения на другие страны могут нарушить логику ниже по цепочке, зависящую от геопозиции.
Тело ответа возвращается в виде нечитаемого текста
Симптом: data (или body) в ответе содержит кракозябры или нечитаемые символы, когда целевой ресурс использует кодировку, отличную от UTF-8.
Причина: По умолчанию FourA автоматически декодирует тело ответа в UTF-8 на основе заголовка Content-Type целевого ресурса или HTML-тега <meta charset>. Если целевой ресурс указывает неверную кодировку, вы получаете нечитаемый текст.
Решение: Для бинарных данных (изображения, protobuf, необработанное аудио) укажите returnBuffer: true в запросе. В этом случае Single и Proxy возвращают data как объект с необработанными байтами, {"type": "Buffer", "data": [<byte values>]}, без применения перекодирования.
{
"method": "GET",
"url": "https://example.com/image.png",
"returnBuffer": true
}
Для текстовых целей с неверно указанной кодировкой декодируйте необработанные байты самостоятельно: выполните fetch с returnBuffer: true, прочитайте значения байтов в data.data, затем декодируйте их с правильной кодировкой.
Неожиданный HTML вместо JSON
Симптом: вы ожидали JSON от целевого сайта, но получили HTML.
Причина: целевая страница может отдавать разный контент в зависимости от заголовков.
Решение: добавьте header 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 responses.
В теле ответа страница проверки, а не контент
Симптом: Вызов прошел успешно, status равен 200, но data (или body) содержит проверку на бота вместо нужной страницы.
Причина: Целевой ресурс запустил проверку на бота, которую FourA встретил, но не смог пройти. В ответе это указано: Single и Proxy возвращают defense с solved: false, а Browser возвращает defenseSolved: false с указанием вендора в defenses.present.
Решение: Сначала проверьте defense.vendor, затем повышайте уровень инструмента. Попробуйте другой профиль браузера в Single, перейдите на Proxy для другого узла выхода или используйте Browser для выполнения JavaScript. Полный справочник полей и список вендоров: Site checks.
Добавьте подстроку validate.data.accept, которая присутствует только на настоящей странице. Страница проверки, распознанная FourA, никогда не считается успешной: она возвращается с заголовком X-FourA-Check-Page и не тарифицируется. Без validate нераспознанная FourA страница проверки, возвращенная с кодом HTTP 200, будет считаться успехом, и вы обнаружите это позже в цепочке обработки, а не в момент вызова.
Проблема не решилась?
Если ни одно из решений не помогло:
- Проверьте страницу статуса на наличие текущих инцидентов
- Просмотрите метрики ваших requests в Dashboard
- Свяжитесь со службой поддержки по адресу support@foura.ai, указав детали request (приложите
X-FourA-Request-Idиз неудавшегося response)
Следующие шаги
- Error Handling: Справочник кодов ошибок API
- Rate Limits: Лимиты тарифных планов и платформы с описанием полей
- Request Outcomes: Как статусы исходов классифицируют результат
- Site checks: Что показывает поле
defense - Choosing the Right Endpoint: Выбор оптимального подхода для целевого ресурса
- Dashboard Overview: Мониторинг ваших requests