Buckets and rules
A bucket is the central configuration object:
| Part | What it is |
|---|---|
name | Unique within the tenant. Lowercase, digits, dashes. |
priority | Lower runs first. Default 100. |
rule | A JSON predicate. The message lands here if it matches and no lower-priority bucket matched first. |
schema | Optional. Fields and extractors. See Schemas and extractors. |
policy | Optional. What auto-applies and what becomes a task. See Policy, tasks and captures. |
destinations | Where applied captures go. |
A message lands in exactly one bucket or in unrouted.
Rules
A rule is a JSON object with exactly one key. Combine with any, all, and not.
{ "any": [
{ "address": "orders@" },
{ "all": [ { "sender_domain": ".shop.example" }, { "subject_contains": ["order", "receipt"] } ] },
{ "not": { "has_attachment": false } }
] }
The full predicate list is in Predicates. Regexes are JavaScript syntax, case-insensitive by default, and are checked when you save: a bad regex is rejected with the path of the predicate that failed.
dry_run_rule returns, per message, whether it matched and the path of the deciding predicate (for example rule.any[1].all[0].sender_domain), which is also stored on the message as its classification reason.
Writing rules as an agent
- Ingest a few real messages. Read them with
get_message; the sanitizedtext, thefrom, and thetoare what rules see. - Start with the cheapest signals: the receiving address, then the sender domain, then subject words. Body text and attachment text last.
- Test with
dry_run_ruleagainst the message ids, including messages that should not match. - Save with
create_bucketorupdate_bucket, thenreprocess_messageon the ones that were unrouted.
This page as Markdown.