💡 Try this endpoint in the Playground →

Page Monitoring

Monitor web pages for content changes on a schedule. When a change is detected, WebPeel calls your webhook with a diff of what changed.

All watch endpoints require authentication. Watches are scoped to your account — you can only read and modify your own watches.

Endpoints

POST/v1/watchAuth Required

Create a new watch on a URL.

GET/v1/watchAuth Required

List all watches for your account.

GET/v1/watch/:idAuth Required

Get details for a single watch.

POST/v1/watch/:id/checkAuth Required

Manually trigger an immediate content check.

PATCH/v1/watch/:idAuth Required

Update a watch — change interval, webhook URL, pause, or resume.

DELETE/v1/watch/:idAuth Required

Delete a watch permanently.

POST /v1/watch — Create Watch

Request Body

ParameterTypeRequiredDescription
url string Required The URL to monitor. Must be a valid HTTP/HTTPS URL, max 2048 chars.
webhookUrl string Optional Endpoint to receive change notifications. WebPeel will POST a JSON diff here when content changes.
checkIntervalMinutes number Optional How often to check the page for changes. Default: 60 minutes. Range: 1–44640 (31 days).
selector string Optional CSS selector to monitor only a specific part of the page (e.g. #price, .article-body).

Response — 201 Created

{
  "ok": true,
  "watch": {
    "id": "wch_01J8XKZP4T...",
    "accountId": "acc_...",
    "url": "https://example.com/pricing",
    "webhookUrl": "https://your-server.com/webhooks/webpeel",
    "checkIntervalMinutes": 60,
    "selector": null,
    "status": "active",
    "lastCheckedAt": null,
    "lastChangedAt": null,
    "createdAt": "2024-03-04T12:00:00.000Z"
  }
}

PATCH /v1/watch/:id — Update Watch

Request Body

ParameterTypeRequiredDescription
status string Optional Set to "paused" to pause checks, or "active" to resume.
webhookUrl string Optional Update the webhook destination URL.
checkIntervalMinutes number Optional Update the check frequency. Range: 1–44640.
selector string Optional Update the CSS selector to monitor.

POST /v1/watch/:id/check — Manual Check

Immediately checks the watched URL for changes, regardless of the schedule. Returns a diff if content has changed since the last check.

Response

{
  "ok": true,
  "diff": {
    "changed": true,
    "previous": "Price: $29",
    "current": "Price: $39",
    "changedAt": "2024-03-04T13:00:00.000Z"
  }
}

Webhook Payload

When a content change is detected, WebPeel POSTs this payload to your webhookUrl:

{
  "event": "change_detected",
  "watchId": "wch_01J8XKZP4T...",
  "url": "https://example.com/pricing",
  "checkedAt": "2024-03-04T14:00:00.000Z",
  "diff": {
    "changed": true,
    "previous": "...",
    "current": "...",
    "changedAt": "2024-03-04T14:00:00.000Z"
  }
}

Examples

curl -X POST https://api.webpeel.dev/v1/watch \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/pricing",
    "webhookUrl": "https://your-server.com/webhooks/price-change",
    "checkIntervalMinutes": 30,
    "selector": "#pricing-table"
  }'
# List all watches
curl https://api.webpeel.dev/v1/watch \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get a specific watch
curl https://api.webpeel.dev/v1/watch/wch_01J8XKZP4T... \
  -H "Authorization: Bearer YOUR_API_KEY"
# Pause a watch
curl -X PATCH https://api.webpeel.dev/v1/watch/wch_01J8XKZP4T... \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "paused" }'

# Resume a watch and change interval
curl -X PATCH https://api.webpeel.dev/v1/watch/wch_01J8XKZP4T... \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "active", "checkIntervalMinutes": 15 }'
const API_KEY = process.env.WEBPEEL_API_KEY;
const BASE = 'https://api.webpeel.dev';

// Create a watch
const res = await fetch(`${BASE}/v1/watch`, {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/pricing',
    webhookUrl: 'https://your-server.com/webhooks/change',
    checkIntervalMinutes: 60,
  }),
});
const { watch } = await res.json();
console.log(`Watch created: ${watch.id}`);

// Manually trigger a check
const checkRes = await fetch(`${BASE}/v1/watch/${watch.id}/check`, {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${API_KEY}` },
});
const { diff } = await checkRes.json();
if (diff.changed) {
  console.log('Content changed!', diff);
}

Watch Object

FieldTypeDescription
idstringUnique watch ID.
urlstringThe monitored URL.
statusstringactive or paused.
checkIntervalMinutesnumberCheck frequency in minutes.
selectorstring|nullCSS selector being monitored, or null for full page.
webhookUrlstring|nullNotification endpoint.
lastCheckedAtstring|nullISO timestamp of last check.
lastChangedAtstring|nullISO timestamp of last detected change.
createdAtstringISO timestamp when watch was created.