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.
Firecrawl のモニターでは、定期的なスクレイピングまたはクロールを実行し、各結果を最後に保持されたスナップショットと比較します。モニターを使うと、商品ページ、ドキュメント、ブログ、変更履歴、競合サイトなど、変更の追跡が重要なページを監視できます。
各チェックでは、ページ単位の結果が same、new、changed、removed、error として記録されます。監視対象の各ページの処理完了時に webhook を受け取ることも、チェックが完了するたびに webhook を受け取ることも、変更やエラーが発生した際にメールで要約を受け取ることもでき、これらを自由に組み合わせることもできます。
モニタリングには、保持されたスナップショットと差分が必要です。ゼロデータ保持のチームでは利用できません。
1 つ以上の明示的な URL を対象としたスクレイピングモニターを作成します:
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)
各 チェック で、クロールによって検出されたすべてのページの差分を比較するクロールモニターを作成します:
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)
create の各呼び出しでは、正規化された cron、計算済みの nextRunAt、および estimatedCreditsPerMonth を含む新しいモニターが返されます。判定が有効な場合、estimatedCreditsPerMonth は上限見積もりになります。これは、判定クレジットが実際に判定された変更ページに対してのみ課金されるためです:
{
"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"
}
}
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
意味のある変更があったときだけ通知を受けたい場合は、平易な表現で goal を追加します。goal が指定されていて judgeEnabled が省略されている場合、Firecrawl は自動的に判定を有効にします。判定は変更のあったページで実行され、meaningful、confidence、reason、meaningfulChanges を含む judgment を返します。
変更の判定はまだ行わず、ゴールだけを保存したい場合は、judgeEnabled: false を使用します。判定が実行されるのは、モニター に judgeEnabled と空でない goal の両方が設定されている場合だけです。
各 チェック では、常に元となるスクレイピングまたはクロールの料金が発生します。判定が有効な場合、judge は検証した変更済みページごとに 1 クレジット を追加で消費します。変更されたページがない チェック では、judge クレジット は消費されません。
適切なゴールは、短く明確であることが重要です。何を alert のトリガーにするかを示し、top N、価格、役割の種類、会社、地域、トピック、status、またはエンティティなどの対象範囲も明記してください。除外条件は、意図に含まれる場合にのみ追加します。ゴールが広い場合は、その広さを保ってください。たとえば、“any change” の場合は、変更を見逃すようなノイズ除去の絞り込みを加えるべきではありません。
たとえば、次のような goal を持つ モニター では:
AIに関連する新しいHacker Newsのストーリーがトップ10に入ったときに通知する。AIに関係のないストーリーの変更は無視する。トップ10外の変更には通知しない。
一致するストーリーが監視対象に入ると、このような monitor.page webhook が生成されることがあります:
{
"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"
}
}
スケジュールは、cron またはシンプルな自然言語テキストで指定できます。
{
"schedule": {
"cron": "*/30 * * * *",
"timezone": "UTC"
}
}
サポートされている自然言語の例:
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
最小間隔は 15 分です。API レスポンスでは常に正規化された cron 式が返されます。テキストによるスケジュールでは、timezone が daily at 9am のような表現の実行時刻を制御します。テキストによるスケジュールは、cron に変換される前にモニター ID ごとに分散されるため、多数のモニターがまったく同じタイミングで実行されることはありません。
モニターでは、2 種類のターゲットをサポートしています。
scrape: urls 内の各 URL に対して 1 回スクレイピングを実行します。
crawl: 各チェックで url に対して完全なクロールを実行し、検出されたすべてのページの差分を比較します。
各モニターには 1~50 個のターゲットを指定できます。retentionDays のデフォルトは 30 で、最大 365 まで設定できます。
ターゲットのスクレイピングのオプションは、そのまま基盤となるスクレイピング ジョブに渡されます。モニターによってトリガーされたスクレイピングでは、maxAge のデフォルトが 0 になるため、明示的に別の maxAge を設定しない限り、各チェックで毎回新しくスクレイピングが実行されます。
{
"type": "scrape",
"urls": ["https://example.com/pricing"],
"scrapeOptions": {
"formats": ["markdown"],
"maxAge": 0
}
}
クロール ターゲットでは、クロールの動作には crawlOptions を、各ページのスクレイピングには scrapeOptions を使用します。
{
"type": "crawl",
"url": "https://example.com/docs",
"crawlOptions": {
"limit": 100,
"includePaths": ["/docs"]
},
"scrapeOptions": {
"formats": ["markdown"]
}
}
デフォルトでは、Firecrawl は各ページの Markdown の差分を比較し、same、changed、new、removed、error のいずれかを返します。特定の構造化フィールド (価格、見出し、在庫フラグ、リスト内の項目など) の変更を検出したい場合は、対象の scrapeOptions に modes: ["json"] を指定した changeTracking フォーマットを追加して、JSON モードの変更追跡を有効にします。
scrapeOptions.formats が ["markdown"] のみの場合、チェック レスポンス内の変更された各ページには、unified 形式のテキスト差分と、parseDiff スタイルの AST が含まれます。
{
"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": []
}
]
}
]
}
}
}
modes: ["json"] を指定した changeTracking フォーマットを、注目するフィールドを定義した JSON schema (または prompt) とあわせて渡します。Firecrawl はチェックのたびにその JSON を抽出し、フィールドパスをキーとするフィールド単位の差分を出力します。さらに、利用側で元のスクレイピング結果を再取得しなくて済むよう、現在の抽出結果全体を含む snapshot.json も出力します。
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)
差分の ペイロード は次のようになります。キーは抽出結果内の JSON パスで、各値は {previous, current} のペアです。
{
"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"]
}
]
}
}
}
追跡対象のフィールドに変更がなく、周囲の Markdown だけが変わった場合でも、git-diff も有効にしない限り (下記の mixed mode を参照) 、JSONモードのモニターは same を返します。この差分は、schema 内のフィールドだけに焦点を当てています。
Mixedモード (JSON + git-diff)
構造化されたフィールド単位の差分 と 生の markdown の unified diff の両方が必要な場合は、両方のモードを指定します。
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" }
}
}
}
}
}
}
]
}
}
すると、チェック レスポンスには snapshot.json の抽出結果に加えて、diff.text (markdown のサイドカー) と diff.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" }
]
}
}
}
mixed-mode のページでは、いずれか 一方でも変更があれば changed が報告されます。
モニター に webhook が設定されている場合、Firecrawl は 2 つの モニター event を送信できます。
monitor.page: 監視対象の各ページのスクレイピングが scrape worker で完了するたびに送信されます。
monitor.check.completed: チェック全体の整合処理が完了した後に送信されます。チェック の status と集計数が含まれます。ページ単位の結果を確認するには、monitor.page event または モニター check API を使用してください。
monitor.page には、変更されたページに対して意味のある変更の判定が実行された場合、isMeaningful と judgment が含まれます。
{
"webhook": {
"url": "https://example.com/webhooks/firecrawl",
"headers": {
"Authorization": "Bearer your-secret"
},
"metadata": {
"environment": "production"
},
"events": ["monitor.page", "monitor.check.completed"]
}
}
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"
}
}
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 です。失敗した チェック または部分的な チェック の場合は false となり、利用可能であれば error に失敗理由が含まれます。
メールの要約は、チェックで変更・新規追加・削除・エラーのいずれかに該当するページがあった場合にのみ送信されます。
{
"notification": {
"email": {
"enabled": true,
"recipients": ["alerts@example.com"],
"includeDiffs": true
}
}
}
モニターでゴールが設定され、判定が有効になっている場合、メールの要約では重要な変更ページが優先されます。変更されたすべてのページがノイズと判定され、新規追加・削除・エラーに該当するページもない場合、メールは送信されません。
recipients を省略すると、Firecrawl はシステムアラートメールの受信対象となるチームメンバーに送信します。
明示的な受信者は最大 25 件まで設定できます。
GET /v2/monitor/{monitorId}/checks でチェックの一覧を取得し、GET /v2/monitor/{monitorId}/checks/{checkId} で個別のチェック詳細を確認できます。SDKs はデフォルトで自動的にページネーションに対応しています。
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)
チェック一覧は、チェックの status で絞り込めます: queued、running、completed、failed、partial、skipped_overlap。
チェック詳細のレスポンスには、estimatedCredits、actualCredits、集計件数、およびページネーションされた pages 配列が含まれます。estimatedCredits はそのチェックに対して上限として予約されるクレジット数で、actualCredits は Firecrawl が変更されたページ数と判定が必要なページ数を把握した後に確定する最終的な請求量です。結果の次のページを取得するには、トップレベルの next URL を使用します。これはクロールのページネーションと同じです。ページは status で絞り込めます: same、new、changed、removed、error。変更された各ページにはインラインの diff データが含まれます。JSONモードのモニターによるページには、現在の抽出結果を含む snapshot も含まれます。
Markdownモード
JSONモード
Mixedモード
{
"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"
}
}
{
"success": true,
"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/pricing",
"status": "changed",
"previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
"currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
"statusCode": 200,
"error": null,
"metadata": {
"title": "Pricing",
"creditsUsed": 1
},
"judgment": {
"meaningful": true,
"confidence": "high",
"reason": "The Starter plan price and Pro storage limit changed.",
"meaningfulChanges": [
{
"type": "changed",
"before": "$19/mo",
"after": "$24/mo",
"reason": "The Starter plan price changed."
},
{
"type": "changed",
"before": "10 GB storage",
"after": "25 GB storage",
"reason": "The Pro storage limit changed."
}
]
},
"createdAt": "2026-05-17T15:35:00.000Z",
"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"]
}
]
}
}
}
]
}
}
Mixed-mode response (JSON + git-diff)
{
"success": true,
"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/pricing",
"status": "changed",
"previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
"currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
"statusCode": 200,
"error": null,
"metadata": {
"title": "Pricing",
"creditsUsed": 1
},
"judgment": {
"meaningful": true,
"confidence": "high",
"reason": "The Starter plan price changed.",
"meaningfulChanges": [
{
"type": "changed",
"before": "Starter — $19/mo",
"after": "Starter — $24/mo",
"reason": "The Starter plan price changed."
}
]
},
"createdAt": "2026-05-17T15:35:00.000Z",
"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" }
]
}
}
}
]
}
}