# Interact tras el scraping (/es/features/interact)

<!-- agent-signals: reading_time_min: 24 · est_tokens: 12516 · updated: 2026-07-31 -->

Haz scraping de una página para obtener datos limpios y luego llama a `/interact` para empezar a realizar acciones en esa página: hacer clic en botones, completar formularios, extraer contenido dinámico o navegar más a fondo. Solo describe lo que quieres hacer, o escribe código si necesitas un control total.

<div className="firecrawl-cta-box">
  <div style="{ display: &#x22;flex&#x22;, alignItems: &#x22;flex-start&#x22;, gap: &#x22;8px&#x22;, marginBottom: &#x22;8px&#x22; }">
    <Icon icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M8 7L16 7&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8 11L12 11&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>" color="#ff4d00" size="22" />

    <div className="firecrawl-cta-title" style="{ margin: 0 }">
      <span style="{ color: &#x22;#ff4d00&#x22; }">
        Recompensa: 5000 créditos
      </span>

      <span style="{ fontWeight: 400 }">
         por comentarios útiles sobre /interact
      </span>
    </div>
  </div>

  <p className="firecrawl-cta-description">
    Para optar a la recompensa, completa una entrevista con información relevante (casos de uso concretos y bien pensados, etc.) con nuestro Asistente de Feedback de Firecrawl. Solo toma unos minutos, puedes detenerla en cualquier momento y es apta tanto para personas como para agentes (¡solo pega el enlace en tu entorno de agentes!). ¿Nunca usaste /interact? Tu opinión también cuenta.
  </p>

  <a href="&#x22;https://www.firecrawl.dev/survey/ogu30?src=&#x22; + (props.src || &#x22;docs-interact&#x22;)" className="firecrawl-cta-btn-primary firecrawl-cta-btn-inline">
    Iniciar la entrevista
  </a>

  <p className="firecrawl-cta-description" style="{ fontSize: &#x22;12px&#x22;, fontStyle: &#x22;italic&#x22;, margin: &#x22;12px 0 0 0&#x22; }">
    Incluye tu correo electrónico para poder optar a la recompensa. La calidad de las entrevistas se revisa al final de cada semana.
  </p>
</div>

<div id="choose-the-right-interaction-model">
  ## Selecciona el modelo de interacción adecuado [#selecciona-el-modelo-de-interacción-adecuado]
</div>

| Necesidad                                                            | Usar                                               | Documentación canónica                                                                                                                                                                                                                                                                                                                     |
| -------------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Iniciar una sesión de browser independiente sin hacer scraping antes | Browser Sandbox / sesión independiente de Interact | [Browser Sandbox](/es/features/browser), [Crear sesión de browser](/es/api-reference/endpoint/browser-create), [Ejecutar código en el browser](/es/api-reference/endpoint/browser-execute), [Listar sesiones de browser](/es/api-reference/endpoint/browser-list), [Eliminar sesión de browser](/es/api-reference/endpoint/browser-delete) |
| Continuar desde un resultado de scraping usando `scrapeId`           | Interact tras el scraping                          | [Ejecutar Interact](/es/api-reference/endpoint/scrape-execute), [Detener Interact](/es/api-reference/endpoint/scrape-browser-delete)                                                                                                                                                                                                       |

Usa Interact vinculado al scraping cuando el flujo de trabajo comienza con `POST /v2/scrape` y la respuesta incluye `data.metadata.scrapeId`. Usa Browser Sandbox cuando necesites una sesión independiente con su propio ciclo de vida.

<CardGroup cols="3">
  <Card title="Prompts de IA" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M8 7L16 7&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8 11L12 11&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>">
    Describe qué acción quieres realizar en la página
  </Card>

  <Card title="Ejecución de código" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M16 6.99998L19.0664 9.64296C20.3554 10.7541 21 11.3096 21 12C21 12.6903 20.3555 13.2459 19.0664 14.357L16 17&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8 6.99998L4.93365 9.64296C3.64455 10.7541 3 11.3096 3 12C3 12.6903 3.64455 13.2459 4.93365 14.357L8 17&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>">
    Interactúa de forma segura mediante la ejecución de código con playwright, agent-browser
  </Card>

  <Card title="Vista en vivo" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M2 8C2 8 6.47715 3 12 3C17.5228 3 22 8 22 8&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M21.544 13.045C21.848 13.4713 22 13.6845 22 14C22 14.3155 21.848 14.5287 21.544 14.955C20.1779 16.8706 16.6892 21 12 21C7.31078 21 3.8221 16.8706 2.45604 14.955C2.15201 14.5287 2 14.3155 2 14C2 13.6845 2.15201 13.4713 2.45604 13.045C3.8221 11.1294 7.31078 7 12 7C16.6892 7 20.1779 11.1294 21.544 13.045Z&#x22; stroke=&#x22;currentColor&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M15 14C15 12.3431 13.6569 11 12 11C10.3431 11 9 12.3431 9 14C9 15.6569 10.3431 17 12 17C13.6569 17 15 15.6569 15 14Z&#x22; stroke=&#x22;currentColor&#x22; stroke-width=&#x22;1.5&#x22;/></svg>">
    Observa o interactúa con el browser en tiempo real mediante un stream incrustable
  </Card>
</CardGroup>

<div id="how-it-works">
  ## Cómo funciona [#cómo-funciona]
</div>

1. **Haz scraping de** una URL con `POST /v2/scrape`. La respuesta incluye un `scrapeId` en `data.metadata.scrapeId`. Si quieres conservar el estado del navegador, pasa `profile` en esta solicitud.
2. **Interactúa** llamando a `POST /v2/scrape/{scrapeId}/interact` con un `prompt` o con código de Playwright `code`. No pases `profile` aquí; la sesión de interacción hereda el perfil del trabajo de scraping.
3. **Detén** la sesión con `DELETE /v2/scrape/{scrapeId}/interact` cuando hayas terminado. En los perfiles con escritura, los cambios se guardan cuando la sesión se detiene.

<div id="quick-start">
  ## Inicio rápido [#inicio-rápido]
</div>

Haz scraping de una página, interactúa con ella y detén la sesión:

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      from firecrawl import Firecrawl

      app = Firecrawl(
        # No se necesita API key para comenzar — añade una para límites de tasa más altos:
        # api_key="fc-YOUR-API-KEY",
      )

      # 1. Extraer la página principal de Amazon
      result = app.scrape("https://www.amazon.com", formats=["markdown"])
      scrape_id = result.metadata.scrape_id

      # 2. Interactuar — buscar un producto y obtener su precio
      app.interact(scrape_id, prompt="Search for iPhone 16 Pro Max")
      response = app.interact(scrape_id, prompt="Click on the first result and tell me the price")
      print(response.output)

      # 3. Detener la sesión
      app.stop_interaction(scrape_id)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      import { Firecrawl } from 'firecrawl';

      const app = new Firecrawl({
        // No se necesita API key para comenzar — agrega una para límites de tasa más altos:
        // apiKey: 'fc-YOUR-API-KEY',
      });

      // 1. Extraer la página principal de Amazon
      const result = await app.scrape('https://www.amazon.com', { formats: ['markdown'] });
      const scrapeId = result.metadata?.scrapeId;

      // 2. Interactuar — buscar un producto y obtener su precio
      await app.interact(scrapeId, { prompt: 'Search for iPhone 16 Pro Max' });
      const response = await app.interact(scrapeId, { prompt: 'Click on the first result and tell me the price' });
      console.log(response.output);

      // 3. Detener la sesión
      await app.stopInteraction(scrapeId);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # 1. Extraer la página principal de Amazon
      # No se necesita API key para comenzar — añade -H "Authorization: Bearer $FIRECRAWL_API_KEY" para límites de tasa más altos:
      RESPONSE=$(curl -s -X POST "https://api.firecrawl.dev/v2/scrape" \
        -H "Content-Type: application/json" \
        -d '{"url": "https://www.amazon.com", "formats": ["markdown"]}')

      SCRAPE_ID=$(echo $RESPONSE | jq -r '.data.metadata.scrapeId')

      # 2. Interactuar — buscar un producto y obtener su precio
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"prompt": "Search for iPhone 16 Pro Max"}'

      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"prompt": "Click on the first result and tell me the price"}'

      # 3. Detener la sesión
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # 1. Scrape la página principal de Amazon (el ID de scrape se guarda automáticamente)
      firecrawl scrape https://www.amazon.com

      # 2. Interactúa — busca un producto y obtén su precio
      firecrawl interact "Search for iPhone 16 Pro Max"
      firecrawl interact "Click on the first result and tell me the price"

      # 3. Detén la sesión
      firecrawl interact stop
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

```json title="Response"
{
  "success": true,
  "cdpUrl": "wss://browser.firecrawl.dev/...",
  "liveViewUrl": "https://liveview.firecrawl.dev/...",
  "interactiveLiveViewUrl": "https://liveview.firecrawl.dev/...",
  "output": "The iPhone 16 Pro Max (256GB) is priced at $1,199.00.",
  "exitCode": 0,
  "killed": false
}
```

<div id="interact-via-prompting">
  ## Interactúa mediante prompts [#interactúa-mediante-prompts]
</div>

La forma más simple de interactuar con una página. Describe lo que quieres en lenguaje natural y hará clic, escribirá, se desplazará y extraerá datos automáticamente.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      response = app.interact(scrape_id, prompt="What are the customer reviews saying about battery life?")
      print(response.output)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      const response = await app.interact(scrapeId, {
        prompt: 'What are the customer reviews saying about battery life?',
      });
      console.log(response.output);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para límites de tasa más altos:
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{
          "prompt": "What are the customer reviews saying about battery life?"
        }'
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      firecrawl interact "What are the customer reviews saying about battery life?"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

La respuesta incluye un campo `output` con la respuesta del agente:

```json title="Response"
{
  "success": true,
  "cdpUrl": "wss://browser.firecrawl.dev/...",
  "liveViewUrl": "https://liveview.firecrawl.dev/...",
  "interactiveLiveViewUrl": "https://liveview.firecrawl.dev/...",
  "output": "Customers are generally positive about battery life. Most reviewers report 8-10 hours of use on a single charge. A few noted it drains faster with heavy multitasking.",
  "stdout": "...",
  "result": "...",
  "stderr": "",
  "exitCode": 0,
  "killed": false
}
```

<div id="keep-prompts-small-and-focused">
  ### Mantén los prompts pequeños y enfocados [#mantén-los-prompts-pequeños-y-enfocados]
</div>

Los prompts funcionan mejor cuando cada uno consiste en una **única tarea clara**. En lugar de pedirle al agente que realice un flujo de trabajo complejo de varios pasos de una sola vez, divídelo en llamadas `interact` independientes. Cada llamada reutiliza la misma sesión del navegador, por lo que el estado se conserva entre una y otra.

<div id="running-code">
  ## Ejecución de código [#ejecución-de-código]
</div>

Para tener control total, puedes ejecutar código directamente en el sandbox del navegador. La variable `page` (un objeto Page de Playwright) está disponible en Node.js y Python. El modo Bash incluye [agent-browser](https://github.com/vercel-labs/agent-browser) preinstalado. También puedes hacer capturas de pantalla dentro de la sesión: usa `(await page.screenshot()).toString("base64")` en Node.js, `await page.screenshot(path="/tmp/screenshot.png")` en Python o `agent-browser screenshot` en Bash.

<div id="nodejs-playwright">
  ### Node.js (Playwright) [#nodejs-playwright]
</div>

El lenguaje predeterminado. Escribe código de Playwright directamente. `page` ya está conectado al navegador.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      response = app.interact(scrape_id, code="""
      // Hacer clic en un botón y esperar la navegación
      await page.click('#next-page');
      await page.waitForLoadState('networkidle');

      // Extraer contenido de la nueva página
      const title = await page.title();
      const content = await page.$eval('.article-body', el => el.textContent);
      JSON.stringify({ title, content });
      """)
      print(response.result)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      const response = await app.interact(scrapeId, {
        code: `
          // Hacer clic en un botón y esperar la navegación
          await page.click('#next-page');
          await page.waitForLoadState('networkidle');

          // Extraer contenido de la nueva página
          const title = await page.title();
          const content = await page.$eval('.article-body', el => el.textContent);
          JSON.stringify({ title, content });
        `,
      });
      console.log(response.result);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para límites de tasa más altos:
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{
          "code": "await page.click(\"#next-page\"); await page.waitForLoadState(\"networkidle\"); const title = await page.title(); JSON.stringify({ title });",
          "language": "node",
          "timeout": 30
        }'
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Usa el último scrape automáticamente
      firecrawl interact -c "
        await page.click('#next-page');
        await page.waitForLoadState('networkidle');
        const title = await page.title();
        const content = await page.\$eval('.article-body', el => el.textContent);
        JSON.stringify({ title, content });
      "

      # O pasa un ID de scrape explícitamente
      # firecrawl interact <scrape-id> -c "await page.title()"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<div id="python">
  ### Python [#python]
</div>

Configura `language` como `"python"` para usar la API de Python de Playwright.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      response = app.interact(
          scrape_id,
          code="""
      import json

      await page.click('#load-more')
      await page.wait_for_load_state('networkidle')

      items = await page.query_selector_all('.item')
      data = []
      for item in items:
          text = await item.text_content()
          data.append(text.strip())

      print(json.dumps(data))
      """,
          language="python",
      )
      print(response.stdout)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      const response = await app.interact(scrapeId, {
        code: `
      import json

      await page.click('#load-more')
      await page.wait_for_load_state('networkidle')

      items = await page.query_selector_all('.item')
      data = []
      for item in items:
          text = await item.text_content()
          data.append(text.strip())

      print(json.dumps(data))
      `,
        language: 'python',
      });
      console.log(response.stdout);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para obtener límites de tasa más altos:
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{
          "code": "import json\nawait page.click(\"#load-more\")\nawait page.wait_for_load_state(\"networkidle\")\nitems = await page.query_selector_all(\".item\")\ndata = [await i.text_content() for i in items]\nprint(json.dumps(data))",
          "language": "python"
        }'
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      firecrawl interact --python -c "
      import json
      await page.click('#load-more')
      await page.wait_for_load_state('networkidle')
      items = await page.query_selector_all('.item')
      data = [await i.text_content() for i in items]
      print(json.dumps(data))
      "
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<div id="bash-agent-browser">
  ### Bash (agent-browser) [#bash-agent-browser]
</div>

[agent-browser](https://github.com/vercel-labs/agent-browser) es una CLI preinstalada en el sandbox con más de 60 comandos. Proporciona un árbol de accesibilidad con referencias de elementos (`@e1`, `@e2`, ...), lo que es ideal para la automatización controlada por LLM.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      # Tomar una instantánea para ver los elementos interactivos
      snapshot = app.interact(
          scrape_id,
          code="agent-browser snapshot -i",
          language="bash",
      )
      print(snapshot.stdout)
      # Salida:
      # [document]
      #   @e1 [input type="text"] "Search..."
      #   @e2 [button] "Search"
      #   @e3 [link] "About"

      # Interactuar con elementos usando @refs
      app.interact(
          scrape_id,
          code='agent-browser fill @e1 "firecrawl" && agent-browser click @e2',
          language="bash",
      )
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      // Tomar una instantánea para ver los elementos interactivos
      const snapshot = await app.interact(scrapeId, {
        code: 'agent-browser snapshot -i',
        language: 'bash',
      });
      console.log(snapshot.stdout);
      // Salida:
      // [document]
      //   @e1 [input type="text"] "Search..."
      //   @e2 [button] "Search"
      //   @e3 [link] "About"

      // Interactuar con elementos usando @refs
      await app.interact(scrapeId, {
        code: 'agent-browser fill @e1 "firecrawl" && agent-browser click @e2',
        language: 'bash',
      });
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # Tomar una instantánea para ver los elementos interactivos
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para mayores límites de tasa:
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"code": "agent-browser snapshot -i", "language": "bash"}'

      # Interactuar con los elementos utilizando @refs
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"code": "agent-browser fill @e1 \"firecrawl\" && agent-browser click @e2", "language": "bash"}'
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Tomar una instantánea para ver los elementos interactivos
      firecrawl interact --bash -c "agent-browser snapshot -i"

      # Interactuar con elementos utilizando @refs
      firecrawl interact --bash -c 'agent-browser fill @e1 "firecrawl" && agent-browser click @e2'
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Comandos comunes de agent-browser:

| Comando                   | Descripción                                                  |
| ------------------------- | ------------------------------------------------------------ |
| `snapshot`                | Árbol de accesibilidad completo con referencias de elementos |
| `snapshot -i`             | Solo elementos interactivos                                  |
| `click @e1`               | Hacer clic en un elemento por referencia                     |
| `fill @e1 "text"`         | Borrar el campo y escribir texto                             |
| `type @e1 "text"`         | Escribir sin borrar                                          |
| `press Enter`             | Pulsar una tecla del teclado                                 |
| `scroll down 500`         | Desplazarse 500 píxeles hacia abajo                          |
| `get text @e1`            | Obtener el contenido de texto                                |
| `get url`                 | Obtener la URL actual                                        |
| `wait @e1`                | Esperar a que aparezca el elemento                           |
| `wait --load networkidle` | Esperar a que la red quede inactiva                          |
| `find text "X" click`     | Buscar un elemento por texto y hacer clic                    |
| `screenshot`              | Tomar una captura de pantalla de la página actual            |
| `eval "js code"`          | Ejecutar JavaScript en la página                             |

<div id="live-view">
  ## vista en vivo [#vista-en-vivo]
</div>

Cada respuesta de interact devuelve una `liveViewUrl` que puedes incrustar para ver el navegador en tiempo real. Es útil para depuración, demos o para crear interfaces con navegador.

```json title="Response"
{
  "success": true,
  "cdpUrl": "wss://browser.firecrawl.dev/...",
  "liveViewUrl": "https://liveview.firecrawl.dev/...",
  "interactiveLiveViewUrl": "https://liveview.firecrawl.dev/...",
  "stdout": "",
  "result": "...",
  "exitCode": 0
}
```

```html
<iframe src="LIVE_VIEW_URL" width="100%" height="600" />
```

<div id="interactive-live-view">
  ### Vista en vivo interactiva [#vista-en-vivo-interactiva]
</div>

La respuesta también incluye un `interactiveLiveViewUrl`. A diferencia de la vista en vivo estándar, que es solo de visualización, la vista en vivo interactiva permite a los usuarios hacer clic, escribir e interactuar con la sesión del navegador directamente a través del stream integrado. Esto resulta útil para crear interfaces de navegador orientadas al usuario, como flujos de inicio de sesión o flujos de trabajo guiados en los que los usuarios finales necesitan controlar el navegador.

```html
<iframe src="INTERACTIVE_LIVE_VIEW_URL" width="100%" height="600" />
```

<div id="cdp-url">
  ### URL de CDP [#url-de-cdp]
</div>

Cada respuesta de interact también devuelve una `cdpUrl`: la URL de WebSocket sin procesar del Chrome DevTools Protocol (CDP) para la sesión del navegador. Úsala para conectarte directamente a la sesión activa desde Playwright, Puppeteer o cualquier cliente CDP, y controlar el navegador con tu propio código.

```js
import { chromium } from "playwright";

const browser = await chromium.connectOverCDP(cdpUrl);
const context = browser.contexts()[0];
const page = context.pages()[0];
```

<div id="session-lifecycle">
  ## Ciclo de vida de la sesión [#ciclo-de-vida-de-la-sesión]
</div>

<div id="creation">
  ### Creación [#creación]
</div>

La primera llamada `POST /v2/scrape/{scrapeId}/interact` continúa la sesión de scraping e inicia la interacción.

<div id="reuse">
  ### Reutilización [#reutilización]
</div>

Las llamadas posteriores a `interact` sobre el mismo `scrapeId` reutilizan la sesión existente. El navegador permanece abierto y conserva su estado entre llamadas, por lo que puedes encadenar varias interacciones:

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      # Primera llamada: haz clic en una pestaña
      app.interact(scrape_id, code="await page.click('#tab-2')")

      # Segunda llamada: la pestaña sigue seleccionada, extrae su contenido
      result = app.interact(scrape_id, code="await page.$eval('#tab-2-content', el => el.textContent)")
      print(result.result)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      // Primera llamada: haz clic en una pestaña
      await app.interact(scrapeId, { code: "await page.click('#tab-2')" });

      // Segunda llamada: la pestaña sigue seleccionada, extrae su contenido
      const result = await app.interact(scrapeId, {
        code: "await page.$eval('#tab-2-content', el => el.textContent)",
      });
      console.log(result.result);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Primera llamada: haz clic en una pestaña
      firecrawl interact -c "await page.click('#tab-2')"

      # Segunda llamada: la pestaña sigue seleccionada, extrae su contenido
      firecrawl interact -c "await page.\$eval('#tab-2-content', el => el.textContent)"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<div id="cleanup">
  ### Limpieza [#limpieza]
</div>

Detén la sesión explícitamente al terminar:

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      app.stop_interaction(scrape_id)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      await app.stopInteraction(scrapeId);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para límites de tasa más altos:
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Detiene la última sesión de scrape
      firecrawl interact stop

      # O detener una sesión específica por ID
      # firecrawl interact stop <scrape-id>
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Las sesiones también expiran automáticamente según el TTL (predeterminado: 10 minutos) o el timeout de inactividad (predeterminado: 5 minutos).

<Warning>
  Detén siempre las sesiones al terminar para evitar Billing innecesario. Los credits se prorratean por segundo.
</Warning>

<div id="persistent-profiles-with-scrape-interact">
  ## Perfiles persistentes con Scraping + Interact [#perfiles-persistentes-con-scraping--interact]
</div>

De forma predeterminada, cada sesión de scraping + interact se inicia con un navegador limpio. Con `profile`, puedes guardar y reutilizar el estado del navegador (cookies, localStorage, sesiones) entre scrapings. Esto resulta útil para mantener la sesión iniciada y conservar las preferencias.

Pasa el objeto `profile` en la solicitud inicial `POST /v2/scrape`. No pases `profile` a `POST /v2/scrape/{scrapeId}/interact`; la sesión de interact reutiliza la sesión del navegador y la configuración del perfil del trabajo de scraping. Detén la sesión de interact con `DELETE /v2/scrape/{scrapeId}/interact` para que puedan guardarse los cambios del perfil.

```bash title="cURL"
curl -X POST "https://api.firecrawl.dev/v2/scrape" \
  -H "Authorization: Bearer fc-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "formats": ["markdown"],
    "profile": {
      "name": "my-profile",
      "saveChanges": true
    }
  }'

curl -X POST "https://api.firecrawl.dev/v2/scrape/SCRAPE_ID/interact" \
  -H "Authorization: Bearer fc-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Click the login button"
  }'

curl -X DELETE "https://api.firecrawl.dev/v2/scrape/SCRAPE_ID/interact" \
  -H "Authorization: Bearer fc-YOUR_API_KEY"
```

El ciclo de vida del perfil es:

1. Crea el scraping con `profile.name` y `saveChanges: true`.
2. Ejecuta interacciones con prompt o código usando el `scrapeId` devuelto.
3. Detén la sesión para guardar cookies, localStorage y otro estado del navegador.
4. Inicia un scraping posterior con el mismo `profile.name`. Usa `saveChanges: false` cuando solo quieras leer el estado existente sin volver a escribir cambios.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="cli+curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="CLI">
        CLI
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      from firecrawl import Firecrawl

      app = Firecrawl(
        # No se necesita API key para comenzar — agrega una para obtener límites de tasa más altos:
        # api_key="fc-YOUR-API-KEY",
      )

      # Sesión 1: Scrape con un perfil, inicia sesión y luego detén (el estado se guarda)
      result = app.scrape(
          "https://app.example.com/login",
          formats=["markdown"],
          profile={"name": "my-app", "save_changes": True},
      )
      scrape_id = result.metadata.scrape_id

      app.interact(scrape_id, prompt="Fill in user@example.com and password, then click Login")
      app.stop_interaction(scrape_id)

      # Sesión 2: Scrape con el mismo perfil en modo de solo lectura — ya con sesión iniciada
      result = app.scrape(
          "https://app.example.com/dashboard",
          formats=["markdown"],
          profile={"name": "my-app", "save_changes": False},
      )
      scrape_id = result.metadata.scrape_id

      response = app.interact(scrape_id, prompt="Extract the dashboard data")
      print(response.output)
      app.stop_interaction(scrape_id)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      import { Firecrawl } from 'firecrawl';

      const app = new Firecrawl({
        // No se necesita API key para comenzar — agrega una para obtener límites de tasa más altos:
        // apiKey: 'fc-YOUR-API-KEY',
      });

      // Sesión 1: Scrape con un perfil, inicia sesión y luego detén (el estado se guarda)
      const result1 = await app.scrape('https://app.example.com/login', {
        formats: ['markdown'],
        profile: { name: 'my-app', saveChanges: true },
      });
      const scrapeId1 = result1.metadata?.scrapeId;

      await app.interact(scrapeId1, { prompt: 'Fill in user@example.com and password, then click Login' });
      await app.stopInteraction(scrapeId1);

      // Sesión 2: Scrape con el mismo perfil en modo de solo lectura — ya con sesión iniciada
      const result2 = await app.scrape('https://app.example.com/dashboard', {
        formats: ['markdown'],
        profile: { name: 'my-app', saveChanges: false },
      });
      const scrapeId2 = result2.metadata?.scrapeId;

      const response = await app.interact(scrapeId2, { prompt: 'Extract the dashboard data' });
      console.log(response.output);
      await app.stopInteraction(scrapeId2);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # Session 1: Scrape with a profile
      # No se necesita API key para comenzar — agrega -H "Authorization: Bearer $FIRECRAWL_API_KEY" para límites de tasa más altos:
      RESPONSE=$(curl -s -X POST "https://api.firecrawl.dev/v2/scrape" \
        -H "Content-Type: application/json" \
        -d '{
          "url": "https://app.example.com/login",
          "formats": ["markdown"],
          "profile": { "name": "my-app", "saveChanges": true }
        }')

      SCRAPE_ID=$(echo $RESPONSE | jq -r '.data.metadata.scrapeId')

      # Log in via interact
      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"prompt": "Fill in user@example.com and password, then click Login"}'

      # Detener - el estado se guarda en el perfil
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"

      # Sesión 2: Scrape nuevamente con el mismo perfil en modo de solo lectura - ya con sesión iniciada
      RESPONSE=$(curl -s -X POST "https://api.firecrawl.dev/v2/scrape" \
        -H "Content-Type: application/json" \
        -d '{
          "url": "https://app.example.com/dashboard",
          "formats": ["markdown"],
          "profile": { "name": "my-app", "saveChanges": false }
        }')

      SCRAPE_ID=$(echo $RESPONSE | jq -r '.data.metadata.scrapeId')

      curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
        -H "Content-Type: application/json" \
        -d '{"prompt": "Extract the dashboard data"}'
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Sesión 1: Scrape con un perfil, inicia sesión y luego detén (el estado se guarda)
      firecrawl scrape https://app.example.com/login --profile my-app
      firecrawl interact "Fill in user@example.com and password, then click Login"
      firecrawl interact stop

      # Sesión 2: Scrape con el mismo perfil — ya has iniciado sesión
      firecrawl scrape https://app.example.com/dashboard --profile my-app
      firecrawl interact "Extract the dashboard data"
      firecrawl interact stop

      # Solo lectura: carga el estado del perfil sin guardar los cambios
      firecrawl scrape https://app.example.com/dashboard --profile my-app --no-save-changes
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

| Parámetro     | Predeterminado | Descripción                                                                                                                                                                                                                                                      |
| ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`        | None           | Nombre del perfil persistente. Los scrapings con el mismo nombre comparten el estado del navegador.                                                                                                                                                              |
| `saveChanges` | `true`         | Cuando es `true`, el estado del navegador se vuelve a guardar en el perfil cuando se detiene la sesión de interact. Establécelo en `false` para cargar datos existentes sin escribir cambios, lo que resulta útil cuando necesitas varios lectores concurrentes. |

<Note>
  Solo una sesión puede guardar en un perfil a la vez. Si otra sesión ya está guardando, recibirás un error `409`. Aun así, puedes abrir el mismo perfil con `saveChanges: false` o volver a intentarlo más tarde.
</Note>

El estado del navegador se guarda cuando se detiene la sesión de interact. Detén siempre la sesión cuando termines para que el perfil pueda reutilizarse.

<div id="validate-persistence">
  ### Validar la persistencia [#validar-la-persistencia]
</div>

Puedes probar la persistencia sin depender de un flujo de inicio de sesión real: escribe un valor en `localStorage` en una sesión, detenla y luego lee ese valor en una segunda sesión con el mismo perfil.

```bash title="cURL"
# Sesión 1: escribir el estado del navegador y guardarlo
RESPONSE=$(curl -s -X POST "https://api.firecrawl.dev/v2/scrape" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "formats": ["markdown"],
    "profile": { "name": "profile-validation", "saveChanges": true }
  }')

SCRAPE_ID=$(echo "$RESPONSE" | jq -r ".data.metadata.scrapeId")

curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "await page.evaluate(() => { localStorage.setItem(\"firecrawlProfileCheck\", \"saved\"); document.cookie = \"firecrawl_profile_check=saved; path=/; max-age=3600\"; return localStorage.getItem(\"firecrawlProfileCheck\"); });"
  }'

curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY"

# Sesión 2: cargar el mismo perfil en modo de solo lectura y verificar el valor
RESPONSE=$(curl -s -X POST "https://api.firecrawl.dev/v2/scrape" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "formats": ["markdown"],
    "profile": { "name": "profile-validation", "saveChanges": false }
  }')

SCRAPE_ID=$(echo "$RESPONSE" | jq -r ".data.metadata.scrapeId")

curl -s -X POST "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "await page.evaluate(() => ({ localStorage: localStorage.getItem(\"firecrawlProfileCheck\"), cookie: document.cookie.includes(\"firecrawl_profile_check=saved\") }));"
  }'

curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact" \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY"
```

La segunda respuesta de Interact debería mostrar `localStorage` como `"saved"` y `cookie` como `true`.

<Info>
  Puede que los perfiles creados a través de la API todavía no aparezcan en Dashboard > Interact > Profiles. Actualmente, el dashboard no ofrece un inventario completo de los perfiles persistentes creados mediante la API.
</Info>

<div id="when-to-use-what">
  ## Cuándo usar cada opción [#cuándo-usar-cada-opción]
</div>

| Caso de uso                                  | Recomendado                     | Por qué                                       |
| -------------------------------------------- | ------------------------------- | --------------------------------------------- |
| Búsqueda web                                 | [Search](/es/features/search)   | Endpoint de búsqueda específico               |
| Obtener contenido limpio de una URL          | [scraping](/es/features/scrape) | Una llamada a la API, sin necesidad de sesión |
| Hacer clic, escribir y navegar en una página | **Interact** (prompt)           | Solo descríbelo en inglés                     |
| Extraer datos tras interacciones             | **Interact** (prompt)           | No se necesitan selectores                    |
| Lógica de scraping compleja                  | **Interact** (code)             | Control total de Playwright                   |

<Info>
  **Interact vs Browser Sandbox**: Interact se basa en la misma infraestructura que [Browser Sandbox](/es/features/browser), pero ofrece una mejor interfaz para el patrón más común: hacer scraping de una página y luego profundizar. Browser Sandbox es mejor cuando necesitas una sesión del navegador independiente que no esté vinculada a un scraping específico.
</Info>

<div id="pricing">
  ## Precios [#precios]
</div>

* **Solo código** (sin `prompt`): 2 credits por minuto de sesión
* **Con prompts de IA**: 7 credits por minuto de sesión
* **scraping**: se factura por separado (1 credit por scraping, más cualquier costo específico del formato)

<div id="api-reference">
  ## Referencia de la API [#referencia-de-la-api]
</div>

* [Ejecutar Interact](/es/api-reference/endpoint/scrape-execute): `POST /v2/scrape/{scrapeId}/interact`
* [Detener Interact](/es/api-reference/endpoint/scrape-browser-delete): `DELETE /v2/scrape/{scrapeId}/interact`

<div id="request-body-post">
  ### Cuerpo de la solicitud (POST) [#cuerpo-de-la-solicitud-post]
</div>

| Campo      | Tipo     | Predeterminado | Descripción                                                                                                               |
| ---------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `prompt`   | `string` | Ninguno        | Tarea en lenguaje natural para el agente de IA. Obligatorio si no se establece `code`. Máximo 10.000 caracteres.          |
| `code`     | `string` | Ninguno        | Código que se va a ejecutar (Node.js, Python o Bash). Obligatorio si no se establece `prompt`. Máximo 100.000 caracteres. |
| `language` | `string` | `"node"`       | `"node"`, `"python"` o `"bash"`. Solo se usa con `code`.                                                                  |
| `timeout`  | `number` | `30`           | Timeout en segundos (1–300).                                                                                              |
| `origin`   | `string` | Ninguno        | Identificador del llamante para el seguimiento de la actividad.                                                           |

<div id="response">
  ### Respuesta [#respuesta]
</div>

| Field                    | Description                                                                                                                                                                             |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success`                | `true` si la ejecución se completó sin errores                                                                                                                                          |
| `cdpUrl`                 | URL WebSocket sin procesar de Chrome DevTools Protocol (CDP) para la sesión del navegador. Conéctate directamente con Playwright, Puppeteer o cualquier cliente CDP                     |
| `liveViewUrl`            | URL de vista en vivo de solo lectura para la sesión del navegador                                                                                                                       |
| `interactiveLiveViewUrl` | URL de vista en vivo interactiva (quienes la vean pueden controlar el navegador)                                                                                                        |
| `output`                 | La respuesta en lenguaje natural del agente a tu prompt. Solo está presente cuando se utiliza `prompt`.                                                                                 |
| `stdout`                 | Salida estándar de la ejecución del código                                                                                                                                              |
| `result`                 | Valor de retorno sin procesar del sandbox. Para `code`: la última expresión evaluada. Para `prompt`: la captura sin procesar de la página que el agente utilizó para producir `output`. |
| `stderr`                 | Salida de error estándar                                                                                                                                                                |
| `exitCode`               | Código de salida (`0` = éxito)                                                                                                                                                          |
| `killed`                 | `true` si la ejecución se finalizó debido a timeout                                                                                                                                     |

***

¿Tienes comentarios o necesitas ayuda? Envía un correo a [help@firecrawl.com](mailto:help@firecrawl.com) o comunícate en [Discord](https://discord.gg/firecrawl).
