Ошибки API

Как обрабатывать ошибки API FourA.

Формат ответа об ошибке

API возвращает плоские JSON-объекты для всех ошибок. Вложенный объект error или коды ошибок отсутствуют.

{
  "error": "Invalid API key"
}

Некоторые ошибки содержат дополнительные поля, такие как status, service, retryAfter, current или limits на верхнем уровне:

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

Отслеживание запроса

Каждый ответ API (успешный или с ошибкой) содержит заголовок X-Foura-Request-Id с UUID для этого вызова. Логируйте его на своей стороне. Если вам понадобится спросить поддержку, что произошло с конкретным запросом, этот ID позволит нам найти его.

curl -i -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://example.com"}'
# HTTP/1.1 200 OK
# X-Foura-Request-Id: 9f1c4e6c-7b2a-4d3e-8a1f-2c9d8e4a3b15
# Content-Type: application/json
# ...

Типы ошибок

400: Bad Request

В теле запроса отсутствуют обязательные поля, оно содержит недопустимые значения или указывает целевой ресурс, который API отказывается запрашивать.

{
  "error": "Invalid request body format"
}

Этот же статус 400 также относится к защите от SSRF. Если ваш url разрешается в приватный, локальный (loopback) или иной зарезервированный диапазон IP-адресов (RFC 5735, RFC 6598, зарезервированные блоки IPv6), запрос отклоняется до того, как он покинет сеть FourA:

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

Решение: Убедитесь, что ваш запрос содержит все обязательные поля, URL используют http:// или https://, а хост разрешается в публичный адрес.

401: Unauthorized

Ваш API-ключ отсутствует или недействителен.

Отсутствует ключ:

{
  "error": "Missing API key. Include X-API-Key header."
}

Недействительный ключ:

{
  "error": "Invalid API key"
}

Решение: Проверьте, что ваш заголовок X-API-Key содержит валидный ключ. При необходимости сгенерируйте новый ключ в Dashboard.

429: Rate Limited

Вы отправили слишком много запросов за короткий промежуток времени.

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

Решение: Подождите количество секунд, указанное в retryAfter, перед отправкой новых запросов. Подробности см. в разделе Rate Limits.

500: Server Error

Что-то пошло не так на нашей стороне.

Решение: Повторите запрос после небольшой паузы. Если ошибка повторяется, проверьте страницу статуса или обратитесь в поддержку, указав X-Foura-Request-Id из неудавшегося ответа.

503: Service Disabled or At Capacity

Статус 503 означает, что сервис временно недоступен из-за технического обслуживания либо вы достигли лимита параллельных запросов. Оба ответа содержат поле retryAfter. Вариант с лимитом параллельных запросов также включает current и limits.

{
  "error": "Service disabled",
  "status": 503,
  "retryAfter": 60
}

Решение: Подождите retryAfter секунд, затем повторите попытку. На странице статуса указаны активные периоды технического обслуживания.

Ошибки на стороне целевого ресурса внутри 200 OK

Не каждая ошибка возвращается в виде HTTP-статуса, отличного от 2xx. Когда целевой сайт возвращает HTTP 200 с телом ошибки, FourA все равно передает вам тело ответа, но классифицирует запрос как application_error. Когда целевой сайт возвращает статус, отличный от 2xx, который не принимается вашими правилами validate, результатом становится application_fail, а тело ответа передается без изменений.

Оба случая тарифицируются так, как если бы запрос успешно прошел на сетевом уровне. Полная классификация приведена в справочнике Outcomes.

Кодировка ответа

FourA автоматически декодирует тела ответов в UTF-8. Если целевой ресурс отдает windows-1251, gbk, shift_jis, iso-8859-* или любую другую кодировку, указанную в заголовке Content-Type или HTML-теге <meta charset>, вы получите чистую строку UTF-8 в поле data (single, proxy) или body (browser).

Для бинарных данных (изображения, protobuf, необработанное аудио) установите returnBuffer: true в запросе. Тело ответа вернется в виде буфера base64 без применения перекодирования.

Стратегия повторных попыток

Пример реализации повторных попыток:

import time
import requests

def make_request(url, payload, api_key, max_retries=3):
    for attempt in range(max_retries):
        resp = requests.post(
            url,
            headers={"X-API-Key": api_key, "Content-Type": "application/json"},
            json=payload,
        )
        if resp.status_code == 200:
            return resp.json()

        body = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {}
        retry_after = body.get("retryAfter", 2 ** attempt)
        request_id = resp.headers.get("X-Foura-Request-Id", "?")

        if resp.status_code in (429, 503):
            time.sleep(retry_after)
            continue
        if resp.status_code >= 500:
            time.sleep(2 ** attempt)
            continue

        # 400/401/404 won't fix themselves
        raise RuntimeError(f"{resp.status_code} (request {request_id}): {body.get('error')}")

    raise RuntimeError(f"Exhausted {max_retries} retries")

Дополнительные материалы

Обновлено: 18 июня 2026 г.