Skip to content

Watches

A watch is one thing you want to know about, expressed as data:

Check these sources, on this schedule, and tell me on these channels when this condition is met — but only if you are at least this sure.

Everything Watcher does is per watch. Watches do not share state, do not see each other, and fail independently: a broken watch never stops the others.

Field Meaning
id A stable slug. It is the watch’s identity, and the key its memory is stored under. Changing it creates a different watch.
name What you see at the top of an alert.
sources[] Where to look. One or more. See Sources.
condition The plain-English question. See Conditions.
schedule Cron, in UTC. See Scheduling.
channels[] Where alerts go.
threshold Minimum confidence (0–1) for a confirmed alert.
weakThreshold Optional lower bar for “unconfirmed” alerts.
minSources Optional: how many distinct sources must contribute evidence before a confirmed alert.
enabled Whether it runs at all.

The complete schema, including every optional field and per-source hint, is in Watch schema.

Watches are data in the database, not code. You can create them three ways:

  • The admin panel or the Android app — a form, with an AI drafter if you want one.
  • The REST APIPOST /watches.
  • YAML files in the repository’s watches/ directory, imported with pnpm watches:import.

Each watch keeps a small amount of state between runs: the content it has already evaluated, the events it has already alerted on, when it last ran, and a short history of recent alerts that it shows the model as context.

This is why a watch gets quieter over time rather than repeating itself — and why editing a condition does not cause Watcher to re-examine content it has already consumed. What Watcher remembers explains the consequences, including how to force a re-check.

Every watch belongs to an owner (the account that created it). Over the API a watch is always scoped to the signed-in identity: you cannot read, run or modify someone else’s watch, and the owner is taken from your token rather than from the request body.