Watch schema
Watches are validated against the same schema whether they arrive from YAML, the API or the admin panel. An invalid watch is rejected rather than partially applied.
| Field | Type | Required | Meaning |
|---|---|---|---|
id |
string | yes | Stable slug and identity. Global across accounts |
ownerId |
string | no (default local) |
Owner. Over the API this is forced from your token and ignored in the body |
name |
string | yes | Shown at the top of an alert |
sources |
Source[] | yes, at least 1 | Where to look |
schedule |
string | yes | Cron expression, UTC |
condition |
string | yes | The plain-English trigger |
channels |
Channel[] | yes, at least 1 | Where alerts go |
threshold |
number 0–1 | yes | Minimum confidence for a confirmed alert |
weakThreshold |
number 0–1 | no | Lower bar for “unconfirmed” alerts. Omit to disable the weak tier |
minSources |
integer ≥ 1 | no | Distinct sources that must contribute evidence for a confirmed alert |
allowUnratedStrong |
boolean | no (default false) |
Allow a source with no resolvable trust tier to fire a confirmed alert |
allowSecondaryModel |
boolean | no (default true) |
When false, this watch’s content never reaches the second-opinion model, including as failover |
enabled |
boolean | yes | Whether it runs |
id: framework-releasesname: Framework stable releasessources: - type: rss value: "https://example.com/blog/feed.xml" trust: official - type: search value: "framework 2.0 stable release" hints: recencyDays: 14 topic: newsschedule: "0 */6 * * *"condition: > Alert when a new stable version is released. Ignore release candidates, betas, and posts about future plans.channels: [telegram]threshold: 0.6weakThreshold: 0.4enabled: trueSource
Section titled “Source”| Field | Type | Required | Meaning |
|---|---|---|---|
type |
rss | search | page |
yes | How to collect |
value |
string | yes | Feed URL, search query, or page URL |
hints |
object | no | Collection tuning (below) |
trust |
official | trusted | unknown | low |
no | Explicit trust. Omit to infer from the host |
Collection hints
Section titled “Collection hints”| Hint | Type | Applies to | Meaning |
|---|---|---|---|
officialDomains |
string[] | search |
Restrict results to these domains, and treat them as official |
recencyDays |
integer > 0 | search |
Only results from the last N days |
searchDepth |
basic | advanced |
search |
Search depth (default advanced) |
topic |
general | news |
search |
Search topic |
extract |
boolean | page |
Set false to skip the extract-service tier |
reader |
boolean | page, rss with followLink |
Enable the reader tier for JavaScript-heavy pages |
followLink |
boolean | rss |
Fetch each entry’s linked article for fuller text |
legacyTls |
boolean | page |
Allow legacy TLS renegotiation for old portals |
Channels
Section titled “Channels”A channel is either a bare type or an object with a destination override:
channels: [telegram]channels: [push]channels: [{ type: telegram, chatId: "-1001234567890" }]channels: [telegram, push]Valid types are telegram, push and email. See Channels
— note that email is not implemented as an alert channel.
Validation rules worth knowing
Section titled “Validation rules worth knowing”thresholdandweakThresholdmust be between 0 and 1.weakThresholdshould be lower thanthresholdto be meaningful.sourcesandchannelsmust each have at least one entry.- An unknown field is rejected rather than ignored, so a typo surfaces immediately instead of silently doing nothing.
- Over the API,
idcomes from the path andownerIdfrom your token; neither is client-settable in the body.
Where watches are stored
Section titled “Where watches are stored”In the database. YAML files under watches/ are an import source only — run
pnpm watches:import to upsert them. See Authoring watches as
files.