> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl-docs-remove-capabilities-from-sidebar.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Errores

> Todos los códigos de error de la API, qué los causa, cómo resolverlos y si se deben reintentar.

Todas las respuestas de error de Firecrawl usan la misma estructura JSON. Busca el valor de `error` (o el código de estado HTTP) en la tabla siguiente para identificar la causa, cómo corregirlo y si es seguro reintentar la solicitud.

<Note>Este catálogo cubre los errores con los que se encontrarán la mayoría de los agentes y clientes. No es exhaustivo: si recibes un error que no aparece aquí, por favor [abre un issue](https://github.com/firecrawl/firecrawl/issues) para que podamos documentarlo.</Note>

<div id="error-response-shape">
  ## Estructura de la respuesta de error
</div>

Todas las respuestas que no son 2xx devuelven JSON con `success: false` en el nivel superior y un `error` de tipo cadena. Algunos endpoints incluyen campos adicionales (`details`, `code`) cuando hay más contexto disponible.

```json theme={null}
{
  "success": false,
  "error": "Unauthorized: Invalid token",
  "details": "Optional structured details (only present on some errors)"
}
```

| Campo | Tipo | Descripción |
| - | - | - |
| `success` | `boolean` | Siempre `false` en caso de error. |
| `error` | `string` | Mensaje de error comprensible para una persona. Úsalo para consultar la fila siguiente. |
| `details` | `any` | Opcional. Errores de validación estructurados por campo, cuando corresponda. |

<div id="errors">
  ## Errores
</div>

| HTTP | `error` (mensaje típico) | Causa | Solución | Reintentable |
| - | - | - | - | - |
| 400 | `Bad Request` / mensaje de validación | El cuerpo de la solicitud no pasó la validación del esquema (faltan campos o son inválidos). | Corrige la carga útil de la solicitud usando la referencia del endpoint. Revisa `details` para identificar los campos. | No |
| 400 | `Invalid URL` | Falta el campo `url`, está mal formado o usa un esquema no compatible. | Proporciona una URL absoluta `http(s)://`. | No |
| 401 | `Unauthorized: Invalid token` | Falta la clave de API, está mal formada o fue revocada. | Envía `Authorization: Bearer fc-...` con una clave válida desde el [dashboard](https://www.firecrawl.dev/app/api-keys). | No |
| 402 | `Payment Required: Insufficient credits` | Los créditos del plan se agotaron o la facturación no está configurada. | Activa el pago por uso o actualiza tu plan. | No |
| 403 | `Forbidden` | La clave no tiene permisos para este endpoint o función. | Usa una clave con el alcance requerido o actualiza el plan que habilita esta función. | No |
| 403 | `SCRAPE_PROMPT_INJECTION_DETECTED` | El modo JSON con `checkPromptInjection: true` detectó un intento de inyección de prompt en el contenido de la página extraída, por lo que se abortó la extracción. | Inspecciona manualmente el contenido de la página. Si es un falso positivo, reintenta sin `checkPromptInjection`. Consulta [Detección de inyección de prompts](/es/features/llm-extract#prompt-injection-detection). | No |
| 404 | `Not Found` | El ID de trabajo, el recurso o la ruta del endpoint no existen. | Verifica el ID del recurso y la URL del endpoint. | No |
| 408 | `Request Timeout` | La página tardó más que el `timeout` de la solicitud en cargarse. | Aumenta `timeout`, simplifica las acciones o usa `fastMode`. | Sí, con backoff |
| 409 | `Conflict` | El recurso está en un estado que impide la operación (p. ej., ya fue eliminado). | Vuelve a consultar el estado y reconcílialo antes de reintentar. | No |
| 413 | `Payload Too Large` | El cuerpo de la solicitud superó el tamaño máximo permitido. | Reduce la carga útil (p. ej., un esquema más corto, menos URL por lote). | No |
| 422 | `Unprocessable Entity` / error de esquema de extracción | El esquema no es un JSON Schema válido o el modelo no pudo generar un resultado conforme. | Valida el esquema; flexibiliza los campos obligatorios; prueba con otro `model`. | A veces |
| 429 | `Rate limit exceeded` | Hay demasiadas solicitudes para el límite por minuto de tu plan. | Espera y reintenta después de los segundos indicados en `Retry-After`. Consulta [Límites de tasa](/es/rate-limits). | Sí, con backoff |
| 429 | `Concurrency limit reached` | Se alcanzó el límite de navegadores concurrentes de tu plan. | Espera a que terminen los trabajos en curso, reduce la concurrencia o actualiza tu plan. | Sí, con backoff |
| 500 | `Internal Server Error` | Error no controlado del lado del servidor. | Reintenta con backoff exponencial. Si persiste, contacta con soporte e indica el ID de la solicitud. | Sí, con backoff |
| 502 | `Bad Gateway` | El proxy upstream o el worker devolvió una respuesta no válida. | Reintenta con backoff. | Sí, con backoff |
| 503 | `Service Unavailable` | El servicio no puede procesar temporalmente la solicitud. | Reintenta con backoff. | Sí, con backoff |
| 504 | `Gateway Timeout` | La solicitud superó el timeout de la puerta de enlace (normalmente en crawls largos). | Usa los endpoints async de crawl/lote y consulta el estado en su lugar. | Sí, con backoff |

Para las respuestas 429, Firecrawl incluye una cabecera `Retry-After` (en segundos) cuando está disponible; espera al menos ese tiempo antes de reintentar.

<div id="agent">
  ## Agent
</div>

Errores específicos de [`/agent`](/es/features/agent) y de sus endpoints de estado, traza, snapshot y cancelación. Los endpoints de traza y snapshot retransmiten sin cambios el cuerpo de error del servicio ascendente, por lo que pueden responder con un cuerpo que omita el campo `success` descrito anteriormente; compruebe el código de estado HTTP y la cadena `error`.

| HTTP | `error` (mensaje típico) | Causa | Solución | Reintentable |
| - | - | - | - | - |
| 400 | `Invalid job ID format. Job ID must be a valid UUID.` | El segmento de ruta `jobId` no es un UUID. | Pase el `id` devuelto por `POST /v2/agent`. | No |
| 400 | `Invalid snapshot ID` | El segmento de ruta `snapshotId` tiene un formato incorrecto. | Use un `snapshotId` de un evento de traza `artifact.updated` [evento de traza](/es/api-reference/endpoint/agent-trace). | No |
| 400 | `Trace is only available for Spark 2 extracts` | El trabajo es anterior a Spark 2, que es el que registra las trazas. | No hay nada que hacer con ese trabajo. Todas las ejecuciones nuevas se realizan en `spark-2` y tienen una traza. | No |
| 400 | `Snapshots are only available for Spark 2 extracts` | El trabajo es anterior a Spark 2, que es el que registra los snapshots. | No hay nada que hacer con ese trabajo. Todas las ejecuciones nuevas se realizan en `spark-2` y tienen snapshots. | No |
| 400 | `Your team has zero data retention enabled. This is not supported on extract.` | No se pueden atender ejecuciones del agente para un equipo que tenga forzada la retención de datos cero. | Contacte con [support@firecrawl.com](mailto:support@firecrawl.com) para habilitar la función para su equipo. | No |
| 404 | `Agent job not found` | El ID de trabajo no existe o pertenece a otro equipo. | Compruebe el ID de trabajo y use una clave del equipo que inició la ejecución. | No |
| 404 | `Snapshot not found` | Ningún snapshot con ese ID pertenece a este trabajo. | Vuelva a obtener la traza y use un `snapshotId` actual de un evento `artifact.updated` [evento de traza](/es/api-reference/endpoint/agent-trace). | No |
| 409 | `Agent already finished` | Se solicitó la cancelación de una ejecución que ya había alcanzado un estado terminal. | Consulte `GET /v2/agent/{jobId}` para obtener el resultado. | No |
| 409 | `Agent is already cancelled` | Se solicitó la cancelación de una ejecución que ya se estaba cancelando. | Consulte `GET /v2/agent/{jobId}`. Una ejecución cancelada informa `failed` con un mensaje de cancelación. | No |
| 500 | `Failed to passthrough agent request.` | El servicio del agente rechazó el trabajo al enviarlo. | Reintente con backoff. Si el problema persiste, contacte con soporte e incluya el ID de solicitud. | Sí, con backoff |

Una ejecución que alcanza su límite de `maxCredits` no devuelve un error HTTP. Finaliza como un trabajo fallido. Consulte el endpoint de estado y obtendrá `status: "failed"` con un mensaje de error por límite de créditos, sin `data` y con `creditsUsed: 0`, ya que las ejecuciones fallidas no se facturan. En la traza, el mismo resultado aparece como un evento `run.finished` con `outcome: "credit_limit_reached"`.

<div id="trace-error-codes">
  ### Códigos de error de la traza
</div>

Los eventos de traza terminales y `error.occurred` contienen un objeto `error` estructurado cuyo `code` puede adoptar uno de cinco valores. Cada uno también incluye un booleano `retryable`, que debes tratar igual que la columna **Reintentable** anterior.

| `code` | Significado y solución |
| - | - |
| `cancelled` | Cancelaste la ejecución. Inicia una nueva cuando quieras repetir el trabajo. |
| `credit_limit_reached` | La ejecución alcanzó el límite de `maxCredits`. Aumenta `maxCredits` o acota el prompt para que la ejecución requiera menos trabajo. |
| `parent_finished` | Un subagente se detuvo porque el agente que lo generó terminó antes. Consulta el evento terminal del agente principal para conocer la causa real. |
| `refused` | El agente rechazó la tarea. Reformula el prompt o acótalo a URL de las que estés autorizado a recopilar datos. |
| `internal` | Se produjo un fallo inesperado durante la ejecución. Reintenta la ejecución; si persiste, contacta con soporte e incluye el ID de trabajo. |

<div id="retry-guidance">
  ## Guía de reintentos
</div>

Toma la columna **Reintentable** como referencia definitiva; no lo deduzcas solo a partir del estado HTTP. El patrón siguiente usa backoff exponencial con jitter y respeta `Retry-After` en respuestas 429.

<CodeGroup>
  ```python Python theme={null}
  import time
  import random
  import requests

  RETRYABLE_STATUSES = {408, 429, 500, 502, 503, 504}

  def request_with_retry(method, url, headers=None, json=None, max_attempts=5):
      for attempt in range(max_attempts):
          resp = requests.request(method, url, headers=headers, json=json)
          if resp.status_code < 400 or resp.status_code not in RETRYABLE_STATUSES:
              return resp
          # Respeta Retry-After cuando esté presente; de lo contrario, usa backoff exponencial con jitter.
          retry_after = resp.headers.get("Retry-After")
          delay = float(retry_after) if retry_after else min(2 ** attempt, 30) + random.random()
          time.sleep(delay)
      return resp
  ```

  ```js Node theme={null}
  const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);

  async function requestWithRetry(url, init = {}, maxAttempts = 5) {
    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      const resp = await fetch(url, init);
      if (resp.ok || !RETRYABLE_STATUSES.has(resp.status)) return resp;
      // Respeta Retry-After cuando esté presente; de lo contrario, usa backoff exponencial con jitter.
      const retryAfter = resp.headers.get('Retry-After');
      const delayMs = retryAfter
        ? Number(retryAfter) * 1000
        : Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000;
      await new Promise((r) => setTimeout(r, delayMs));
    }
  }
  ```

  ```bash cURL theme={null}
  # Bucle simple de shell con backoff exponencial para estados reintentables.
  attempt=0
  max=5
  until response=$(curl -sS -w "\n%{http_code}" -X POST "https://api.firecrawl.dev/v2/scrape" \
      -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"url":"https://example.com"}'); do
    status=$(printf '%s' "$response" | tail -n1)
    case "$status" in
      408|429|500|502|503|504)
        attempt=$((attempt+1))
        [ "$attempt" -ge "$max" ] && break
        sleep $((2 ** attempt))
        ;;
      *) break ;;
    esac
  done
  echo "$response"
  ```
</CodeGroup>

<div id="429-responses">
  ## Respuestas 429
</div>

Las respuestas 429 son el error reintentable más común. Los límites de tasa y de concurrencia por plan se documentan en [Límites de tasa](/es/rate-limits). Respeta siempre la cabecera `Retry-After` cuando esté presente, en lugar de reintentar de inmediato.
