All docs
On this page

A monitor re-captures a URL on a schedule and diffs the normalized content (line-trimmed markdown, SHA-256). On change it emits a webhook event and keeps a snapshot for later diffing.

Endpoints

POST   /v1/monitor                 create
GET    /v1/monitor                 list (keyset)
GET    /v1/monitor/{id}            detail
PATCH  /v1/monitor/{id}            { "status": "paused" | "active" } | interval | ignore_patterns | wait_for
DELETE /v1/monitor/{id}            delete (cascades checks + snapshots)
GET    /v1/monitor/{id}/checks     check history (keyset); changed/removed rows carry
                                 an inline diff_excerpt (bounded change summary)
GET    /v1/monitor/{id}/checks/{checkId}/diff   adjacent-snapshot line diff (free)
GET    /v1/monitor/{id}/snapshots/{snapshotId}  snapshot source: normalized markdown
                                 (text/markdown, not the JSON envelope; free)
POST   /v1/monitor/{id}/run        trigger a manual check now → 202

Create body: {url, name?, interval_minutes?, ignore_patterns?, webhook_id?, wait_for?}.

Semantics

  • Interval floor is per-plan — e.g. Free gets a coarser minimum than paid plans; too-small values are rejected with INVALID_REQUEST.
  • wait_for (ms, 0–60000, optional) — extra wait after page load before capture, same field as /v1/markdown. Pages that hydrate their content with JS (app-like directories, dashboards, filtered lists) need it: without it the snapshot may only contain page meta/boilerplate and changes to the real content are never seen. If the first check's snapshot looks like front-matter only, PATCH {"wait_for": 5000} — the next check re-captures as changed (a legit baseline re-cut, not an error). Content below the rendered viewport (infinite scroll) is still out of scope.
  • Each check costs 1 credit; errored checks cost 0.
  • ignore_patterns: regex lines stripped before hashing — use for timestamps, view counters, ad text that changes every render.
  • Check statuses: new (first baseline) · same · changed · removed · error.
  • Circuit breaker: after consecutive errors the monitor auto-pauses and notifies you — fix the target and resume with PATCH.
  • Snapshots are stored on new/changed only (bounded retention per monitor).
  • Diff endpoint: GET .../checks/{checkId}/diff returns a bounded hunk-style line diff (context param, elision segments, stats, truncated). available:false + reason is a normal state, not an error — not_diffable (same/error), snapshot_expired (snapshot pruned by retention: snapshots outlive ~10 changes, checks 200), too_large.
  • Snapshot source endpoint: GET .../snapshots/{snapshotId} returns the stored normalized markdown (line-trimmed, ignore_patterns lines stripped — not the raw page) as text/markdown, with ETag=content_hash and X-Snapshot-Char-Count/X-Snapshot-Created-At headers. Check rows expose snapshot_id (content written by that check) and prev_snapshot_id (the baseline — for removed/same rows this is the content that was seen). Only the latest ~10 snapshots per monitor are kept: a 404 usually means the snapshot was pruned by retention, so fetch soon after the event.

Notifications

Monitors notify via your team's notification channels — subscribe to monitor.* events in dashboard → Notifications, or pin a specific channel with webhook_id. Use POST /v1/monitor/{id}/run to verify the wiring without waiting for the schedule.