Pular para o conteúdo principal

Documentation Index

Fetch the complete documentation index at: https://docs.firecrawl.dev/llms.txt

Use this file to discover all available pages before exploring further.

Os monitores do Firecrawl executam scraping ou rastreamentos recorrentes e comparam cada resultado com o último snapshot retido. Use os monitores para acompanhar páginas de produto, documentação, blogs, changelogs, sites de concorrentes ou qualquer página em que as mudanças sejam importantes. Cada verificação registra resultados por página como same, new, changed, removed ou error. Você pode receber um webhook quando cada página monitorada for concluída, um webhook para cada verificação concluída, resumos por email quando houver mudanças ou erros, ou qualquer combinação dessas notificações.
O monitoramento exige snapshots e diffs retidos. Ele não está disponível para equipes com Zero Data Retention.

Criar um monitor

Crie um monitor de scraping para uma ou mais URLs especificadas explicitamente:
from firecrawl import Firecrawl

firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

monitor = firecrawl.create_monitor(
    name="Hacker News AI monitor",
    schedule={"text": "every 30 minutes", "timezone": "UTC"},
    goal=(
        "Alert when a new Hacker News story related to AI enters the top 10. "
        "Ignore changes to stories that are not about AI. "
        "Do not alert on changes outside the top 10."
    ),
    targets=[
        {
            "type": "scrape",
            "urls": ["https://news.ycombinator.com"],
        }
    ],
    notification={
        "email": {
            "enabled": True,
            "recipients": ["alerts@example.com"],
            "includeDiffs": True,
        }
    },
)

print(monitor.id)
Crie um monitor de rastreamento para detectar diferenças em cada página descoberta por um rastreamento a cada verificação:
from firecrawl import Firecrawl

firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

monitor = firecrawl.create_monitor(
    name="Docs monitor",
    schedule={"cron": "7-59/15 * * * *", "timezone": "UTC"},
    goal="Notify me when docs pages add, remove, or materially change API behavior",
    targets=[
        {
            "type": "crawl",
            "url": "https://example.com/docs",
            "crawlOptions": {
                "limit": 100,
                "maxDiscoveryDepth": 3,
            },
        }
    ],
    webhook={
        "url": "https://example.com/webhooks/firecrawl",
        "events": ["monitor.page", "monitor.check.completed"],
    },
)

print(monitor.id)
Cada chamada de criação retorna o novo monitor com o cron normalizado, nextRunAt calculado e estimatedCreditsPerMonth. Quando a avaliação está habilitada, estimatedCreditsPerMonth é uma estimativa de limite superior, porque os créditos de avaliação só são cobrados para páginas alteradas que de fato são avaliadas:
Response
{
  "success": true,
  "data": {
    "id": "019df960-06e7-7383-9d89-82c0113dc31a",
    "name": "Hacker News AI monitor",
    "status": "active",
    "schedule": {
      "cron": "*/30 * * * *",
      "timezone": "UTC"
    },
    "nextRunAt": "2026-05-17T16:00:00.000Z",
    "lastRunAt": null,
    "currentCheckId": null,
    "goal": "Alert when a new Hacker News story related to AI enters the top 10. Ignore changes to stories that are not about AI. Do not alert on changes outside the top 10.",
    "judgeEnabled": true,
    "targets": [
      {
        "id": "019df960-09bb-7c11-8001-1f12f50ab1c2",
        "type": "scrape",
        "urls": ["https://news.ycombinator.com"]
      }
    ],
    "webhook": null,
    "notification": {
      "email": {
        "enabled": true,
        "recipients": ["alerts@example.com"],
        "includeDiffs": true
      }
    },
    "retentionDays": 30,
    "estimatedCreditsPerMonth": 2880,
    "lastCheckSummary": null,
    "createdAt": "2026-05-17T15:30:00.000Z",
    "updatedAt": "2026-05-17T15:30:00.000Z"
  }
}
Você também pode criar monitores pela CLI do Firecrawl:
CLI
firecrawl monitor create --name "Hacker News AI" \
  --schedule "every 30 minutes" \
  --goal "Alert when a new Hacker News story related to AI enters the top 10. Ignore changes to stories that are not about AI. Do not alert on changes outside the top 10." \
  --page https://news.ycombinator.com

Objetivos e avaliação

Adicione um goal em linguagem simples quando quiser receber alertas apenas sobre mudanças significativas. Se goal estiver presente e judgeEnabled for omitido, o Firecrawl ativa a avaliação automaticamente. A avaliação é executada nas páginas alteradas e retorna um judgment com meaningful, confidence, reason e meaningfulChanges. Use judgeEnabled: false se quiser armazenar uma meta sem avaliar as mudanças ainda. O avaliador só é executado quando o monitor tem judgeEnabled e um goal não vazio.
Cada verificação sempre cobra pelos scrapings ou rastreamentos subjacentes. Se a avaliação estiver habilitada, o avaliador adiciona 1 crédito para cada página alterada que ele valida. Verificações sem páginas alteradas não usam créditos do avaliador.
Boas metas são curtas e explícitas: diga o que deve acionar um alerta, reforce qualquer escopo, como top N, preço, tipo de cargo, empresa, região, tópico, status ou entidade, e inclua exclusões apenas quando fizerem parte da intenção. Se a meta for ampla, mantenha-a ampla; por exemplo, “qualquer mudança” não deve adicionar filtros de ruído que ocultem mudanças. Por exemplo, um monitor com esta meta:
Alerte quando uma nova história do Hacker News relacionada a IA entrar no top 10. Ignore mudanças em histórias que não sejam sobre IA. Não alerte sobre mudanças fora do top 10.
poderia gerar um webhook monitor.page como este quando uma história correspondente entrar no escopo:
monitor.page
{
  "success": true,
  "type": "monitor.page",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0000-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "url": "https://news.ycombinator.com",
      "status": "changed",
      "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
      "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
      "error": null,
      "isMeaningful": true,
      "judgment": {
        "meaningful": true,
        "confidence": "high",
        "reason": "A new AI-related story entered the Hacker News top 10.",
        "meaningfulChanges": [
          {
            "type": "added",
            "after": "4. Show HN: Open-source AI coding assistant",
            "reason": "This is a new AI-related story inside the top 10."
          }
        ]
      },
      "diff": {
        "text": "--- previous\n+++ current\n@@ -1,5 +1,6 @@\n # Hacker News\n 1. Database internals for beginners\n 2. A new approach to CSS\n 3. Building reliable queues\n+4. Show HN: Open-source AI coding assistant\n"
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}

Agendamentos

Os agendamentos podem ser fornecidos como expressão cron ou como texto simples em linguagem natural.
{
  "schedule": {
    "cron": "*/30 * * * *",
    "timezone": "UTC"
  }
}
Exemplos aceitos em linguagem natural:
  • every 30 minutes
  • every 15 minutes starting at :07
  • hourly
  • every 2 hours
  • daily
  • daily at 9:00
  • daily at 9am
  • daily at 5:30 PM
  • weekly
O intervalo mínimo é de 15 minutos. As respostas da API sempre retornam a expressão cron normalizada. Para agendamentos em texto, timezone determina quando expressões como daily at 9am são executadas. Os agendamentos em texto são distribuídos com base no ID do monitor antes de serem convertidos para cron, para que vários monitores não sejam executados todos no mesmo instante.

Alvos

Os monitores oferecem suporte a dois tipos de alvo:
  • scrape: executa uma operação de scraping por URL em urls.
  • crawl: executa um rastreamento completo de url em cada verificação e depois compara todas as páginas descobertas.
Cada monitor aceita de 1 a 50 alvos. O padrão de retentionDays é 30, e ele pode ser definido em até 365. As opções de scraping do alvo são repassadas aos jobs de scraping subjacentes. Os scrapings acionados pelo monitor usam maxAge como 0 por padrão, então cada verificação executa um scraping novo, a menos que você defina explicitamente um maxAge diferente.
Scrape target
{
  "type": "scrape",
  "urls": ["https://example.com/pricing"],
  "scrapeOptions": {
    "formats": ["markdown"],
    "maxAge": 0
  }
}
Para alvos de rastreamento, use crawlOptions para definir o comportamento do rastreamento e scrapeOptions para o scraping de cada página:
Crawl target
{
  "type": "crawl",
  "url": "https://example.com/docs",
  "crawlOptions": {
    "limit": 100,
    "includePaths": ["/docs"]
  },
  "scrapeOptions": {
    "formats": ["markdown"]
  }
}

Rastreamento de mudanças

Por padrão, o Firecrawl compara o markdown de cada página e informa same, changed, new, removed ou error. Quando quiser detectar mudanças em campos estruturados específicos (preço, manchete, indicador de disponibilidade em estoque, itens de uma lista etc.), habilite o rastreamento de mudanças no modo JSON adicionando um formato changeTracking com modes: ["json"] às scrapeOptions do alvo.

Modo Markdown (padrão)

Quando scrapeOptions.formats é apenas ["markdown"], cada página alterada na resposta da verificação inclui um diff de texto unificado e uma AST no estilo parseDiff:
Markdown-mode diff
{
  "diff": {
    "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Pricing\n-Starter — $19/mo\n+Starter — $24/mo\n",
    "json": {
      "files": [
        {
          "from": "previous",
          "to": "current",
          "chunks": [
            {
              "content": "@@ -1,3 +1,3 @@",
              "changes": []
            }
          ]
        }
      ]
    }
  }
}

Modo JSON

Passe um formato changeTracking com modes: ["json"] junto com um schema JSON (ou um prompt) que descreva os campos que importam para você. O Firecrawl extrai esse JSON em cada verificação e gera um diff por campo identificado pelo caminho do campo, além de um snapshot.json com a extração atual completa, para que os consumidores não precisem buscar novamente o scraping subjacente.
from firecrawl import Firecrawl
from pydantic import BaseModel
from typing import List

firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")


class Plan(BaseModel):
    name: str
    price: str
    features: List[str]


class Pricing(BaseModel):
    plans: List[Plan]


monitor = firecrawl.create_monitor(
    name="Pricing monitor",
    schedule={"text": "hourly", "timezone": "UTC"},
    goal="Notify me when a pricing tier, price, or headline feature changes",
    targets=[
        {
            "type": "scrape",
            "urls": ["https://example.com/pricing"],
            "scrapeOptions": {
                "formats": [
                    {
                        "type": "changeTracking",
                        "modes": ["json"],
                        "prompt": "Extract pricing tiers and headline features for each plan.",
                        "schema": Pricing.model_json_schema(),
                    }
                ]
            },
        }
    ],
    notification={
        "email": {
            "enabled": True,
            "recipients": ["alerts@example.com"],
            "includeDiffs": True,
        }
    },
)

print(monitor.id)
O payload do diff se parece com isto — as chaves são caminhos JSON na extração, e cada valor é um par {previous, current}:
JSON-mode diff
{
  "diff": {
    "json": {
      "plans[0].price": {
        "previous": "$19/mo",
        "current": "$24/mo"
      },
      "plans[1].features[2]": {
        "previous": "10 GB storage",
        "current": "25 GB storage"
      }
    }
  },
  "snapshot": {
    "json": {
      "plans": [
        {
          "name": "Starter",
          "price": "$24/mo",
          "features": ["Up to 3 users", "Basic analytics", "Email support"]
        },
        {
          "name": "Pro",
          "price": "$49/mo",
          "features": ["Unlimited users", "Advanced analytics", "25 GB storage"]
        }
      ]
    }
  }
}
Mesmo que nenhum campo rastreado tenha mudado, mas o markdown ao redor tenha sido alterado, os monitores no modo JSON ainda reportam same, a menos que você também habilite o git-diff (veja o modo misto abaixo). O diff se concentra exclusivamente nos campos do seu schema.

Modo misto (JSON + git-diff)

Se você quiser as duas saídas — o diff estruturado por campo e o diff unificado bruto em markdown — passe ambos os modos:
Mixed target (JSON + git-diff)
{
  "type": "scrape",
  "urls": ["https://example.com/pricing"],
  "scrapeOptions": {
    "formats": [
      {
        "type": "changeTracking",
        "modes": ["json", "git-diff"],
        "prompt": "Extract pricing tiers and headline features for each plan.",
        "schema": {
          "type": "object",
          "properties": {
            "plans": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": { "type": "string" },
                  "price": { "type": "string" }
                }
              }
            }
          }
        }
      }
    ]
  }
}
A resposta da verificação passa então a conter tanto diff.text (sidecar em markdown) quanto diff.json (diff por campo), junto com a extração snapshot.json:
Mixed-mode diff (JSON + git-diff)
{
  "diff": {
    "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Pricing\n-Starter — $19/mo\n+Starter — $24/mo\n",
    "json": {
      "plans[0].price": {
        "previous": "$19/mo",
        "current": "$24/mo"
      }
    }
  },
  "snapshot": {
    "json": {
      "plans": [
        { "name": "Starter", "price": "$24/mo" },
        { "name": "Pro", "price": "$49/mo" }
      ]
    }
  }
}
Uma página em modo misto indica changed sempre que qualquer uma das saídas mudar.

Notificações

Webhooks

Quando um monitor tem um webhook, o Firecrawl pode enviar dois eventos do monitor:
  • monitor.page: Enviado conforme cada scraping monitorado é concluído no worker de scraping.
  • monitor.check.completed: Enviado após a consolidação da verificação completa. Inclui o status da verificação e contagens de resumo. Use os eventos monitor.page ou a API de verificação do monitor para obter resultados por página.
monitor.page inclui isMeaningful e judgment quando a avaliação de alteração significativa é executada para uma página alterada.
Webhook config
{
  "webhook": {
    "url": "https://example.com/webhooks/firecrawl",
    "headers": {
      "Authorization": "Bearer your-secret"
    },
    "metadata": {
      "environment": "production"
    },
    "events": ["monitor.page", "monitor.check.completed"]
  }
}
Payload de monitor.page:
monitor.page
{
  "success": true,
  "type": "monitor.page",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0000-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "url": "https://example.com/blog",
      "status": "changed",
      "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
      "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
      "error": null,
      "isMeaningful": true,
      "judgment": {
        "meaningful": true,
        "confidence": "high",
        "reason": "The page headline changed to announce a new release cadence.",
        "meaningfulChanges": [
          {
            "type": "changed",
            "before": "Welcome to our weekly update.",
            "after": "Welcome to our weekly update — now with daily releases!",
            "reason": "The headline changed in a way that matches the monitor goal."
          }
        ]
      },
      "diff": {
        "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Latest posts\n-Welcome to our weekly update.\n+Welcome to our weekly update — now with daily releases!\n"
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}
Payload de monitor.check.completed:
monitor.check.completed
{
  "success": true,
  "type": "monitor.check.completed",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0001-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "status": "completed",
      "summary": {
        "totalPages": 2,
        "same": 1,
        "changed": 1,
        "new": 0,
        "removed": 0,
        "error": 0
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}
success é true quando a verificação é concluída sem erros de página. É false em verificações com falha ou parciais, e error contém o motivo da falha quando disponível.

Email

Os resumos por email são enviados somente quando uma verificação detecta páginas alteradas, novas, removidas ou com erro.
Email config
{
  "notification": {
    "email": {
      "enabled": true,
      "recipients": ["alerts@example.com"],
      "includeDiffs": true
    }
  }
}
Quando um monitor tem uma meta e a avaliação está habilitada, os resumos por email priorizam páginas alteradas significativas. Se todas as páginas alteradas forem classificadas como ruído e não houver páginas novas, removidas ou com erro, o email não será enviado. Se recipients for omitido, o Firecrawl enviará para os membros da equipe aptos a receber emails de alerta do sistema. Você pode configurar até 25 destinatários especificados.

Consultar resultados

Use GET /v2/monitor/{monitorId}/checks para listar verificações e GET /v2/monitor/{monitorId}/checks/{checkId} para inspecionar uma verificação. Os SDKs fazem paginação automática por padrão.
from firecrawl import Firecrawl

firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

check = firecrawl.get_monitor_check(monitor_id, check_id, limit=25, status="changed")

for page in check.pages:
    print(page.url, page.status)

    if page.judgment:
        print(page.judgment.meaningful, page.judgment.reason)

    if page.diff and page.diff.text:
        print(page.diff.text)

    if page.snapshot and page.snapshot.json:
        print(page.snapshot.json)
A lista de verificações pode ser filtrada pelo status da verificação: queued, running, completed, failed, partial ou skipped_overlap. A resposta de detalhes da verificação inclui estimatedCredits, actualCredits, contagens resumidas e um array pages paginado. estimatedCredits é a reserva no limite máximo para a verificação; actualCredits é o valor final cobrado depois que o Firecrawl determina quantas páginas mudaram e precisaram de avaliação. Use a URL next de nível superior para buscar a próxima página de resultados, seguindo a paginação do rastreamento. Você pode filtrar páginas por status: same, new, changed, removed ou error. Cada página alterada inclui dados de diff inline; páginas de monitores em modo JSON também incluem um snapshot com a extração atual.
Markdown-mode response
{
  "success": true,
  "next": "https://api.firecrawl.dev/v2/monitor/019df960-06e7-7383-9d89-82c0113dc31a/checks/019df960-5f2a-75fb-a98b-bd2d32ca67d4?skip=25&limit=25",
  "data": {
    "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
    "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
    "status": "completed",
    "estimatedCredits": 2,
    "actualCredits": 2,
    "summary": {
      "totalPages": 1,
      "same": 0,
      "changed": 1,
      "new": 0,
      "removed": 0,
      "error": 0
    },
    "pages": [
      {
        "id": "019df960-7708-7c62-a5dc-6206f16ac122",
        "targetId": "019df960-09bb-7c11-8001-1f12f50ab1c2",
        "url": "https://example.com/blog",
        "status": "changed",
        "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
        "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
        "statusCode": 200,
        "error": null,
        "metadata": {
          "title": "Example Blog",
          "creditsUsed": 1
        },
        "judgment": {
          "meaningful": true,
          "confidence": "high",
          "reason": "The page headline changed to announce a new release cadence.",
          "meaningfulChanges": [
            {
              "type": "changed",
              "before": "Welcome to our weekly update.",
              "after": "Welcome to our weekly update — now with daily releases!",
              "reason": "The headline changed in a way that matches the monitor goal."
            }
          ]
        },
        "createdAt": "2026-05-17T15:35:00.000Z",
        "diff": {
          "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Latest posts\n-Welcome to our weekly update.\n+Welcome to our weekly update — now with daily releases!\n",
          "json": {
            "files": [
              {
                "from": "previous",
                "to": "current",
                "chunks": []
              }
            ]
          }
        }
      }
    ],
    "next": "https://api.firecrawl.dev/v2/monitor/019df960-06e7-7383-9d89-82c0113dc31a/checks/019df960-5f2a-75fb-a98b-bd2d32ca67d4?skip=25&limit=25"
  }
}

Referência da API