# Interaja após o scraping (/pt-BR/features/interact)

<!-- agent-signals: reading_time_min: 23 · est_tokens: 12068 · updated: 2026-07-31 -->

Faça o scraping de uma página para obter dados limpos e, em seguida, chame `/interact` para começar a realizar ações nessa página: clicar em botões, preencher formulários, extrair conteúdo dinâmico ou navegar mais profundamente. Basta descrever o que você quer, ou escrever código se precisar de controle 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: 5.000 créditos
      </span>

      <span style="{ fontWeight: 400 }">
         por feedback consistente sobre /interact
      </span>
    </div>
  </div>

  <p className="firecrawl-cta-description">
    Para se qualificar, faça uma entrevista rica em informações (com casos de uso bem pensados e concretos etc.) com nosso Assistente de Feedback do Firecrawl. Leva apenas alguns minutos, pode ser interrompida a qualquer momento e funciona tanto para humanos quanto para agentes (basta colar o link no seu framework de agentes!). Nunca usou /interact? Sua opinião também conta.
  </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 a entrevista
  </a>

  <p className="firecrawl-cta-description" style="{ fontSize: &#x22;12px&#x22;, fontStyle: &#x22;italic&#x22;, margin: &#x22;12px 0 0 0&#x22; }">
    Inclua seu email para se qualificar. As entrevistas são avaliadas quanto à qualidade ao final de cada semana.
  </p>
</div>

<div id="choose-the-right-interaction-model">
  ## Escolha o modelo de interação certo [#escolha-o-modelo-de-interação-certo]
</div>

| Necessidade                                                      | Use                                            | Documentação canônica                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Inicie uma sessão autônoma do navegador sem fazer scraping antes | Browser Sandbox / sessão autônoma do interagir | [Browser Sandbox](/pt-BR/features/browser), [Criar sessão do navegador](/pt-BR/api-reference/endpoint/browser-create), [Executar código no navegador](/pt-BR/api-reference/endpoint/browser-execute), [Listar sessões do navegador](/pt-BR/api-reference/endpoint/browser-list), [Excluir sessão do navegador](/pt-BR/api-reference/endpoint/browser-delete) |
| Continue a partir de um resultado de scraping usando `scrapeId`  | Interagir após o scraping                      | [Executar interagir](/pt-BR/api-reference/endpoint/scrape-execute), [Parar interagir](/pt-BR/api-reference/endpoint/scrape-browser-delete)                                                                                                                                                                                                                   |

Use o interagir vinculado ao scraping quando o fluxo de trabalho começar com `POST /v2/scrape` e a resposta incluir `data.metadata.scrapeId`. Use o Browser Sandbox quando precisar de uma sessão autônoma com seu próprio 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>">
    Descreva a ação que você quer executar na página
  </Card>

  <Card title="Execução 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>">
    Interaja com segurança por meio da execução de código usando playwright, agent-browser
  </Card>

  <Card title="Visualização em tempo real" 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>">
    Assista ou interaja com o navegador em tempo real por meio de um stream incorporável
  </Card>
</CardGroup>

<div id="how-it-works">
  ## Como funciona [#como-funciona]
</div>

1. **Faça o scraping** de uma URL com `POST /v2/scrape`. A resposta inclui um `scrapeId` em `data.metadata.scrapeId`. Se você quiser persistir o estado do navegador, passe `profile` nesta solicitação.
2. **Interaja** chamando `POST /v2/scrape/{scrapeId}/interact` com um `prompt` ou com `code` do Playwright. Não passe `profile` aqui; a sessão de interação herda o perfil do job de scraping.
3. **Encerre** a sessão com `DELETE /v2/scrape/{scrapeId}/interact` quando terminar. Para perfis graváveis, as mudanças são salvas quando a sessão é encerrada.

<div id="quick-start">
  ## Início rápido [#início-rápido]
</div>

Faça o scraping de uma página, interaja com ela e encerre a sessão:

<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(
        # Nenhuma API key necessária para começar — adicione uma para limites de taxa maiores:
        # api_key="fc-YOUR-API-KEY",
      )

      # 1. Fazer scraping da página inicial da Amazon
      result = app.scrape("https://www.amazon.com", formats=["markdown"])
      scrape_id = result.metadata.scrape_id

      # 2. Interagir — buscar um produto e obter seu preço
      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. Encerrar a sessão
      app.stop_interaction(scrape_id)
      ```
    </CodeBlockTab>

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

      const app = new Firecrawl({
        // Nenhuma API key necessária para começar — adicione uma para limites de taxa mais altos:
        // apiKey: 'fc-YOUR-API-KEY',
      });

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

      // 2. Interagir — buscar um produto e obter seu preço
      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. Encerrar a sessão
      await app.stopInteraction(scrapeId);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      # 1. Fazer scraping da página inicial da Amazon
      # Nenhuma API key necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa maiores:
      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. Interagir — buscar um produto e obter seu preço
      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. Encerrar a sessão
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # 1. Faça scraping da página inicial da Amazon (o ID de scraping é salvo automaticamente)
      firecrawl scrape https://www.amazon.com

      # 2. Interaja — busque um produto e obtenha seu preço
      firecrawl interact "Search for iPhone 16 Pro Max"
      firecrawl interact "Click on the first result and tell me the price"

      # 3. Encerre a sessão
      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">
  ## Interaja usando prompts [#interaja-usando-prompts]
</div>

A forma mais simples de interagir com uma página. Descreva o que você quer em linguagem natural, e ele clicará, digitará, rolará a página e extrairá dados automaticamente.

<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  
      # Nenhuma API key necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa maiores:
      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>

A resposta inclui um campo `output` com a resposta do 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">
  ### Mantenha os Prompts Pequenos e Focados [#mantenha-os-prompts-pequenos-e-focados]
</div>

Prompts funcionam melhor quando cada um é uma **tarefa única e clara**. Em vez de pedir ao agente para executar um fluxo de trabalho complexo com várias etapas de uma só vez, divida isso em chamadas `interact` separadas. Cada chamada reutiliza a mesma sessão do navegador, então o estado é mantido entre elas.

<div id="running-code">
  ## Executando código [#executando-código]
</div>

Para ter controle total, você pode executar código diretamente no sandbox do navegador. A variável `page` (um objeto `Page` do Playwright) está disponível tanto em Node.js quanto em Python. O modo Bash vem com [agent-browser](https://github.com/vercel-labs/agent-browser) pré-instalado. Você também pode fazer capturas de tela na sessão: use `(await page.screenshot()).toString("base64")` em Node.js, `await page.screenshot(path="/tmp/screenshot.png")` em Python ou `agent-browser screenshot` no Bash.

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

A linguagem padrão. Escreva código Playwright diretamente. `page` já está conectado ao 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="""
      // Clique em um botão e aguarde a navegação
      await page.click('#next-page');
      await page.waitForLoadState('networkidle');

      // Extraia o conteúdo da nova 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: `
          // Clica em um botão e aguarda a navegação
          await page.click('#next-page');
          await page.waitForLoadState('networkidle');

          // Extrai o conteúdo da nova 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  
      # Nenhuma chave de API é necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa mais 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 o último scraping automaticamente
      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 });
      "

      # Ou passe um ID de scraping explicitamente
      # firecrawl interact <scrape-id> -c "await page.title()"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

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

Defina `language` como `"python"` para a API do Python do 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  
      # Nenhuma chave de API é necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa maiores:
      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) é uma CLI pré-instalada no sandbox com mais de 60 comandos. Ela fornece uma árvore de acessibilidade com refs de elementos (`@e1`, `@e2`, ...), o que é ideal para automação conduzida 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  
      # Tire um snapshot para ver elementos interativos
      snapshot = app.interact(
          scrape_id,
          code="agent-browser snapshot -i",
          language="bash",
      )
      print(snapshot.stdout)
      # Resultado:
      # [document]
      #   @e1 [input type="text"] "Search..."
      #   @e2 [button] "Search"
      #   @e3 [link] "About"

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

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

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

    <CodeBlockTab value="cURL">
      ```bash  
      # Tire um snapshot para ver elementos interativos
      # Nenhuma API key necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa maiores:
      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"}'

      # Interaja com elementos usando @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  
      # Tire um snapshot para ver elementos interativos
      firecrawl interact --bash -c "agent-browser snapshot -i"

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

Comandos comuns do agent-browser:

| Comando                   | Descrição                                               |
| ------------------------- | ------------------------------------------------------- |
| `snapshot`                | Árvore de acessibilidade completa com refs de elementos |
| `snapshot -i`             | Apenas elementos interativos                            |
| `click @e1`               | Clica no elemento pela ref                              |
| `fill @e1 "text"`         | Limpa o campo e digita o texto                          |
| `type @e1 "text"`         | Digita sem limpar                                       |
| `press Enter`             | Pressiona uma tecla do teclado                          |
| `scroll down 500`         | Rola 500 pixels para baixo                              |
| `get text @e1`            | Obtém o conteúdo de texto                               |
| `get url`                 | Obtém a URL atual                                       |
| `wait @e1`                | Aguarda o elemento                                      |
| `wait --load networkidle` | Aguarda a rede ficar inativa                            |
| `find text "X" click`     | Encontra o elemento pelo texto e clica                  |
| `screenshot`              | Tira uma captura de tela da página atual                |
| `eval "js code"`          | Executa JavaScript na página                            |

<div id="live-view">
  ## Visualização em tempo real [#visualização-em-tempo-real]
</div>

Toda resposta de `interact` retorna uma `liveViewUrl` que você pode incorporar para acompanhar o navegador em tempo real. Útil para depuração, demonstrações ou para criar UIs com 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">
  ### Visualização em tempo real interativa [#visualização-em-tempo-real-interativa]
</div>

A resposta também inclui uma `interactiveLiveViewUrl`. Diferentemente da visualização em tempo real padrão, que é somente para visualização, a visualização em tempo real interativa permite que os usuários cliquem, digitem e interajam com a sessão do navegador diretamente pelo stream incorporado. Isso é útil para criar interfaces de navegador voltadas para o usuário final, como fluxos de login ou fluxos de trabalho guiados em que os usuários finais precisam controlar o navegador.

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

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

Toda resposta de interação também retorna uma `cdpUrl`: a URL WebSocket bruta do Chrome DevTools Protocol (CDP) da sessão do navegador. Use-a para se conectar diretamente à sessão ativa pelo Playwright, Puppeteer ou qualquer cliente CDP e controlar o navegador com seu próprio 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 da sessão [#ciclo-de-vida-da-sessão]
</div>

<div id="creation">
  ### Criação [#criação]
</div>

A primeira `POST /v2/scrape/{scrapeId}/interact` dá continuidade à sessão de scraping e inicia a interação.

<div id="reuse">
  ### Reutilização [#reutilização]
</div>

Chamadas subsequentes de `interact` no mesmo `scrapeId` reutilizam a sessão existente. O navegador permanece aberto e mantém seu estado entre as chamadas, para que você possa encadear várias interações:

<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  
      # Primeira chamada: clicar em uma aba
      app.interact(scrape_id, code="await page.click('#tab-2')")

      # Segunda chamada: a aba ainda está selecionada, extrair seu conteúdo
      result = app.interact(scrape_id, code="await page.$eval('#tab-2-content', el => el.textContent)")
      print(result.result)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      // Primeira chamada: clicar em uma aba
      await app.interact(scrapeId, { code: "await page.click('#tab-2')" });

      // Segunda chamada: a aba ainda está selecionada, extrair seu conteúdo
      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  
      # Primeira chamada: clicar em uma aba
      firecrawl interact -c "await page.click('#tab-2')"

      # Segunda chamada: a aba ainda está selecionada, extrair seu conteúdo
      firecrawl interact -c "await page.\$eval('#tab-2-content', el => el.textContent)"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<div id="cleanup">
  ### Limpeza [#limpeza]
</div>

Encerre a sessão explicitamente quando 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  
      # Nenhuma API key necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa maiores:
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"
      ```
    </CodeBlockTab>

    <CodeBlockTab value="CLI">
      ```bash  
      # Para a última sessão de scraping
      firecrawl interact stop

      # Ou pare uma sessão específica pelo ID
      # firecrawl interact stop <scrape-id>
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

As sessões também expiram automaticamente com base no TTL (default: 10 minutes) ou no tempo limite de inatividade (default: 5 minutes).

<Warning>
  Sempre encerre as sessões quando terminar para evitar cobrança desnecessária. Os créditos são rateados por segundo.
</Warning>

<div id="persistent-profiles-with-scrape-interact">
  ## Perfis persistentes com Scrape + Interagir [#perfis-persistentes-com-scrape--interagir]
</div>

Por padrão, cada sessão de scraping + interagir começa com um navegador limpo. Com `profile`, você pode salvar e reutilizar o estado do navegador (cookies, localStorage, sessões) entre scrapes. Isso é útil para continuar conectado e preservar preferências.

Passe o objeto `profile` na requisição inicial `POST /v2/scrape`. Não passe `profile` para `POST /v2/scrape/{scrapeId}/interact`; a sessão de interagir reutiliza a sessão do navegador e as configurações de perfil do scrape job. Encerre a sessão de interagir com `DELETE /v2/scrape/{scrapeId}/interact` para que mudanças graváveis no perfil possam ser salvas.

```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"
```

O ciclo de vida do perfil é:

1. Crie o scraping com `profile.name` e `saveChanges: true`.
2. Execute interações por prompt ou código usando o `scrapeId` retornado.
3. Encerre a sessão para salvar cookies, localStorage e outros estados do navegador.
4. Inicie um scraping posterior com o mesmo `profile.name`. Use `saveChanges: false` quando quiser apenas ler o estado existente sem gravar as mudanças de volta.

<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(
        # Nenhuma API key necessária para começar — adicione uma para limites de taxa mais altos:
        # api_key="fc-YOUR-API-KEY",
      )

      # Sessão 1: Scraping com um perfil, autentique-se e encerre (o estado é salvo)
      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)

      # Sessão 2: Scraping com o mesmo perfil em modo somente leitura - já autenticado
      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({
        // Nenhuma API key necessária para começar — adicione uma para limites de taxa mais altos:
        // apiKey: 'fc-YOUR-API-KEY',
      });

      // Session 1: Scrape com um perfil, faça login e pare (o estado é salvo)
      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);

      // Sessão 2: Scraping com o mesmo perfil em modo somente leitura - já autenticado
      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
      # Nenhuma API key necessária para começar — adicione -H "Authorization: Bearer $FIRECRAWL_API_KEY" para limites de taxa mais 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"}'

      # Parar — o estado é salvo no perfil
      curl -s -X DELETE "https://api.firecrawl.dev/v2/scrape/$SCRAPE_ID/interact"

      # Sessão 2: Scraping novamente com o mesmo perfil em modo somente leitura — já autenticado
      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  
      # Sessão 1: Scraping com um perfil, faça login e pare (estado é salvo)
      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

      # Sessão 2: Scraping com o mesmo perfil — já autenticado
      firecrawl scrape https://app.example.com/dashboard --profile my-app
      firecrawl interact "Extract the dashboard data"
      firecrawl interact stop

      # Somente leitura: carrega o estado do perfil sem salvar mudanças
      firecrawl scrape https://app.example.com/dashboard --profile my-app --no-save-changes
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

| Parâmetro     | Padrão | Descrição                                                                                                                                                                                                                                  |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`        | None   | Um nome para o perfil persistente. Scrapes com o mesmo nome compartilham o estado do navegador.                                                                                                                                            |
| `saveChanges` | `true` | Quando `true`, o estado do navegador é salvo novamente no perfil quando a sessão de interagir é encerrada. Defina como `false` para carregar dados existentes sem gravar, o que é útil quando você precisa de vários leitores simultâneos. |

<Note>
  Apenas uma sessão pode salvar em um perfil por vez. Se outra sessão já estiver salvando, você receberá um erro `409`. Você ainda pode abrir o mesmo perfil com `saveChanges: false` ou tentar novamente mais tarde.
</Note>

O estado do navegador é salvo quando a sessão de interagir é encerrada. Sempre encerre a sessão quando terminar para que o perfil possa ser reutilizado.

<div id="validate-persistence">
  ### Validar a persistência [#validar-a-persistência]
</div>

Você pode testar a persistência sem depender de um fluxo de login real gravando um valor no `localStorage` em uma sessão, encerrando-a e, em seguida, lendo esse valor em uma segunda sessão com o mesmo perfil.

```bash title="cURL"
# Sessão 1: gravar o estado do navegador e salvá-lo
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"
```

A segunda resposta do Interagir deve mostrar `localStorage` como `"saved"` e `cookie` como `true`.

<Info>
  Os perfis criados via API talvez ainda não apareçam em painel > Interagir > Perfis. No momento, o painel ainda não oferece uma visão completa dos perfis persistentes criados via API.
</Info>

<div id="when-to-use-what">
  ## Quando usar o quê [#quando-usar-o-quê]
</div>

| Use Case                                | Recommended                      | Why                                           |
| --------------------------------------- | -------------------------------- | --------------------------------------------- |
| Busca na web                            | [Search](/pt-BR/features/search) | Endpoint de busca dedicado                    |
| Obter conteúdo limpo de uma URL         | [Scrape](/pt-BR/features/scrape) | Uma chamada de API, sem necessidade de sessão |
| Clicar, digitar e navegar em uma página | **Interagir** (prompt)           | Basta descrever em inglês                     |
| Extrair dados por trás das interações   | **Interagir** (prompt)           | Não são necessários seletores                 |
| Lógica de scraping complexa             | **Interagir** (code)             | Controle total do Playwright                  |

<Info>
  **Interagir vs Browser Sandbox**: O Interagir é construído sobre a mesma infraestrutura que o [Browser Sandbox](/pt-BR/features/browser), mas oferece uma interface melhor para o padrão mais comum: fazer scrape de uma página e depois se aprofundar. O Browser Sandbox é melhor quando você precisa de uma sessão do navegador independente que não esteja vinculada a um scrape específico.
</Info>

<div id="pricing">
  ## Preços [#preços]
</div>

* **Somente código** (sem `prompt`): 2 créditos por minuto de sessão
* **Com prompts de IA**: 7 créditos por minuto de sessão
* **Scraping**: cobrado separadamente (1 crédito por scraping, além de quaisquer custos específicos do formato)

<div id="api-reference">
  ## Referência da API [#referência-da-api]
</div>

* [Execute Interagir](/pt-BR/api-reference/endpoint/scrape-execute): `POST /v2/scrape/{scrapeId}/interact`
* [Stop Interagir](/pt-BR/api-reference/endpoint/scrape-browser-delete): `DELETE /v2/scrape/{scrapeId}/interact`

<div id="request-body-post">
  ### Corpo da Requisição (POST) [#corpo-da-requisição-post]
</div>

| Campo      | Tipo     | Padrão   | Descrição                                                                                                                |
| ---------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `prompt`   | `string` | Nenhum   | Tarefa em linguagem natural para o agente de IA. Obrigatório se `code` não estiver definido. Máx. 10.000 caracteres.     |
| `code`     | `string` | Nenhum   | Código a ser executado (Node.js, Python ou Bash). Obrigatório se `prompt` não estiver definido. Máx. 100.000 caracteres. |
| `language` | `string` | `"node"` | `"node"`, `"python"` ou `"bash"`. Usado apenas com `code`.                                                               |
| `timeout`  | `number` | `30`     | Tempo limite em segundos (1–300).                                                                                        |
| `origin`   | `string` | Nenhum   | Identificador do chamador para acompanhamento de atividades.                                                             |

<div id="response">
  ### Resposta [#resposta]
</div>

| Field                    | Description                                                                                                                                                     |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success`                | `true` se a execução for concluída sem erros                                                                                                                    |
| `cdpUrl`                 | URL WebSocket bruta do Chrome DevTools Protocol (CDP) para a sessão do navegador. Conecte-se diretamente com Playwright, Puppeteer ou qualquer cliente CDP      |
| `liveViewUrl`            | URL de visualização em tempo real somente leitura para a sessão do navegador                                                                                    |
| `interactiveLiveViewUrl` | URL de visualização em tempo real interativa (os visualizadores podem controlar o navegador)                                                                    |
| `output`                 | A resposta em linguagem natural do agente ao seu prompt. Presente apenas ao usar `prompt`.                                                                      |
| `stdout`                 | Saída padrão da execução do código                                                                                                                              |
| `result`                 | Valor bruto retornado do sandbox. Para `code`: a última expressão avaliada. Para `prompt`: o snapshot bruto da página que o agente usou para produzir `output`. |
| `stderr`                 | Saída de erro padrão                                                                                                                                            |
| `exitCode`               | Código de saída (`0` = sucesso)                                                                                                                                 |
| `killed`                 | `true` se a execução tiver sido encerrada devido a tempo limite                                                                                                 |

***

Tem feedback ou precisa de ajuda? Envie um e-mail para [help@firecrawl.com](mailto:help@firecrawl.com) ou entre em contato no [Discord](https://discord.gg/firecrawl).
