Encabezados de respuesta

Cada response de la API de FourA incluye un conjunto reducido de custom headers. Resultan útiles para rastreo, soporte, conciliación de facturación y análisis posterior.

Headers que FourA establece

Header Presente en Descripción
X-FourA-Request-Id Cada response de /api/*, incluidos errores y 401, excepto si FourA no puede leer el body en absoluto (400 Invalid JSON in request body, 413), el cual se rechaza antes de asignar un ID Un UUID que identifica este request. Regístralo en tus logs.
X-FourA-Credits Cada response de /api/* que llegó al backend Créditos consumidos en esta llamada. Se devuelve tanto en caso de éxito como de fallo (el trabajo se realizó en ambos casos).
X-FourA-Limit Cada 403 o 429 generado por uno de los límites de tu plan Qué límite rechazó la llamada: plan_limit_ seguido de feature, premium, concurrency, rate, browser_daily, credits o bandwidth.
Retry-After 429 por límite de plan que se resuelven esperando: concurrencia, rate limit, créditos, ancho de banda Segundos de espera, como un número entero. Coincide con retry_after_seconds en el body.
X-FourA-Exit-Class Cada llamada de /api/proxy/ que especificó un exitClass y entregó una página, y cada llamada Single o Browser servida a través de una salida premium premium o standard: la clase de salida que entregó el body. Una llamada Proxy fallida no entregó nada y no incluye este header.
X-FourA-Check-Page Responses de Single, Proxy Finder y Browser cuyo body HTTP 200 es una página de verificación de bots reconocida por FourA El nombre de la página de verificación, por ejemplo amazon-captcha. Dicho request no se factura: consulta Request Outcomes.
Content-Type Cada response Siempre application/json para el envelope. El content-type del destino se devuelve dentro del campo headers del envelope.

X-FourA-Request-Id

Cada llamada a POST /api/auto/, POST /api/single/, POST /api/proxy/ o POST /api/browser/ se etiqueta con un UUID. El header se establece incluso cuando falla la autenticación, lo que te permite correlacionar también las llamadas mal configuradas.

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
X-FourA-Credits: 2
Content-Type: application/json
...

Cuándo usarlo

  • Tickets de soporte: incluye el request ID y podremos encontrar la llamada exacta en nuestros registros.
  • Tus propios logs: almacénalo junto a la línea de log de tu aplicación. Si la queja de un cliente dice "los datos eran incorrectos a las 14:32", puedes reproducir el request exacto.
  • Rastreo en el dashboard: el mismo ID aparece en el Activity feed para las claves que administras, por lo que puedes abrir la fila correspondiente e inspeccionar el request y response capturados.

Ejemplo: registrar en tu lado

import logging
import requests

log = logging.getLogger(__name__)

def fetch(url, api_key):
    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},
    )
    request_id = resp.headers.get("X-FourA-Request-Id", "no-id")
    credits = resp.headers.get("X-FourA-Credits", "0")
    log.info("foura request_id=%s url=%s status=%s credits=%s", request_id, url, resp.status_code, credits)
    resp.raise_for_status()
    return resp.json()
async function fetchPage(url, apiKey) {
  const resp = await fetch('https://eu.api.foura.ai/api/single/', {
    method: 'POST',
    headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
    body: JSON.stringify({ method: 'GET', url })
  });

  const requestId = resp.headers.get('X-FourA-Request-Id') || 'no-id';
  const credits = resp.headers.get('X-FourA-Credits') || '0';
  console.log(`foura request_id=${requestId} url=${url} status=${resp.status} credits=${credits}`);

  return resp.json();
}

X-FourA-Credits

X-FourA-Credits informa el costo en créditos de la llamada que acabas de realizar. Es un medidor, no una factura: el header refleja lo que consumió el trabajo independientemente del resultado. La capa de facturación del dashboard solo contabiliza los resultados facturables contra tu plan (consulta Request Outcomes para saber qué resultados son facturables).

Referencia de costos

Motor Base Con unblocker
Single 1 2
Proxy 2 4
Browser 5 10 (cuando se resolvió una defensa)

/api/auto/ cuenta como una sola request en tu dashboard, con un costo en créditos que es la suma de las subllamadas realizadas internamente (una sola repetición en un objetivo activo puede terminar en 2; una resolución en frío en un sitio difícil puede costar mucho más). El valor de X-FourA-Credits en la response de auto es igual a meta.credits en el body y registra el costo total del proceso.

¿Por qué un header y un campo en el body?

El header es práctico: puedes leerlo antes de procesar el body, registrarlo junto a tu línea de request o sumarlo en múltiples llamadas sin parsear JSON. El campo meta.credits en el body (Auto) o los metadatos por motor (dashboards de Single, Proxy, Browser) contienen el mismo número, pero accesible dentro del envelope de la response.

X-FourA-Limit

X-FourA-Limit aparece solo cuando uno de los límites de tu plan rechazó la llamada. Los rate limits compartidos de la plataforma nunca lo configuran, por lo que el header es la forma más rápida de distinguir entre "mi plan detuvo esto" y "FourA está ocupado" sin necesidad de procesar el body.

HTTP/1.1 429 Too Many Requests
X-FourA-Limit: plan_limit_concurrency
Retry-After: 1
X-FourA-Request-Id: 9f1c4e6c-7b2a-4d3e-8a1f-2c9d8e4a3b15
Content-Type: application/json

Dos de los siete valores devuelven un 403 en lugar de un 429: plan_limit_feature (el endpoint o el parámetro exitCountries no están en tu plan) y plan_limit_premium (exitClass: premium no está en tu plan). Ninguno establece Retry-After, ya que esperar no cambia la respuesta.

STOP_ON = {
    "plan_limit_feature", "plan_limit_premium",
    "plan_limit_browser_daily", "plan_limit_credits", "plan_limit_bandwidth",
}

resp = requests.post(url, headers=headers, json=payload)

limit = resp.headers.get("X-FourA-Limit")
if limit in STOP_ON:
    stop_the_run(limit)                # hours or days away, not seconds
elif limit:
    time.sleep(int(resp.headers.get("Retry-After", 1)))

Los siete valores y los campos del body que acompañan a cada uno están en Rate Limits.

X-FourA-Exit-Class

X-FourA-Exit-Class indica la clase de salida que entregó el body: premium cuando lo hizo una salida premium, standard cuando lo hizo el pool estándar. Aparece en una response de POST /api/proxy/ que entregó una página siempre que la request especificó un exitClass, donde el body incluye el mismo valor, y en una response de Single o Browser siempre que el proxy que fijaste fue una salida premium, donde el body no tiene un campo para ello. Una llamada Proxy fallida no entregó nada, por lo que no incluye ni el header ni el campo.

HTTP/1.1 200 OK
X-FourA-Exit-Class: premium
X-FourA-Credits: 2
X-FourA-Request-Id: 2c1d0f9e-4a7b-4c3e-9d2a-8b1f6e5c4d3a
Content-Type: application/json

El tráfico a través de una salida premium cuenta tanto para tu tráfico premium como para tu ancho de banda total. Se mide en la red e incluye los intentos premium que no devolvieron tu página, por lo que una request respondida con standard aún puede haber consumido algo de tráfico premium en un intento que falló antes de que el pool estándar respondiera. Este header indica la clase que entregó la respuesta, no si se utilizó tráfico premium: la marca premium en una fila de Activity y la página de Usage & Limits muestran lo que se contabilizó. Qué hace exitClass y cuándo se utiliza una salida premium: exitClass.

Cache Behavior

La API no establece Cache-Control ni ETag en las responses. Cada llamada llega al backend. Si necesitas almacenamiento en caché, agrégalo de tu lado.

Target Response Headers

Los headers que devolvió el sitio de destino no están en la response de la API de FourA. Se devuelven dentro del contenedor JSON como el campo headers. Para los endpoints Single y Proxy, este es un array de objetos de header por salto (una entrada por cada paso de redirección). Para el endpoint Browser, es un objeto plano con los headers de la response final.

{
  "status": 200,
  "headers": [
    { "Content-Type": "text/html; charset=utf-8", "Server": "..." }
  ],
  "data": "<!doctype html>...",
  "total_time": 0.42
}

Si necesitas un header de destino específico, léelo desde el campo headers del envelope, no desde la respuesta HTTP de la propia llamada a la API.

Relacionado

Actualizado: 30 de septiembre de 2026