Create a Firecrawl monitor — a recurring scrape, crawl, or search that diffs each result against the last retained snapshot.
Prefer the simple path: pass `page` or `pages` plus `goal` to monitor specific URLs, OR pass `queries` plus `goal` to monitor web search results for new/changed hits. The tool will create the monitor with a 30-minute schedule and meaningful-change judging enabled by the API. Use `body` only for advanced requests such as crawl targets, JSON change tracking, custom retention, or manual `judgeEnabled` control.
Meaningful-change judge: set `goal` to a plain-language description of what the user actually cares about. `judgeEnabled` defaults to true when `goal` is set, so providing `goal` is enough. Page webhooks expose `isMeaningful` and `judgment` on `monitor.page` events.
Simple fields:
- `page`: one page URL to monitor.
- `pages`: multiple page URLs to monitor.
- `queries`: one or more search queries (1-12) to monitor instead of fixed URLs. Each check runs the searches and diffs the result set, so you get alerted when new or changed results appear. Mutually exclusive with `page`/`pages` in the simple path.
- `searchWindow`: optional recency window for search targets — one of `5m`, `15m`, `1h`, `6h`, `24h`, `7d` (default `24h`).
- `maxResults`: optional max results per search, 1-50 (default 10).
- `includeDomains` / `excludeDomains`: optional domain allow/deny lists for search targets.
- `goal`: plain-English instruction for what changes matter. Required for the simple path (and always required when `queries` are set — web monitors must have a goal).
- `scheduleText`: optional natural-language schedule, default `every 30 minutes`.
- `email`: optional email recipient for summaries.
- `webhookUrl`: optional webhook URL. Configures `monitor.page` and `monitor.check.completed`.
**Search-mode example:**
```json
{
"name": "firecrawl_monitor_create",
"arguments": {
"queries": ["new LLM release", "frontier model launch"],
"goal": "Notify me about major new LLM model releases.",
"searchWindow": "24h",
"maxResults": 10
}
}
```
Goal guidance:
- Expand the user's one-line monitoring intent into a concise 2-3 sentence monitor goal.
- State what should trigger an alert, restate any scope the user gave, and include intent-specific exclusions only when obvious from the user's request.
- Generic noise such as whitespace, formatting-only changes, request IDs, tracking params, generic metadata, and unrelated page chrome is already handled by the judge; do not repeat it in every goal.
- If the user is vague, keep the goal broad rather than guessing exclusions. If the user asks for broad monitoring or "any change", preserve that and do not add exclusions that hide changes.
- If the user says they do not care about something, include that explicitly. It is okay to ask whether they want to ignore specific noise when it is likely to matter.
- Do not invent page-specific sections, thresholds, entities, or business rules unless the user mentioned them.
Query guidance (web monitors): `queries` control recall (what search retrieves) and `goal` controls precision (which results alert) — tune both.
- Write keywords, not sentences: `OpenAI new model release`, not `tell me when OpenAI releases a new model`.
- Quote multi-word entities (`"Llama 4"`); group synonyms with `OR` (`launch OR release OR announcement`).
- Keep each query tight (~2-6 terms). One broad query usually beats several narrow ones — extra queries split the `maxResults` budget. Use one query per distinct entity; do not emit one per facet of a single subject.
- Keep `site:` operators out of queries — use `includeDomains` / `excludeDomains`.
- A healthy web monitor mostly returns `new: 0` and alerts only on genuinely new, on-goal results. Many `ignored` results ⇒ queries too broad (tighten them); nothing for long stretches ⇒ queries too narrow or window too tight (broaden); dismissed alerts ⇒ goal too broad (add an intent-specific Ignore). Aim for high precision with enough recall.
Full `body` requests require: `name`, `schedule` (with `cron` or `text`), and `targets` (one or more `{ type: 'scrape', urls: [...] }`, `{ type: 'crawl', url: '...' }`, or `{ type: 'search', queries: [...], searchWindow?, maxResults?, includeDomains?, excludeDomains? }`). Optional: `goal` (required when any search target is present), `judgeEnabled`, `webhook`, `notification`, `retentionDays`.
**Markdown-mode (default):** Each check produces a unified text diff of the page's markdown. No extra configuration needed.
```json
{
"name": "firecrawl_monitor_create",
"arguments": {
"page": "https://example.com/blog",
"goal": "Alert when a new blog post is published or an existing headline changes.",
"email": "alerts@example.com"
}
}
```
**Multiple pages:**
```json
{
"name": "firecrawl_monitor_create",
"arguments": {
"pages": ["https://example.com/pricing", "https://example.com/changelog"],
"goal": "Alert when pricing, packaging, or launch messaging changes.",
"webhookUrl": "https://example.com/webhooks/firecrawl"
}
}
```
**JSON-mode change tracking:** To detect changes in **specific structured fields** (price, headline, in-stock flag, list items) instead of the whole page, add a `changeTracking` format with `modes: ["json"]` and a JSON schema to the target's `scrapeOptions.formats`. The check response will then carry a per-field diff (keyed by JSON path, e.g. `plans[0].price`) and a `snapshot.json` with the full current extraction. See `firecrawl_monitor_check` for the response shape.
```json
{
"name": "firecrawl_monitor_create",
"arguments": {
"body": {
"name": "Pricing watch",
"schedule": { "text": "hourly", "timezone": "UTC" },
"goal": "Alert when a pricing tier, price, billing period, limit, or headline feature changes. Ignore unrelated marketing copy unless it changes the pricing offer.",
"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" } }
}
}
}
}
}
}]
}
}]
}
}
}
```
**Mixed mode (JSON + git-diff):** Use `modes: ["json", "git-diff"]` to get both per-field diffs and a markdown sidecar. The page is marked `changed` whenever either surface changed.