GuíasSelector Syntax

Selector Syntax

DiffHook selectors tell the engine exactly what part of a page or feed to watch, and let you compose rich include/exclude logic. Selectors live in the Selector expression field of every monitor's advanced settings, and you can also pass them when creating monitors via the API.

A selector is a small string. Most monitors only need a single one, but you can stack rules and combine them with AND / OR / NOT to fine-tune what fires an alert.

Quick reference by monitor type

Monitor kindSelector formatExample
RSS / Atom feedrss:items (all new items)rss:items
RSS / Atom feedrss:item[<attr>="<value>"]rss:item[guid="3"]
RSS / Atom feedrss:items[match*="<keyword>"]rss:items[match*="pricing"]
JSON APIJSONPath rooted at $$.stargazers_count
JSON-LD on a webpagejsonld:<Type>.<path>jsonld:Product.offers.price
Page screenshotpage:full (visual diff of viewport)page:full
Page screenshotpage:#<bbox-id> (specific element)page:#lead-card
Sitemapsitemap:urlssitemap:urls

The auto-detected default appears in the Watching field of the monitor — you only need to write a selector by hand when you want something more specific than the default.

RSS attribute matching

For RSS / Atom monitors, the attribute selector lets you target items by any field the parser exposes:

AttributeMatches
guidThe item's <guid> (or fallback identity)
linkThe item's <link> URL
titleThe item's <title>
description / summaryThe item's <description> (alias)
matchFree-text keyword, evaluated against title + description

Operators:

OperatorMeaningCase
=Exact matchCase-sensitive
*=Substring containsCase-insensitive
^=Starts withCase-insensitive
$=Ends withCase-insensitive

A bare attribute name (no operator) tests presencerss:item[guid] matches when the item has a non-empty <guid>.

Examples:

rss:item[title*="security"]
rss:item[author="Patrick Collison"]
rss:item[link^="https://stripe.com/blog/2026"]
rss:items[match*="pricing"]

Logical operators

Build richer rules by combining selectors with boolean operators:

OperatorSymbolMeaning
AND&&Both sides must match
OR||At least one side must match
NOT!Inverts the result

Operators are case-insensitive (AND, and, And all work). Word forms (AND/OR/NOT) require a word boundary, so identifiers like organization or android are never split.

Precedence (highest to lowest): NOTANDOR. Parentheses override precedence.

rss:item[title*="AI"] AND NOT rss:item[author="bot"]

(rss:item[category="security"] OR rss:item[category="ai"]) AND NOT rss:item[title*="weekly roundup"]

Multi-line composition

A selector expression can span multiple lines. The engine treats each non-blank, non-comment line as one rule and ANDs them all together at the top level — an item must satisfy every line to pass.

rss:item[title*="AI"]
NOT rss:item[author="bot@example.com"]

Equivalent to:

rss:item[title*="AI"] AND NOT rss:item[author="bot@example.com"]

Use whichever form is more readable. Long policies with several constraints are easier to scan when split across lines.

PrefixMeaning
#Comment (line is ignored)
(blank)Ignored

Combining filters: examples

Watch only AI- or security-tagged posts:

rss:item[title*="AI"] OR rss:item[category="security"]

Watch all new posts except those by a specific author:

rss:items
NOT rss:item[author="bot@example.com"]

Watch a single article by GUID, but never if it's been re-tagged as draft:

rss:item[guid="3"]
NOT rss:item[category="draft"]

Watch security posts that mention pricing, but skip the weekly newsletter roundup:

# include — must match all three
rss:item[category="security"]
rss:items[match*="pricing"]
NOT rss:item[title*="weekly roundup"]

Watch posts about either AI agents or autonomous systems, never bot-authored, never drafts:

rss:item[title*="AI agents"] OR rss:items[match*="autonomous"]
NOT rss:item[author*="bot"]
NOT rss:item[category="draft"]

Behavior with missing data

  • An attribute that the parser has not exposed yet (or is absent on the item) evaluates to no match. NOT rss:item[author="bot"] therefore passes when author is missing.
  • An empty selector expression (or one made entirely of blanks and comments) matches every item.
  • A selector for a different monitor kind (e.g. jsonld:Product.offers.price inside an RSS monitor) evaluates to false — it won't error, it just doesn't match anything on this pipeline.

Error handling

Selector expressions are validated at save time. If you try to save an invalid expression, the API returns the line number and the parser's diagnostic. If a malformed expression somehow reaches the engine, it is logged and treated as no filter — the monitor keeps running rather than halting deliveries.

Tips

  • Keep selectors specific. A narrow selector means fewer false alerts and cheaper checks against your plan budget.
  • Use the match*= operator for natural language. It searches title + description and is the right tool when you want "anything about pricing" without listing every variant.
  • Test in the chat first. The new-monitor chat understands phrases like "only posts about pricing" or "ignore drafts" and writes the selector for you — copy it into the textarea once it works.
  • Comments are encouraged for long policies. If your team rotates monitor ownership, a one-line # comment per block saves a lot of archaeology.

Roadmap

The grammar is intentionally focused. Open requests we're tracking:

  • Regex operator (~=).
  • Attribute matching against author and category for feeds where the underlying parser doesn't surface them yet.
  • Field-level diff selectors for HTML pages (CSS / XPath beyond the auto-detected bboxes).

If you need any of these for a specific monitor, contact support — we'll often turn it on for your account ahead of the public rollout.