webclaw

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/watch

Create 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

FieldTypeRequiredDescription
urlstringYesThe URL to monitor.
namestringNoHuman-readable label for the watch.
interval_minutesintegerNoCheck interval in minutes (60-10080). Default: 1440 (daily).
webhook_urlstringNoURL to receive POST notifications when changes are detected.

Interval options

IntervalMinutesCredits / month (est.)
Hourly60~720
Every 6 hours360~120
Daily1440~30
Weekly10080~4

List watches

GET/v1/watch

List 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

FieldTypeDescription
idstringUnique snapshot identifier.
content_hashstringHash of the extracted content for quick comparison.
word_countintegerWord count of the page content.
statusstring"initial" (first check), "same" (no change), or "changed".
titlestringPage title at check time.
diff_summarystring | nullAI-generated summary of what changed. Null for initial snapshots.
word_count_deltaintegerChange in word count from previous snapshot.
links_addedstring[]New links found on the page.
links_removedstring[]Links removed since last check.
checked_atstringISO 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}/check

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