> ## 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.

# 监控

> 设置定期检查，检测变更，并通过 Webhook 或电子邮件接收通知

Firecrawl 监控会定期执行检查，并在有内容发生变化或出现新内容时通知你或你的代理。使用 `/monitor` 可以[监视已知页面](/zh/features/monitoring-page)、[按计划爬取网站](/zh/features/monitoring-website)，或[持续运行网页搜索](/zh/features/monitoring-web-scale)，以查找与某个目标匹配的新结果。

所有监控类型都遵循相同的工作流：选择一个或多个目标，设置计划，添加一个可选的自然语言目标描述，并在有重要变化时接收 Webhook 或电子邮件通知。本页介绍通用配置。若要查看特定目标的设置和示例，请前往 [Page](/zh/features/monitoring-page)、[Website](/zh/features/monitoring-website) 或 [Entire web-scale](/zh/features/monitoring-web-scale) 监控页面。

<CardGroup cols={3}>
  <Card title="页面监控" icon="file-lines" href="/zh/features/monitoring-page">
    监视一个或多个已知 URL，将每次抓取与上一次快照进行 diff，并在页面发生有意义的变化时触发告警。
  </Card>

  <Card title="网站监控" icon="spider" href="/zh/features/monitoring-website">
    按计划爬取网站，检测新增、变更或移除的页面，并通知你的 Webhook 或收件箱。
  </Card>

  <Card title="全网页规模监控" icon="globe" href="/zh/features/monitoring-web-scale">
    定期运行网页搜索，并在出现与你的目标匹配的新结果时触发告警。
  </Card>
</CardGroup>

每次检查都会将页面级结果记录为 `same`、`new`、`changed`、`removed` 或 `error`。你可以在每个受监控页面处理完成时接收 Webhook，也可以在每次检查完成后接收一个 Webhook；还可以在发生更改或错误时接收电子邮件摘要，或组合使用这些通知方式。

<div className="firecrawl-cta-box" style={{ opacity: 0.6 }}>
  <div style={{ display: "flex", alignItems: "flex-start", gap: "8px", marginBottom: "8px" }}>
    <Icon icon="sack-dollar" color="#9ca3af" size={22} />

    <div className="firecrawl-cta-title" style={{ margin: 0, color: "#9ca3af" }}>
      <span>已结束：/monitor 反馈悬赏</span>
    </div>
  </div>

  <p className="firecrawl-cta-description">
    所有符合悬赏奖励资格的受访者均已联系。请关注我们文档中未来的悬赏活动！
  </p>
</div>

<div id="targets">
  ## 目标
</div>

每个监控都有一个或多个**目标**。目标类型决定了每次检查会执行什么：

| 目标       | 监控内容        | 设置方式                                         |
| -------- | ----------- | -------------------------------------------- |
| `scrape` | 你指定的已知 URL  | [页面监控](/zh/features/monitoring-page)         |
| `crawl`  | 通过爬取发现的每个页面 | [网站监控](/zh/features/monitoring-website)      |
| `search` | 整个网页中的新结果   | [全网页规模监控](/zh/features/monitoring-web-scale) |

每个监控支持 1–50 个目标，并且你可以在同一个监控中混合使用不同的目标类型。`retentionDays` 的默认值为 `30`，最高可设置为 `365`。

每次创建调用都会返回新创建的监控，其中包含规范化后的 cron、计算得出的 `nextRunAt` 和 `estimatedCreditsPerMonth`。启用判定后，`estimatedCreditsPerMonth` 是一个上限估算值，因为判定额度只会对实际发生变化且被判定的页面计费：

```json Response theme={null}
{
  "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"
  }
}
```

<div id="goals-and-judging">
  ## 目标与判定
</div>

如果你只想在发生有意义的变化时收到告警，请添加一个通俗易懂的 `goal`。如果设置了 `goal` 但省略了 `judgeEnabled`，Firecrawl 会自动启用判定。判定会在已发生变化的页面上运行，并返回一个 `judgment`，其中包含 `meaningful`、`confidence`、`reason` 和 `meaningfulChanges`。

目标如何应用取决于目标：[page](/zh/features/monitoring-page) 和 [website](/zh/features/monitoring-website) 监控会对已发生变化的页面进行判定，而 [entire web-scale monitors](/zh/features/monitoring-web-scale#judging) 会对每个新的搜索结果进行判定。

如果你想先保存目标、暂时不对变化进行判定，请使用 `judgeEnabled: false`。只有当监控同时设置了 `judgeEnabled` 且 `goal` 非空时，判定器才会运行。

<Note>
  对于 `search` 目标 (全网页规模监控) ，除非你设置了 `judgeEnabled: false`，否则 `goal` 为必填。对于 `scrape` 和 `crawl` 目标，则为可选。
</Note>

<Note>
  每次检查都会对底层抓取或爬取照常计费。如果启用了判定，判定器还会为其验证的每个已发生变化的页面额外收取 1 个额度。没有已发生变化页面的检查不会消耗判定额度。
</Note>

好的目标应简短且明确：说明什么情况应触发告警，重申任何范围限制，例如前 N 项、价格、角色类型、公司、地区、主题、状态或实体，并且仅在排除条件本身属于目标意图时才写入。如果目标范围较宽泛，就保持宽泛；例如，"任何变化" 不应再加入会掩盖变化的噪声过滤条件。

例如，一个具有以下目标的监控：

```text theme={null}
当与 AI 相关的新 Hacker News 故事进入前 10 时发出告警。忽略与 AI 无关的故事的变动。不对前 10 以外的变动发出告警。
```

当匹配的故事进入监控范围时，可能会生成如下这样的 `monitor.page` Webhook：

```json monitor.page theme={null}
{
  "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"
  }
}
```

<div id="schedules">
  ## 调度计划
</div>

调度计划可以使用 cron 表达式或简单的自然语言文本来设置。

<CodeGroup>
  ```json Cron theme={null}
  {
    "schedule": {
      "cron": "*/30 * * * *",
      "timezone": "UTC"
    }
  }
  ```

  ```json Text theme={null}
  {
    "schedule": {
      "text": "every 30 minutes",
      "timezone": "UTC"
    }
  }
  ```
</CodeGroup>

支持的自然语言示例：

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

最短间隔为 5 分钟。API 响应始终返回规范化后的 cron 表达式。对于文本调度计划，`timezone` 用于控制像 `daily at 9am` 这类短语何时运行。文本调度计划在转换为 cron 之前，会先按监控 ID 错开分布，因此多个监控不会在同一时刻同时运行。

<div id="change-tracking">
  ## 变更追踪
</div>

[页面](/zh/features/monitoring-page) 和 [网站](/zh/features/monitoring-website) 监控默认会比较每个页面的 markdown 差异，并报告 `same`、`changed`、`new`、`removed` 或 `error`。如果你想检测**特定结构化字段** (如价格、标题、库存状态标记、列表中的条目等) 的变化，请在目标的 `scrapeOptions` 中添加 `changeTracking` 格式，并设置 `modes: ["json"]`，以启用 JSON 模式的变更追踪。

<Note>
  变更追踪适用于 `scrape` 和 `crawl` 目标。面向整个网页规模的 (`search`) 监控会针对新结果触发告警，而不是比较已知页面的差异。请参见 [Statuses and dedup](/zh/features/monitoring-web-scale#statuses-and-dedup)。
</Note>

<div id="markdown-mode-default">
  ### Markdown 模式 (默认)
</div>

当 `scrapeOptions.formats` 仅为 `["markdown"]` 时，检查 响应中的每个已变更页面都会附带统一文本 diff，以及一个 [parseDiff](https://github.com/sergeyt/parse-diff) 风格的 AST：

```json Markdown-mode diff theme={null}
{
  "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": []
            }
          ]
        }
      ]
    }
  }
}
```

<div id="json-mode">
  ### JSON 模式
</div>

传入 `changeTracking` 格式并设置 `modes: ["json"]`，同时提供一个 JSON schema (或用于描述你关注字段的 `prompt`) 。Firecrawl 会在每次检查时提取该 JSON，并输出一个**按字段区分的差异**，以字段路径作为键；此外还会附带一个包含当前完整提取结果的 `snapshot.json`，这样消费方就无需重新获取底层 抓取 结果。

<CodeGroup>
  ```python Python theme={null}
  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)
  ```

  ```js Node theme={null}
  import Firecrawl from "@mendable/firecrawl-js";
  import { z } from "zod";

  const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

  const pricingSchema = z.object({
    plans: z.array(
      z.object({
        name: z.string(),
        price: z.string(),
        features: z.array(z.string()),
      }),
    ),
  });

  const monitor = await firecrawl.createMonitor({
    name: "Pricing monitor",
    schedule: { text: "hourly", timezone: "UTC" },
    goal: "Notify me when a pricing tier, price, or headline feature changes",
    notification: {
      email: {
        enabled: true,
        recipients: ["alerts@example.com"],
        includeDiffs: true,
      },
    },
    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: pricingSchema,
            },
          ],
        },
      },
    ],
  });

  console.log(monitor.id);
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.firecrawl.dev/v2/monitor" \
    -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Pricing monitor",
      "schedule": {
        "text": "hourly",
        "timezone": "UTC"
      },
      "goal": "Notify me when a pricing tier, price, or headline feature changes",
      "notification": {
        "email": {
          "enabled": true,
          "recipients": ["alerts@example.com"],
          "includeDiffs": true
        }
      },
      "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": {
                  "type": "object",
                  "properties": {
                    "plans": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": { "type": "string" },
                          "price": { "type": "string" },
                          "features": {
                            "type": "array",
                            "items": { "type": "string" }
                          }
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }'
  ```
</CodeGroup>

diff 载荷使用提取结果中的 JSON 路径作为键。每个值都是一个 `{previous, current}` 对：

```json JSON-mode diff theme={null}
{
  "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"]
        }
      ]
    }
  }
}
```

<Note>
  即使被跟踪的字段都没有变化，但周围的 markdown 发生了变化，JSON 模式监控仍会报告 `same`，除非你同时启用 git-diff (请参见下方的混合模式) 。该 diff 只关注 schema 中定义的字段。
</Note>

<div id="mixed-mode-json-git-diff">
  ### 混合模式 (JSON + git-diff)
</div>

如果你同时需要结构化的逐字段差异 **以及** 原始 markdown 统一 diff，请同时传入这两种模式：

```json Mixed target (JSON + git-diff) theme={null}
{
  "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" }
                }
              }
            }
          }
        }
      }
    ]
  }
}
```

随后，检查 响应会同时包含 `diff.text` (markdown sidecar) 和 `diff.json` (逐字段差异) ，以及提取得到的 `snapshot.json`：

```json Mixed-mode diff (JSON + git-diff) theme={null}
{
  "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" }
      ]
    }
  }
}
```

混合模式页面会在**任一**结果形式发生变化时报告 `changed`。

<div id="notifications">
  ## 通知
</div>

<div id="webhooks">
  ### Webhooks
</div>

当监控配置了 `webhook` 时，Firecrawl 可以发送两种监控事件：

* `monitor.page`：每个被监控的 抓取 在 抓取 worker 中完成后发送。
* `monitor.check.completed`：在完整检查完成汇总后发送。包含检查状态和汇总计数。页面级结果请使用 `monitor.page` 事件或监控检查 API。

如果对已变更页面执行了有意义变更判定，`monitor.page` 会包含 `isMeaningful` 和 `judgment`。

```json Webhook config theme={null}
{
  "webhook": {
    "url": "https://example.com/webhooks/firecrawl",
    "headers": {
      "Authorization": "Bearer your-secret"
    },
    "metadata": {
      "environment": "production"
    },
    "events": ["monitor.page", "monitor.check.completed"]
  }
}
```

`monitor.page` 载荷：

```json monitor.page theme={null}
{
  "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` 载荷：

```json monitor.check.completed theme={null}
{
  "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` 会包含失败原因。

<div id="email">
  ### 电子邮件
</div>

仅当某次检查出现页面变更、新增、移除或报错时，才会发送电子邮件摘要。

```json Email config theme={null}
{
  "notification": {
    "email": {
      "enabled": true,
      "recipients": ["alerts@example.com"],
      "includeDiffs": true
    }
  }
}
```

当某个监控设置了目标并启用判定后，电子邮件摘要会优先展示有意义的变更页面。如果所有变更页面都被判定为噪声，且没有新增、移除或报错的页面，则会抑制发送该电子邮件。

如果省略 `recipients`，Firecrawl 会将邮件发送给有资格接收系统告警邮件的团队成员。
你最多可以配置 25 个明确指定的收件人。

<div id="recipient-confirmation-process">
  #### 收件人确认流程
</div>

当有新的收件人被添加到某项监控时，Firecrawl 会向其发送一封包含确认链接的电子邮件，以确保对方明确同意接收该监控的通知。如果收件人已是团队成员，则无需确认。

<div id="check-results">
  ## 查看检查结果
</div>

使用 `GET /v2/monitor/{monitorId}/checks` 获取检查列表，使用 `GET /v2/monitor/{monitorId}/checks/{checkId}` 查看某次检查的详情。SDKs 默认会自动处理分页。

<CodeGroup>
  ```python Python theme={null}
  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)
  ```

  ```js Node theme={null}
  import Firecrawl from "@mendable/firecrawl-js";

  const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

  const check = await firecrawl.getMonitorCheck(monitorId, checkId, {
    limit: 25,
    status: "changed",
  });

  for (const page of check.pages) {
    console.log(page.url, page.status);

    if (page.judgment) {
      console.log(page.judgment.meaningful, page.judgment.reason);
    }

    if (page.diff?.text) {
      console.log(page.diff.text);
    }

    if (page.snapshot?.json) {
      console.log(page.snapshot.json);
    }
  }
  ```

  ```bash cURL theme={null}
  curl "https://api.firecrawl.dev/v2/monitor/$MONITOR_ID/checks/$CHECK_ID?limit=25&status=changed" \
    -H "Authorization: Bearer $FIRECRAWL_API_KEY"
  ```
</CodeGroup>

检查列表可按检查 `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`。

<Tabs>
  <Tab title="Markdown 模式">
    ```json Markdown-mode response theme={null}
    {
      "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"
      }
    }
    ```
  </Tab>

  <Tab title="JSON 模式">
    ```json JSON-mode response theme={null}
    {
      "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"]
                  }
                ]
              }
            }
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="混合模式">
    ```json Mixed-mode response (JSON + git-diff) theme={null}
    {
      "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" }
                ]
              }
            }
          }
        ]
      }
    }
    ```
  </Tab>
</Tabs>

<div id="pricing">
  ## 定价
</div>

监控不单独按每个监控收费。每次检查都按其执行的底层 抓取、爬取 或 搜索 计费；此外，如果启用了有效变更判定，则每个发生变更且经判定器确认的页面还会额外消耗 1 个额度。

| 组件                              | 额度                                 |
| ------------------------------- | ---------------------------------- |
| 抓取 监控                           | 每次检查每个 URL 1 个额度                   |
| 爬取 监控                           | 每次检查每个发现的页面 1 个额度                  |
| 网页 监控                           | 每次检查每 10 个结果 2 个额度                 |
| 网页 监控判定                         | 启用 AI 判定时，每个判定结果 1 个额度 (包含抓取和评估结果) |
| 启用有效变更判定                        | 每个经判定器确认的变更页面额外 1 个额度              |
| 格式附加项 (JSON、PDF、question、增强模式等) | 与单独使用 [抓取](/zh/features/scrape) 相同 |

<div id="api-reference">
  ## API 参考
</div>

* [创建监控](/zh/api-reference/endpoint/monitor-create)
* [查看监控列表](/zh/api-reference/endpoint/monitor-list)
* [获取监控](/zh/api-reference/endpoint/monitor-get)
* [更新监控](/zh/api-reference/endpoint/monitor-update)
* [删除监控](/zh/api-reference/endpoint/monitor-delete)
* [运行监控](/zh/api-reference/endpoint/monitor-run)
* [查看监控检查列表](/zh/api-reference/endpoint/monitor-checks-list)
* [获取监控检查](/zh/api-reference/endpoint/monitor-check-get)
* [监控页面 Webhook 载荷](/zh/api-reference/endpoint/webhook-monitor-page)
* [监控检查完成 Webhook 载荷](/zh/api-reference/endpoint/webhook-monitor-check-completed)
