Watch
Monitor any URL for content changes. Webclaw periodically scrapes the page, compares it to the previous snapshot, and notifies you via webhook when something changes.
Note
Maximum 20 watches per user. Each check consumes 1 scrape credit.
Create a watch
POST
/v1/watchCreate a new URL watch with a check interval and optional webhook.
json
{
"url": "https://example.com/pricing",
"name": "Example Pricing Page",
"interval_minutes": 1440,
"webhook_url": "https://hooks.example.com/webclaw"
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The URL to monitor. |
name | string | No | Human-readable label for the watch. |
interval_minutes | integer | No | Check interval in minutes (60-10080). Default: 1440 (daily). |
webhook_url | string | No | URL to receive POST notifications when changes are detected. |
Interval options
| Interval | Minutes | Credits / month (est.) |
|---|---|---|
| Hourly | 60 | ~720 |
| Every 6 hours | 360 | ~120 |
| Daily | 1440 | ~30 |
| Weekly | 10080 | ~4 |
List watches
GET
/v1/watchList all watches for the authenticated user.
json
// Query params: ?limit=20&offset=0
{
"watches": [
{
"id": "wtc_8f3a1b2c",
"url": "https://example.com/pricing",
"name": "Example Pricing Page",
"interval_minutes": 1440,
"webhook_url": "https://hooks.example.com/webclaw",
"active": true,
"last_checked_at": "2026-03-19T08:00:00Z",
"last_status": "same",
"created_at": "2026-03-10T14:22:00Z"
}
]
}Watch details
GET
/v1/watch/{id}Get a watch and its snapshot timeline.
json
{
"id": "wtc_8f3a1b2c",
"url": "https://example.com/pricing",
"name": "Example Pricing Page",
"interval_minutes": 1440,
"webhook_url": "https://hooks.example.com/webclaw",
"active": true,
"created_at": "2026-03-10T14:22:00Z",
"snapshots": [
{
"id": "snap_d4e5f6",
"content_hash": "a1b2c3d4e5f6",
"word_count": 1240,
"status": "changed",
"title": "Pricing — Example",
"diff_summary": "Added new Enterprise tier at $499/mo",
"word_count_delta": 85,
"links_added": ["https://example.com/enterprise"],
"links_removed": [],
"checked_at": "2026-03-19T08:00:00Z"
},
{
"id": "snap_a1b2c3",
"content_hash": "f6e5d4c3b2a1",
"word_count": 1155,
"status": "initial",
"title": "Pricing — Example",
"diff_summary": null,
"word_count_delta": 0,
"links_added": [],
"links_removed": [],
"checked_at": "2026-03-10T14:22:00Z"
}
]
}Snapshot object
| Field | Type | Description |
|---|---|---|
id | string | Unique snapshot identifier. |
content_hash | string | Hash of the extracted content for quick comparison. |
word_count | integer | Word count of the page content. |
status | string | "initial" (first check), "same" (no change), or "changed". |
title | string | Page title at check time. |
diff_summary | string | null | AI-generated summary of what changed. Null for initial snapshots. |
word_count_delta | integer | Change in word count from previous snapshot. |
links_added | string[] | New links found on the page. |
links_removed | string[] | Links removed since last check. |
checked_at | string | ISO 8601 timestamp of the check. |
Update a watch
PATCH
/v1/watch/{id}Update watch settings. Only provided fields are changed.
json
{
"name": "Updated Name",
"interval_minutes": 360,
"webhook_url": "https://hooks.example.com/new-endpoint",
"active": false
}Delete a watch
DELETE
/v1/watch/{id}Permanently remove a watch and all its snapshots.
Trigger manual check
POST
/v1/watch/{id}/checkImmediately check the URL and create a new snapshot. Costs 1 scrape credit.
json
{
"snapshot": {
"id": "snap_g7h8i9",
"content_hash": "b2c3d4e5f6a1",
"word_count": 1290,
"status": "changed",
"title": "Pricing — Example",
"diff_summary": "Updated Enterprise tier pricing from $499 to $449/mo",
"word_count_delta": 50,
"links_added": [],
"links_removed": [],
"checked_at": "2026-03-19T15:30:00Z"
}
}Webhook payload
When a change is detected and a webhook_url is configured, Webclaw sends a POST request with this payload:
json
{
"event": "watch.changed",
"watch_id": "wtc_8f3a1b2c",
"url": "https://example.com/pricing",
"name": "Example Pricing Page",
"snapshot": {
"id": "snap_g7h8i9",
"status": "changed",
"diff_summary": "Updated Enterprise tier pricing from $499 to $449/mo",
"word_count": 1290,
"word_count_delta": 50,
"links_added": [],
"links_removed": [],
"checked_at": "2026-03-19T15:30:00Z"
}
}SDK examples
Python
python
from webclaw import Webclaw
client = Webclaw(api_key="wc_...")
# Create a daily watch
watch = client.watch.create(
url="https://example.com/pricing",
name="Pricing Page",
interval_minutes=1440,
webhook_url="https://hooks.example.com/webclaw"
)
# List all watches
watches = client.watch.list()
# Trigger a manual check
snapshot = client.watch.check(watch.id)
print(snapshot.diff_summary)TypeScript
typescript
import Webclaw from "@webclaw/sdk";
const client = new Webclaw({ apiKey: "wc_..." });
// Create a daily watch
const watch = await client.watch.create({
url: "https://example.com/pricing",
name: "Pricing Page",
intervalMinutes: 1440,
webhookUrl: "https://hooks.example.com/webclaw",
});
// List all watches
const { watches } = await client.watch.list();
// Trigger a manual check
const snapshot = await client.watch.check(watch.id);
console.log(snapshot.diffSummary);cURL
bash
# Create a watch
curl -X POST https://api.webclaw.io/v1/watch \
-H "Authorization: Bearer wc_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/pricing", "interval_minutes": 1440}'
# List watches
curl https://api.webclaw.io/v1/watch \
-H "Authorization: Bearer wc_..."
# Trigger manual check
curl -X POST https://api.webclaw.io/v1/watch/wtc_8f3a1b2c/check \
-H "Authorization: Bearer wc_..."Note
Watches are paused automatically if 3 consecutive checks fail (e.g. the page returns 404). Update the watch with
active: true to resume.