> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl-claude-eager-dijkstra-dne9il.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP

> El SDK de PHP de Firecrawl es un wrapper de la API de Firecrawl que te ayuda a convertir sitios web en markdown fácilmente.

<div id="installation">
  ## Instalación
</div>

El SDK oficial de PHP se mantiene en el monorepo de Firecrawl, en [apps/php-sdk](https://github.com/firecrawl/firecrawl/tree/main/apps/php-sdk).

Para instalar el SDK de PHP de Firecrawl, añade la dependencia con Composer:

```bash theme={null}
composer require firecrawl/firecrawl-sdk
```

<Note>Requiere PHP 8.1 o superior.</Note>

<div id="laravel-integration">
  ### Integración con Laravel
</div>

El SDK incluye soporte nativo para Laravel con autodetección. Después de instalar el paquete, publica el archivo de configuración:

```bash theme={null}
php artisan vendor:publish --provider="Firecrawl\Laravel\FirecrawlServiceProvider"
```

A continuación, agrega tu clave de API al archivo `.env`:

```env theme={null}
FIRECRAWL_API_KEY=fc-your-api-key
```

Se admiten las siguientes variables de entorno:

| Variable                   | Predeterminado              | Descripción                                        |
| -------------------------- | --------------------------- | -------------------------------------------------- |
| `FIRECRAWL_API_KEY`        | —                           | Tu clave de API de Firecrawl (obligatoria)         |
| `FIRECRAWL_API_URL`        | `https://api.firecrawl.dev` | URL base de la API                                 |
| `FIRECRAWL_TIMEOUT`        | `300`                       | Tiempo de espera de la solicitud HTTP, en segundos |
| `FIRECRAWL_MAX_RETRIES`    | `3`                         | Reintentos automáticos para fallos transitorios    |
| `FIRECRAWL_BACKOFF_FACTOR` | `0.5`                       | Factor de retroceso exponencial, en segundos       |

<div id="usage">
  ## Uso
</div>

1. Obtén una clave de API en [firecrawl.dev](https://firecrawl.dev)
2. Configura la clave de API como una variable de entorno llamada `FIRECRAWL_API_KEY`, o pásala con `FirecrawlClient::create(apiKey: ...)`

Aquí tienes un ejemplo rápido con la API actual del SDK:

```php theme={null}
use Firecrawl\Client\FirecrawlClient;
use Firecrawl\Models\CrawlOptions;
use Firecrawl\Models\ScrapeOptions;

$client = FirecrawlClient::fromEnv();

$doc = $client->scrape(
    'https://firecrawl.dev',
    ScrapeOptions::with(formats: ['markdown'])
);

$crawl = $client->crawl(
    'https://firecrawl.dev',
    CrawlOptions::with(limit: 5)
);

echo $doc->getMarkdown();
echo 'Crawled pages: ' . count($crawl->getData());
```

<div id="using-the-laravel-facade">
  ### Uso del facade de Laravel
</div>

En una aplicación de Laravel, puedes utilizar el facade `Firecrawl` o la inyección de dependencias:

```php theme={null}
use Firecrawl\Client\FirecrawlClient;
use Firecrawl\Laravel\Facades\Firecrawl;

// Vía Facade
$doc = Firecrawl::scrape('https://example.com');

// Vía inyección de dependencias
class ScrapeController
{
    public function __construct(
        private readonly FirecrawlClient $firecrawl,
    ) {}

    public function index()
    {
        $doc = $this->firecrawl->scrape('https://example.com');
        return response()->json(['markdown' => $doc->getMarkdown()]);
    }
}
```

<div id="scraping-a-url">
  ### Scraping de una URL
</div>

Para hacer scraping de una sola URL, usa el método `scrape`.

```php theme={null}
use Firecrawl\Models\Document;
use Firecrawl\Models\ScrapeOptions;

$doc = $client->scrape(
    'https://firecrawl.dev',
    ScrapeOptions::with(
        formats: ['markdown', 'html'],
        onlyMainContent: true,
        waitFor: 5000,
    )
);

echo $doc->getMarkdown();
echo $doc->getMetadata()['title'] ?? '';
```

<div id="json-extraction">
  #### Extracción JSON
</div>

Extrae JSON estructurado con `JsonFormat` mediante el endpoint `scrape`:

```php theme={null}
use Firecrawl\Models\JsonFormat;
use Firecrawl\Models\ScrapeOptions;

$jsonFmt = JsonFormat::with(
    prompt: 'Extract the product name and price',
    schema: [
        'type' => 'object',
        'properties' => [
            'name' => ['type' => 'string'],
            'price' => ['type' => 'number'],
        ],
    ],
);

$doc = $client->scrape(
    'https://example.com/product',
    ScrapeOptions::with(formats: [$jsonFmt])
);

print_r($doc->getJson());
```

<div id="crawling-a-website">
  ### Rastreo de un sitio web
</div>

Para rastrear un sitio web y esperar a que finalice, usa `crawl`.

```php theme={null}
use Firecrawl\Models\CrawlOptions;
use Firecrawl\Models\ScrapeOptions;

$job = $client->crawl(
    'https://firecrawl.dev',
    CrawlOptions::with(
        limit: 50,
        maxDiscoveryDepth: 3,
        scrapeOptions: ScrapeOptions::with(formats: ['markdown']),
    )
);

echo 'Status: ' . $job->getStatus();
echo 'Progress: ' . $job->getCompleted() . '/' . $job->getTotal();

foreach ($job->getData() as $page) {
    echo $page->getMetadata()['sourceURL'] ?? '';
}
```

<div id="start-a-crawl">
  ### Iniciar un rastreo
</div>

Inicia un trabajo sin esperar con `startCrawl`.

```php theme={null}
use Firecrawl\Models\CrawlOptions;

$start = $client->startCrawl(
    'https://firecrawl.dev',
    CrawlOptions::with(limit: 100)
);

echo 'Job ID: ' . $start->getId();
```

<div id="checking-crawl-status">
  ### Consultar el estado del rastreo
</div>

Consulta el progreso del rastreo con `getCrawlStatus`.

```php theme={null}
$status = $client->getCrawlStatus($start->getId());
echo 'Status: ' . $status->getStatus();
echo 'Progress: ' . $status->getCompleted() . '/' . $status->getTotal();
```

<div id="cancelling-a-crawl">
  ### Cancelar un rastreo
</div>

Cancela un rastreo en curso con `cancelCrawl`.

```php theme={null}
$result = $client->cancelCrawl($start->getId());
print_r($result);
```

<div id="crawl-errors">
  ### Errores de rastreo
</div>

Consulta los errores del rastreo (si los hay) con `getCrawlErrors`.

```php theme={null}
$errors = $client->getCrawlErrors($start->getId());
print_r($errors);
```

<div id="mapping-a-website">
  ### Mapeo de un sitio web
</div>

Descubre enlaces de un sitio utilizando `map`.

```php theme={null}
use Firecrawl\Models\MapOptions;

$data = $client->map(
    'https://firecrawl.dev',
    MapOptions::with(
        limit: 100,
        search: 'blog',
    )
);

foreach ($data->getLinks() as $link) {
    echo ($link['url'] ?? '') . ' - ' . ($link['title'] ?? '');
}
```

<div id="searching-the-web">
  ### Buscar en la Web
</div>

Realiza una búsqueda con ajustes de búsqueda opcionales utilizando `search`.

```php theme={null}
use Firecrawl\Models\SearchOptions;

$results = $client->search(
    'firecrawl web scraping',
    SearchOptions::with(limit: 10)
);

foreach ($results->getWeb() as $result) {
    echo ($result['title'] ?? '') . ' - ' . ($result['url'] ?? '');
}
```

<div id="batch-scraping">
  ### Scraping por lotes
</div>

Realiza scraping de varias URL en paralelo con `batchScrape`.

```php theme={null}
use Firecrawl\Models\BatchScrapeOptions;
use Firecrawl\Models\ScrapeOptions;

$job = $client->batchScrape(
    ['https://firecrawl.dev', 'https://firecrawl.dev/blog'],
    BatchScrapeOptions::with(
        options: ScrapeOptions::with(formats: ['markdown']),
    )
);

foreach ($job->getData() as $doc) {
    echo $doc->getMarkdown();
}
```

Para controlar manualmente la ejecución asíncrona, usa `startBatchScrape`, `getBatchScrapeStatus` y `cancelBatchScrape`:

```php theme={null}
use Firecrawl\Models\BatchScrapeOptions;
use Firecrawl\Models\ScrapeOptions;

$start = $client->startBatchScrape(
    ['https://firecrawl.dev', 'https://firecrawl.dev/blog'],
    BatchScrapeOptions::with(
        options: ScrapeOptions::with(formats: ['markdown']),
    )
);

$status = $client->getBatchScrapeStatus($start->getId());
echo 'Batch status: ' . $status->getStatus();

$cancel = $client->cancelBatchScrape($start->getId());
print_r($cancel);
```

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

Ejecuta un agente con IA mediante `agent`.

```php theme={null}
use Firecrawl\Models\AgentOptions;

$result = $client->agent(
    AgentOptions::with(
        prompt: 'Find the pricing plans for Firecrawl and compare them',
    )
);

print_r($result->getData());
```

Con un esquema JSON para una salida estructurada:

```php theme={null}
use Firecrawl\Models\AgentOptions;

$result = $client->agent(
    AgentOptions::with(
        prompt: 'Extract pricing plan details',
        urls: ['https://firecrawl.dev'],
        schema: [
            'type' => 'object',
            'properties' => [
                'plans' => [
                    'type' => 'array',
                    'items' => [
                        'type' => 'object',
                        'properties' => [
                            'name' => ['type' => 'string'],
                            'price' => ['type' => 'string'],
                        ],
                    ],
                ],
            ],
        ],
    )
);

print_r($result->getData());
```

Para controlar manualmente la ejecución asíncrona, usa `startAgent`, `getAgentStatus` y `cancelAgent`:

```php theme={null}
use Firecrawl\Models\AgentOptions;

$start = $client->startAgent(
    AgentOptions::with(
        prompt: 'Summarize what Firecrawl does in one sentence',
        urls: ['https://firecrawl.dev'],
    )
);

$status = $client->getAgentStatus($start->getId());
echo 'Agent status: ' . $status->getStatus();

$cancel = $client->cancelAgent($start->getId());
print_r($cancel);
```

<div id="usage-metrics">
  ### Uso & métricas
</div>

Consulta la concurrencia y los créditos restantes:

```php theme={null}
use Firecrawl\Models\ConcurrencyCheck;
use Firecrawl\Models\CreditUsage;

$concurrency = $client->getConcurrency();
echo 'Concurrency: ' . $concurrency->getConcurrency() . '/' . $concurrency->getMaxConcurrency();

$credits = $client->getCreditUsage();
echo 'Remaining credits: ' . $credits->getRemainingCredits();
```

<div id="laravel-ai-sdk-tools">
  ## Herramientas de Laravel AI SDK
</div>

El SDK incluye clases de herramientas nativas para el [Laravel AI SDK](https://laravel.com/docs/ai-sdk) (`laravel/ai`), de modo que los agentes puedan hacer scraping, buscar, mapear y rastrear la web sin un MCP Server ni llamadas HTTP manuales.

```bash theme={null}
composer require laravel/ai
```

<Note>Requiere `firecrawl/firecrawl-sdk` 1.9.0 o posterior, además de `laravel/ai` 0.9 o posterior (PHP 8.3+, Laravel 12+). Las clases de las herramientas solo se cargan cuando `laravel/ai` está instalado.</Note>

Las herramientas resuelven `FirecrawlClient` desde el contenedor, por lo que se reutiliza tu configuración actual de `config/firecrawl.php` y `FIRECRAWL_API_KEY` tal cual:

```php theme={null}
use Firecrawl\Laravel\Tools\FirecrawlScrape;
use Firecrawl\Laravel\Tools\FirecrawlSearch;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;
use Stringable;

class ResearchAssistant implements Agent, HasTools
{
    use Promptable;

    public function instructions(): Stringable|string
    {
        return 'You are a research assistant. Use the Firecrawl tools to find and read web content.';
    }

    public function tools(): iterable
    {
        return [
            new FirecrawlScrape,
            new FirecrawlSearch,
        ];
    }
}

$response = ResearchAssistant::make()->prompt('What does firecrawl.dev do?');
```

<div id="available-tools">
  ### Herramientas disponibles
</div>

| Clase             | Nombre de la herramienta | Qué hace                                            |
| ----------------- | ------------------------ | --------------------------------------------------- |
| `FirecrawlScrape` | `firecrawl_scrape`       | Hace scraping de una URL y devuelve markdown limpio |
| `FirecrawlSearch` | `firecrawl_search`       | Busca en la web y devuelve resultados en JSON       |
| `FirecrawlMap`    | `firecrawl_map`          | Descubre las URL de un sitio web                    |
| `FirecrawlCrawl`  | `firecrawl_crawl`        | Rastrea varias páginas y las convierte en markdown  |

Los nombres de las herramientas coinciden con los del Firecrawl MCP server, por lo que los agentes ven la misma terminología en todas las interfaces. Registra las cuatro a la vez con el helper spread:

```php theme={null}
use Firecrawl\Laravel\Tools\FirecrawlTools;

public function tools(): iterable
{
    return [...FirecrawlTools::all()];
}
```

Cada herramienta también acepta un cliente explícito, para credenciales puntuales o para usarlo fuera del contenedor. `FirecrawlTools::all()` se lo pasa a las cuatro herramientas:

```php theme={null}
use Firecrawl\Client\FirecrawlClient;

$client = FirecrawlClient::create(apiKey: 'fc-other-key');

new FirecrawlScrape($client);
// o
FirecrawlTools::all($client);
```

<div id="tool-parameters">
  ### Parámetros de las herramientas
</div>

Cada herramienta expone un esquema pequeño pensado para el modelo. Estos son los parámetros que el agente puede proporcionar:

| Herramienta        | Parámetro             | Descripción                                                                       |
| ------------------ | --------------------- | --------------------------------------------------------------------------------- |
| `firecrawl_scrape` | `url` (obligatorio)   | URL absoluta de la página a la que se le hará scraping, incluido el protocolo     |
| `firecrawl_search` | `query` (obligatorio) | La consulta de búsqueda                                                           |
|                    | `limit`               | Número máximo de resultados que se devolverán, 1–20. El valor predeterminado es 5 |
| `firecrawl_map`    | `url` (obligatorio)   | URL base del sitio web que se va a mapear                                         |
|                    | `search`              | Término opcional para filtrar las URL descubiertas por relevancia                 |
|                    | `limit`               | Número máximo de URL que se devolverán, 1–500. El valor predeterminado es 100     |
| `firecrawl_crawl`  | `url` (obligatorio)   | URL desde la que iniciar el rastreo                                               |
|                    | `limit`               | Número máximo de páginas que se rastrearán, 1–25. El valor predeterminado es 5    |

Los valores de `limit` fuera de rango se ajustan al límite más cercano en lugar de rechazarse, por lo que un modelo que solicite 99 resultados de búsqueda recibirá 20 en lugar de un error.

<div id="tool-behavior">
  ### Comportamiento de la herramienta
</div>

Los fallos de la herramienta, como límites de tasa, tiempos de espera y URL no válidas, se devuelven al modelo como cadenas de error legibles en lugar de generar excepciones, para que las ejecuciones del agente sigan funcionando de forma controlada. Las salidas se limitan para mantenerse dentro del contexto del modelo: los resultados de scraping se truncan a 80.000 caracteres, las páginas de rastreo a 15.000 caracteres cada una dentro de un presupuesto total de 100.000 caracteres por resultado completo, y los resultados de search y mapeo eliminan los elementos del final con un marcador explícito de omisión.

`firecrawl_search` y `firecrawl_map` devuelven arrays JSON de resultados. `firecrawl_scrape` devuelve la página en markdown.

<div id="crawl-results">
  ### Resultados del rastreo
</div>

`firecrawl_crawl` espera hasta 55 segundos a que termine el rastreo y luego devuelve un objeto JSON que deja explícito el resultado. Los rastreos fallidos, cancelados o parciales siguen siendo visibles para el modelo a través del campo `status`, en lugar de truncarse sin avisar:

```json theme={null}
{
  "status": "completed",
  "completed": 5,
  "total": 5,
  "pages": [
    { "url": "https://example.com/docs", "markdown": "..." }
  ]
}
```

Aparecen dos campos opcionales cuando los resultados no caben: `omittedPages` cuenta las páginas omitidas para mantenerse dentro del presupuesto de salida, y `note` le indica al modelo que existen más páginas en el servidor y que debe usar un límite más bajo o hacer scraping de páginas específicas con `firecrawl_scrape`. La herramienta informa sobre la paginación en lugar de seguirla, por lo que los agentes que necesitan todas las páginas de un rastreo grande deben usar `FirecrawlClient` directamente.

Si el rastreo sigue en ejecución cuando expira la espera, la herramienta lo indica y le recuerda al modelo que el rastreo aún puede completarse del lado del servidor. Los inicios de rastreo incluyen una clave de idempotencia UUID, por lo que un reintento a nivel HTTP nunca crea un rastreo duplicado.

Si tu agente se ejecuta dentro de un trabajo en cola, mantén pequeño el límite del rastreo o aumenta el timeout del trabajo del worker. La espera, la frecuencia de poll y el límite por página son propiedades protegidas, así que extiende la clase para ajustarlas:

```php theme={null}
use Firecrawl\Laravel\Tools\FirecrawlCrawl;

class PatientCrawl extends FirecrawlCrawl
{
    protected int $timeoutSeconds = 120;
    protected int $pollIntervalSeconds = 5;
    protected int $pageCharacterLimit = 30000;
}
```

<div id="browser">
  ## Browser
</div>

El SDK de PHP incluye funciones auxiliares para Browser Sandbox.

<div id="create-a-session">
  ### Crear una sesión
</div>

```php theme={null}
use Firecrawl\Models\BrowserCreateResponse;

$session = $client->browser(ttl: 120, activityTtl: 60, streamWebView: true);
echo $session->getId();
echo $session->getCdpUrl();
echo $session->getLiveViewUrl();
```

<div id="execute-code">
  ### Ejecutar código
</div>

```php theme={null}
use Firecrawl\Models\BrowserExecuteResponse;

$run = $client->browserExecute(
    sessionId: $session->getId(),
    code: 'await page.goto("https://example.com"); console.log(await page.title());',
    language: 'node',
    timeout: 60,
);

echo $run->getStdout();
echo $run->getExitCode();
```

<div id="scrape-bound-interactive-session">
  ### Sesión interactiva vinculada al scraping
</div>

Usa un ID de trabajo de scraping para ejecutar código adicional del navegador en el mismo contexto reproducido:

* `interact(...)` ejecuta código en la sesión de navegador vinculada al scraping (y la inicializa la primera vez que se usa).
* `stopInteractiveBrowser(...)` detiene explícitamente la sesión interactiva cuando hayas terminado.

```php theme={null}
use Firecrawl\Models\BrowserExecuteResponse;
use Firecrawl\Models\BrowserDeleteResponse;
use Firecrawl\Models\ScrapeOptions;

$doc = $client->scrape(
    'https://example.com',
    ScrapeOptions::with(formats: ['markdown'])
);

$scrapeJobId = $doc->getMetadata()['scrapeId'] ?? null;
if ($scrapeJobId === null) {
    throw new RuntimeException('scrapeId not found in metadata');
}

$scrapeRun = $client->interact(
    jobId: $scrapeJobId,
    code: 'console.log(page.url());',
    language: 'node',
    timeout: 60,
);

echo $scrapeRun->getStdout();

$deleted = $client->stopInteractiveBrowser($scrapeJobId);
echo 'Deleted: ' . ($deleted->isSuccess() ? 'true' : 'false');
```

<div id="list-close-sessions">
  ### Listar & cerrar sesiones
</div>

```php theme={null}
use Firecrawl\Models\BrowserListResponse;
use Firecrawl\Models\BrowserSession;

$active = $client->listBrowsers('active');
foreach ($active->getSessions() as $s) {
    echo $s->getId() . ' - ' . $s->getStatus();
}

$closed = $client->deleteBrowser($session->getId());
echo 'Closed: ' . ($closed->isSuccess() ? 'true' : 'false');
```

<div id="configuration">
  ## Configuración
</div>

`FirecrawlClient::create()` admite las siguientes opciones:

| Opción           | Tipo                         | Predeterminado                                      | Descripción                                       |
| ---------------- | ---------------------------- | --------------------------------------------------- | ------------------------------------------------- |
| `apiKey`         | `string`                     | variable de entorno `FIRECRAWL_API_KEY`             | Tu clave de API de Firecrawl                      |
| `apiUrl`         | `string`                     | `https://api.firecrawl.dev` (o `FIRECRAWL_API_URL`) | URL base de la API                                |
| `timeoutSeconds` | `float`                      | `300`                                               | Tiempo de espera de la solicitud HTTP en segundos |
| `maxRetries`     | `int`                        | `3`                                                 | Reintentos automáticos para fallos transitorios   |
| `backoffFactor`  | `float`                      | `0.5`                                               | Factor de retroceso exponencial en segundos       |
| `httpClient`     | `GuzzleHttp\ClientInterface` | Se crea a partir del tiempo de espera               | Cliente HTTP personalizado compatible con Guzzle  |

```php theme={null}
use Firecrawl\Client\FirecrawlClient;

$client = FirecrawlClient::create(
    apiKey: 'fc-your-api-key',
    apiUrl: 'https://api.firecrawl.dev',
    timeoutSeconds: 300,
    maxRetries: 3,
    backoffFactor: 0.5,
);
```

<div id="custom-http-client">
  ### Cliente HTTP personalizado
</div>

Puedes pasar una implementación preconfigurada de `GuzzleHttp\ClientInterface` para controlar el pool de conexiones, el middleware, la configuración del proxy y otras funciones HTTP. Si se proporciona, la configuración `timeoutSeconds` se ignora y se utiliza la configuración del propio cliente.

```php theme={null}
use Firecrawl\Client\FirecrawlClient;
use GuzzleHttp\Client as GuzzleClient;

$guzzle = new GuzzleClient([
    'proxy' => 'http://proxy.example.com:8080',
    'timeout' => 60,
    'connect_timeout' => 10,
]);

$client = FirecrawlClient::create(
    apiKey: 'fc-your-api-key',
    httpClient: $guzzle,
);
```

<div id="error-handling">
  ## Manejo de errores
</div>

El SDK lanza excepciones de tiempo de ejecución en el espacio de nombres `Firecrawl\Exceptions`.

```php theme={null}
use Firecrawl\Exceptions\AuthenticationException;
use Firecrawl\Exceptions\FirecrawlException;
use Firecrawl\Exceptions\JobTimeoutException;
use Firecrawl\Exceptions\RateLimitException;

try {
    $doc = $client->scrape('https://example.com');
} catch (AuthenticationException $e) {
    echo 'Auth failed: ' . $e->getMessage();
} catch (RateLimitException $e) {
    echo 'Rate limited: ' . $e->getMessage();
} catch (JobTimeoutException $e) {
    echo 'Job ' . $e->getJobId() . ' timed out after ' . $e->getTimeoutSeconds() . 's';
} catch (FirecrawlException $e) {
    echo 'Error ' . $e->getStatusCode() . ': ' . $e->getMessage();
}
```

> ¿Eres un agente de IA que necesita una clave de API de Firecrawl? Consulta [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) para obtener instrucciones de incorporación automática.
