Buckets and rules

A bucket is the central configuration object:

PartWhat it is
nameUnique within the tenant. Lowercase, digits, dashes.
priorityLower runs first. Default 100.
ruleA JSON predicate. The message lands here if it matches and no lower-priority bucket matched first.
schemaOptional. Fields and extractors. See Schemas and extractors.
policyOptional. What auto-applies and what becomes a task. See Policy, tasks and captures.
destinationsWhere 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

  1. Ingest a few real messages. Read them with get_message; the sanitized text, the from, and the to are what rules see.
  2. Start with the cheapest signals: the receiving address, then the sender domain, then subject words. Body text and attachment text last.
  3. Test with dry_run_rule against the message ids, including messages that should not match.
  4. Save with create_bucket or update_bucket, then reprocess_message on the ones that were unrouted.

This page as Markdown.