A primer on the Breadbox rule DSL — how to build condition trees, what actions are available, and four worked examples you can adapt.
Rules are the workhorse of any Breadbox setup. A well-tuned set of rules can categorize the overwhelming majority of your transactions during sync, leaving only the genuinely ambiguous ones for a human or agent to look at. This guide walks through the DSL by example — four rules you can adapt and drop into your instance today.If you haven’t yet, skim Breadbox in a nutshell first for the vocabulary. The full specification lives in Auto-categorize transactions with rules and the rules API reference.
The canonical “merchant name contains a substring” rule. Two conditions combined with and: the description must contain AMAZON, and the amount must be positive (so we don’t catch Amazon refunds).
When a single condition isn’t enough, an or group handles the “any of these merchants” case. Here we use the in operator on merchant_name to check against a list in one shot.
merchant_name is only populated for providers that enrich the raw description (Plaid does this; Teller and CSV imports often don’t). If your data comes primarily from Teller, prefer name with contains and match on a substring of the raw description.
Example 3 — Threshold tag: flag anything over $500
Not every rule has to change the category. This one only tags — anything over $500 gets the high-amount tag so you can scan the queue for big-ticket items before the rest.
You’d pair this with a tag you’ve pre-created in the dashboard (Tags → New tag, slug high-amount). Then filter to /transactions?tags=high-amount in the UI, or query_transactions(tags=["high-amount"]) from an agent.
You can freely nest and, or, and not up to 10 levels deep. For most workflows you’ll keep it under three.
If a transaction gets the wrong category anyway, set it manually from the dashboard. That flips , which the rule engine honors forever — your deliberate choice won’t be undone by a later rule.
Rules only fire at sync time by default. To run a newly created rule against your full history:
# Apply one rulecurl -X POST \ -H "X-API-Key: bb_your_key" \ http://localhost:8080/api/v1/rules/rule_abc123/apply# Apply every active rulecurl -X POST \ -H "X-API-Key: bb_your_key" \ http://localhost:8080/api/v1/rules/apply-all
Retroactive apply follows the same pipeline order and the same category_override protection as live sync. One caveat: add_comment actions are skipped during retroactive apply (they’re designed to narrate a specific sync event).