Website Monitoring
Watch any page for changes on a schedule — get a webhook or email when it changes
Last updated Jul 22, 2026
The Website Monitoring API watches a URL on a schedule, captures a snapshot on every check, and records a change whenever the page differs from the previous snapshot. Each detected change can fire a signed webhook and/or email alert.
It reuses the same scraping pipeline as the URL Scraper (proxies, browser rendering, authenticated sessions), so anything you can scrape, you can monitor.
A monitor's scope is page (default) — watch one URL — site — crawl the whole site each run and track pages added, removed, and changed (see Site monitors) — or wire — run a managed Wire API action each run and diff the JSON it returns, for sites with no public API of their own (see Wire monitors).
How it works
- Create a monitor with a URL, a schedule (
intervalMinutes), and what to watch. - On every check the monitor scrapes the page and stores a snapshot.
- If the new snapshot differs from the last one, a change is recorded.
- If alerts are configured, the change is delivered to your webhook / email.
What to watch
watchMode | What it compares | Cost / check |
|---|---|---|
full_page (default) | The whole page body, in the watchFormat you choose (markdown, html, or cleaned_html). | 2 credits |
specific_data | Only the fields in your outputSchema (JSON Schema), extracted with AI. Ideal for price / stock / status tracking. | 3 credits |
Enabling AI meaningful-change (aiMode: true) filters out trivial noise (ads, timestamps) and summarizes real changes — it adds +1 credit per check.
The Monitor object
{
"id": "b1e7…",
"userId": "u_123",
"url": "https://example.com/product/123",
"scope": "page",
"maxPages": null,
"maxDepth": null,
"includePatterns": [],
"excludePatterns": [],
"excludedUrls": [],
"watchMode": "specific_data",
"watchFormat": "markdown",
"useBrowser": false,
"country": "us",
"sessionId": null,
"sessionExpired": false,
"outputSchema": { "type": "object", "properties": { "price": { "type": "number" } }, "required": ["price"] },
"aiMode": true,
"aiGoal": "only when the price drops or it goes out of stock",
"intervalMinutes": 60,
"isActive": true,
"nextRunAt": "2026-01-01T12:00:00Z",
"lastCheckedAt": "2026-01-01T11:00:00Z",
"creditCostPerRun": 4,
"alertWebhookUrl": "https://your-app.com/hooks/anakin",
"alertWebhookSecret": "whsec_…",
"alertEmails": "you@example.com",
"lastAlertedAt": "2026-01-01T11:00:00Z",
"createdAt": "2025-12-01T09:00:00Z",
"updatedAt": "2025-12-15T09:00:00Z"
}| Field | Type | Description |
|---|---|---|
id | string | Monitor ID. |
url | string | The monitored URL (root URL for site scope; the Wire site's URL for wire scope). |
scope | string | page, site, or wire. See Site monitors and Wire monitors. |
maxPages, maxDepth | number | null | Site scope: pages-per-run cap and crawl depth. |
includePatterns, excludePatterns, excludedUrls | string[] | Site scope: pages to track (hand-picked full URLs, crawled directly) and/or include/exclude globs, plus pages removed from tracking. |
wireActionId | string | null | Wire scope: the Wire action run each check (e.g. amazon.search_products). |
wireCatalogSlug | string | null | Wire scope: catalogue slug of the Wire site. |
wireCredentialId | string | null | Wire scope: connected credential id, when the action needs auth. |
wireParams | object | null | Wire scope: parameters passed to the action. |
wireWatchPaths | string[] | null | Wire scope: JSON paths to diff instead of the whole response. |
watchMode | string | full_page or specific_data. |
watchFormat | string | For full_page: markdown, html, or cleaned_html. Always markdown for specific_data. |
useBrowser | boolean | Whether checks render with a headless browser. Forced true when a sessionId is set. |
country | string | Proxy country code. See Supported Countries. |
sessionId | string | null | Saved browser session used for authenticated pages. |
sessionExpired | boolean | true when the saved session is no longer valid (the monitor is paused until re-auth). |
outputSchema | object | null | JSON Schema of the tracked fields (specific_data mode). |
aiMode | boolean | AI meaningful-change filtering is on. |
aiGoal | string | null | Optional natural-language description of which changes count as meaningful. |
intervalMinutes | number | Check frequency. Minimum 15. |
isActive | boolean | Whether the monitor is running (false = paused). |
expiresAt | string | null | Optional end date; the monitor auto-pauses when it passes. |
expired | boolean | true once the end date has passed (cleared on resume / new expiry). |
nextRunAt | string | ISO 8601 timestamp of the next scheduled check. |
lastCheckedAt | string | null | ISO 8601 timestamp of the most recent check. |
creditCostPerRun | number | Credits deducted per check (2/3 by mode, +1 with aiMode). |
alertWebhookUrl | string | null | Webhook that receives change alerts. |
alertWebhookSecret | string | null | HMAC signing secret for the webhook (see Alerts). |
alertEmails | string | null | Comma-separated email recipients. |
lastAlertedAt | string | null | ISO 8601 timestamp of the last alert sent. |
Limits
- Minimum interval: 15 minutes.
- Active monitors per plan: Free
5, Pro20, Scale100. Creating or resuming past the cap returns402 monitor_limit_reached.
Endpoints
/v1/monitorsCreate a monitor
/v1/monitorsList monitors, or get one by ID
/v1/monitors/{id}Update or delete a monitor
/v1/monitors/{id}/runPause, resume, or run a check now
/v1/monitors/{id}/changesSnapshots & detected changes
/v1/monitors/{id}/test-alertAlerts, deliveries & webhook signing