Watch any page.
Act the moment it moves.
Point a monitor at any value on any page, a price, a status, a visual zone, as fast as every 10 seconds. When it changes, Writ fires the same beat: notify an agent, call a webhook, or kick off a workflow.
A number, an element, or a whole zone.
Baseline on a value, a CSS selector, or a screenshot region. Writ watches only that, and only tells you when it actually changes. Pick a target:
The reaction starts from the persona’s warm session — no cold login. If the action fails, Writ logs the run and applies the retry policy you configured.
As often as every ten seconds.
Set how often the monitor checks. The fastest cadence is set by your plan, and lightweight HTTP checks run tighter than heavier browser renders. Pick an interval:
Detect the change. Fire the action.
When a Monitor detects a change, that event becomes an automation trigger: it fires a workflow, optionally held behind a confirm-gate for your approval. Detection to action, automatic. Trip it:
The action is an automation that fires a workflow. See the full pattern on Watch-and-Act.
Runs on your machine, free, or in the cloud.
Local monitors run on your own machine at no compute charge. Cloud monitors run on the managed fleet, checked from the region you choose. Pick a venue:
Honest cadence - no asterisks.
Check frequency is a fixed floor per plan. HTTP checks (static pages) are faster than JS renders (dynamic pages), which run a full browser.
| Plan | HTTP (static) | JS render (dynamic) |
|---|---|---|
| Free | every 5 min | every 15 min |
| Starter | every 1 min | every 10 min |
| Pro | every 1 min | every 10 min |
| Growth | every 30 s | every 5 min |
| Scale | every 10 s | every 2 min |
| Enterprise | every 10 s | every 2 min |
These floors are the same numbers on the pricing page - never a "contact us" for a cadence we list. 10-second checking is the top-tier floor.
Unattended action, on rails you set.
Every fire walks the same seven steps, in order, and the sensitive ones wait for you. Nothing acts straight off a page change.
Detect runs at your plan's cadence floor - Free 5 min · Starter 1 min · Pro 1 min · Growth 30 s · Scale 10 s · Enterprise 10 s. The same floors as on the pricing page, never hand-adjusted here.
A gated action waits for your explicit approval; anything that can spend money also lives under a hard spend cap. Writ runs on your own accounts, with your own credentials, on sites you choose. It automates work a person could do by hand - within hard limits, never beyond them. See the Acceptable Use Policy.
Back in stock to a prepared workflow - one configuration.
The trigger, the action, and the safety rails live in a single configuration. Call the resulting Workflow as an endpoint, or let the change fire it automatically.
# Monitor: out-of-stock PDP, every 10s (Scale), JS render, selector ".stock-status"
# Automation: on change to "In stock" -> run Workflow "reserve-and-notify"
# Workflow: navigate -> fill (order form, Persona) -> submit -> capture confirmation
# Rails: confirm_gate=on, dry_run=false, rate_cap=1/min, idempotency_key=<sku+event>
POST https://api.usewrit.app/v1/reserve-and-notify/run
Authorization: Bearer wt_...
-> { "status": "awaiting_approval", "run_id": "...", "gate": "confirm-gate" } Wire monitors from code.
Arm a Monitor over the API in any language: set the target, the cadence, and what fires on change. Pick a language and run it:
A monitor is one POST with a key. No install, no agent to run — Writ checks the page on your cadence and records every change.
# Watch a page on Writ Cloud — no install, just the key.
curl -X POST https://api.usewrit.app/api/targets \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com",
"check_type": "content",
"selector": "h1",
"check_period_ms": 300000}' A check interval below your plan’s minimum is refused outright, naming the floor — it is never quietly slowed down.
Point your assistant at Writ and it can create and wire monitors itself — watch a page, then run something when it moves.
claude mcp add writ-cloud \
-e WRIT_API_KEY=wt_your_api_key \
-- npx -y writ-mcp
# then, one line in the session:
writ_create_monitor({ url: "https://example.com",
selector: "h1", interval_minutes: 5 })
writ_wire_monitor({ monitor_id: 47, action: "notify",
channels: ["email"] }) Config-file clients — Claude Desktop · Cursor · Windsurf
The same monitors appear in the app, the API and the SDKs; the venue changes, the monitor does not.
npm install github:usewrit/writ-sdks --workspace typescript
import { CloudApi } from "@usewrit/agent-sdk";
const cloud = new CloudApi({ apiKey: process.env.WRIT_API_KEY }); // wt_…
const mon = await cloud.monitors.create({
url: "https://example.com",
selector: "h1",
check_period_ms: 300_000,
});
const changes = await cloud.monitors.changes(mon.id, { limit: 50 }); pip install "git+https://github.com/usewrit/writ-sdks#subdirectory=python"
from writ_agent import Cloud
cloud = Cloud(api_key=os.environ["WRIT_API_KEY"]) # wt_… — no daemon needed
mon = cloud.monitors.create({
"url": "https://example.com",
"selector": "h1",
"check_period_ms": 300_000,
})
changes = cloud.monitors.changes(mon["id"], limit=50) go get github.com/usewrit/writ-sdks/go
client := writ.New(writ.WithAPIKey(os.Getenv("WRIT_API_KEY")))
mon, err := client.Cloud.Monitors.Create(ctx, writ.CloudMonitorParams{
URL: "https://example.com",
Selector: writ.Ptr("h1"),
CheckPeriodMs: writ.Ptr(int64(300_000)),
})
changes, _ := client.Cloud.Monitors.Changes(ctx, mon.ID, writ.Ptr(50)) cargo add writ-client --git https://github.com/usewrit/writ-sdks
use serde_json::json;
use writ_client::CloudClient;
let cloud = CloudClient::from_env()?; // reads WRIT_API_KEY
let mon = cloud.monitors().create(json!({
"url": "https://example.com",
"selector": "h1",
"check_period_ms": 300_000
})).await?;
let changes = cloud.monitors().changes(mon.id, Some(50)).await?;