Press / to search

All documentation
docs Watch and act Monitors

Runs onWrit CloudDesktop

monitors ▸ watch and act

Monitors.

A monitor watches a page and reports real change against a baseline. On the top cloud plans it checks as often as every 10 seconds, and a detected change can fire a workflow the moment it lands.

Writ runs on your own accounts, with your own credentials and data, on sites you are authorized to use.

types ▸ two checks

Two check types.

A target is a URL plus a check_type:

check_typeWhat it checks
contentFetches the page and compares what you watch — a selector, the structure, or a screenshot zone — against its stored baseline.
uptimeChecks that the page answers: HTTP status, response time, certificate validity.

JS rendering is a separate switch: set requires_playwright and the check runs in a real browser instead of a plain fetch. A JS check weighs an HTML check in your plan’s check budget.

watch ▸ three modes

What a content check can watch.

A content target watches in one of three modes, each with its own baseline:

ModeHow change is detected
selectorThe text at a CSS selector, hashed and compared. With no selector set, the whole page is watched.
htmlThe structured markup, compared structurally rather than as raw text.
visualA screenshot zone — visual_region is {x, y, width, height} — compared against a stored baseline image.

Noise control: an ignore_regex can be set on the target and on each selector — matching fragments are struck from the comparison, so counters and timestamps stop producing false changes.

Extractors

On selector content, extractors turn the matched region into named values that travel with the change event. Each extractor has a key, an optional multiple flag, and a default_value:

typeWhat it pulls
textThe element’s text content.
attributeA named attribute of the element.
regexThe first (or every) match of a pattern.
cssA nested CSS selection inside the watched region.
json_pathA path into JSON found in the watched content.

Create one from code

On your own machine, the SDKs create a monitor against the local agent and read its change history back:

monitor.ts

import { WritAgent } from "@usewrit/agent-sdk";

const client = new WritAgent();
const mon = await client.monitors.create({ url: "https://example.com/pricing" });
const history = await client.monitors.changes(mon.id, { limit: 50 });
console.log(mon.id, history);

context ▸ around the check

Logged-in checks, and acting in the same session.

A target can carry the context its page needs — and hand the live session straight to a workflow when change is detected:

FieldWhat it does
pre_check_workflow_idA workflow that runs before the check — typically a sign-in — so the check sees the page your account sees.
on_change workflowA workflow fired when change is detected. It can run in the same live session, so it acts on the exact page state the check just saw.
persona_idThe persona whose saved sign-in state the check uses.
use_residentialRoute the check through residential egress where your plan allows it.

cadence ▸ floors per plan

Cadence floors — rejected, not clamped.

Every plan sets a fastest allowed interval, separately for HTML checks and JS-rendered checks. An interval below your plan’s floor is rejected with 402 and code interval_too_short — it is never silently slowed down to the floor.

PlanHTML floorJS floor
Free5 min15 min
Starter1 min10 min
Pro1 min10 min
Growth30 s5 min
Scale / Enterprise10 s2 min

What you set is what runs. If a request would need a faster plan, the API says so up front instead of quietly degrading your monitor.

Two separate gates sit beside the floor: a weighted checks-per-minute budget across all your targets (10 on Free, up to 3000 on Enterprise; a JS check counts 5×) answered with 402 budget_exceeded when spent — and a hard maximum number of targets per check type.

pipeline ▸ change to action

From change to action.

When a check lands, every fired action has walked the same pipeline:

  1. ExtractExtractors turn the watched content into named values.
  2. MatchTriggers watching this target (or this selector) are collected.
  3. Build contextThe {{…}} template context is assembled: extracted values, now / now_date and friends, change_detected_at, target_id and the target URL.
  4. DedupSelector-less triggers fire once per (trigger, target) per batch — one check cannot double-fire the same rule.
  5. ConditionsEach trigger’s conditions are evaluated, plus its guardrails: schedule windows and cooldown.
  6. Log, dispatch, settleThe firing is logged as pending, actions dispatch, and the log settles with status, action_results and trigger_count.

Condition operators (11): changed, exists, equals, not_equals, contains, not_contains, matches, gt, gte, lt, lte.

templates ▸ filters

Template filters.

Inside {{…}} templates — messages, webhook payloads, workflow inputs — values can be piped through filters:

FilterWhat it does
default (alias: or)Fallback when the value is empty.
upper / lowerCase conversion.
trimStrip surrounding whitespace.
truncate:NCut to N characters.
replace:a:bReplace a with b.
round[:digits]Round a number, optionally to a digit count.
add / sub / mul / divArithmetic on numeric values.
match:<regex>Keep the regex match (patterns up to 512 characters).

alerts ▸ nine channels

Where alerts go.

Monitor and trigger alerts deliver through nine channels: pushover, email, twilio (SMS), whatsapp, signal, webhook, slack, discord and telegram.

pushoveremailtwiliowhatsappsignalwebhookslackdiscordtelegram

Recipients are addressed as "channel:id" strings — e.g. ["pushover:1", "email:3"] — so one trigger can fan out to several configured destinations at once. Outbound webhook deliveries are signed; see webhooks.

next ▸ where to go

Keep going.