Monitors
Watch a page and get a signed webhook when it changes
A scheduled check — a CSS selector’s text, or an LLM-extracted set of fields — hashed and compared, pushing an HMAC-signed webhook to your callback only when the watched value actually moves.
create_monitor
What it is
The job: Know when something on a page changed, without polling it yourself.
A monitor is a URL, a cadence and a definition of what counts as “the value”. check_type "observe" watches a CSS selector’s text (or the page map when you give no selector) and is deterministic and cheap. check_type "extract" watches LLM-extracted fields or a natural-language description — more expensive, and the only option when the thing you care about is not addressable by a selector.
Each scheduled check reads the value, hashes it and compares it to the last hash. Nothing happens on an unchanged check beyond the credit for having looked. On a change, your callback_url receives a webhook, HMAC-signed when you set a callback_secret.
The minimum interval is 60 seconds. A monitor whose tenant runs out of credits is paused rather than silently dropped, and get_monitor_history shows you every check with its outcome, so a monitor that has been quietly failing is visible rather than mistaken for a page that never changes.
The call
Call it exactly like this.
Copied from the tool's registration and the route handler — not paraphrased.
// MCP tool call — server "twin-browser"
{
"tool": "create_monitor",
"arguments": {
"name": "pricing page",
"check_type": "observe",
"url": "https://example.com/pricing",
"selector": ".price-table",
"interval_seconds": 3600,
"callback_url": "https://your.app/hooks/price",
"callback_secret": "whsec_…"
}
}curl -X POST https://twin-browser.com/api/v1/monitors \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "content-type: application/json" \
-d '{"name":"pricing page","check_type":"observe","url":"https://example.com/pricing","selector":".price-table","interval_seconds":3600,"callback_url":"https://your.app/hooks/price","callback_secret":"whsec_…"}'| Parameter | Type | What it does |
|---|---|---|
| name* | string | A label for the monitor. |
| check_type* | "observe" | "extract" | How the watched value is read. observe watches a selector’s text deterministically; extract runs a model over the page. |
| url* | string | The page URL to watch. |
| interval_seconds* | number | How often to check, in seconds. Minimum 60. |
| callback_url* | string | The http(s) URL that receives the change webhook. |
| selector | string | CSS selector scoping an observe check to one element. Without it, an observe check watches the page map. |
| watch_fields | array | object | For extract: the fields to watch — names, or { name, description }. |
| nl_watch | string | For extract: a natural-language description of what to watch. |
| callback_secret | string | Secret used to HMAC-sign the change webhook. Set it — otherwise you cannot authenticate the delivery. |
| proxy | string | Your own egress proxy URL for the checks. |
Returns
HTTP 201 — the created monitor (secrets excluded).What it costs
Free to create — 1 or 5 credits per check
Creating a monitor costs nothing; the recurring cost is the check. An observe check bills 1 credit, the same as observe_page. An extract check bills the 5-credit extract floor, settled higher-of against the model cost. Multiply by your cadence before you set interval_seconds to 60.
See the full rate cardWhich one
When a different tool is the right call.
The honest answer is often the neighbouring tool. These are the trades.
observe_pageA monitor is observe_page on a timer with change detection and a webhook attached. If you only need the value once, call observe_page and skip the schedule.
observe_pagesubmit_crawlA crawl reads many pages once. A monitor reads one page many times. Neither substitutes for the other.
submit_crawlQuestions
create_monitor, answered.
- Which check type should I use?
- observe, if the value has a stable selector. It is deterministic, cheap and cannot hallucinate a change. Reach for extract only when what you care about is not addressable — “has the status line stopped saying ‘in stock’ anywhere on the page” — and accept that it costs the extract floor on every check.
- What happens if my balance runs out?
- The monitor is paused rather than silently skipped, and the pause is recorded in your audit log. Top up and re-enable it; you do not lose the definition or its history.
- Do I get a webhook on every check?
- No — only on a change. The check hashes the watched value and compares it to the last one; an unchanged check does nothing except appear in get_monitor_history. That is what makes a one-minute cadence survivable on your side, even though it is not free on ours.
Keep going
The rest of the tool set.
list_monitorsSee what you are already watching, and what it is costing you per hour.
get_monitor_historyTell the difference between “nothing changed” and “the check has been broken for a week”.
delete_monitorTurn off a watch you no longer need.
observe_pageLet an agent see what is on a page before deciding what to do about it.