Rules: automate categorization, tagging, and annotations
Build condition-based rules that categorize, apply tags, and leave annotations on transactions automatically — at sync time or retroactively — using Breadbox’s recursive AND/OR/NOT condition engine with a multi-stage pipeline.
Breadbox’s rules engine lets you define conditions that run automatically whenever transactions are synced. When a transaction matches a rule’s conditions, the rule assigns a category, adds tags, or leaves a comment — without any manual intervention.
A rule is a JSON document that pairs a condition (which transactions to match) with one or more actions (what to do with them). Rules run at sync time in a defined pipeline order. You can also apply rules retroactively to your full transaction history at any time.A single rule can:
Set a transaction’s category (set_category)
Add a tag to the transaction (add_tag)
Remove a tag from the transaction (remove_tag)
Leave an automated comment explaining the categorization (add_comment)
Link the transaction to a recurring series (assign_series)
Provider’s raw primary category (does not change when Breadbox reassigns)
category_detailed
string
Provider’s raw detailed subcategory
category
string
Currently assigned Breadbox category slug (updates mid-pipeline as rules run)
pending
boolean
Whether the transaction is pending
provider
string
plaid, teller, or csv
account_id
string
Account UUID
account_name
string
Account display name
user_id
string
Family member UUID
user_name
string
Family member display name
tags
tags
Current tag slugs on the transaction
Use category (not category_primary or category_detailed) when you want a condition to react to the category that Breadbox or a prior rule assigned. The category_primary and category_detailed fields always hold the provider’s original values and never change.
Rules run in pipeline order — lower stage numbers run first. For set_category, the last matching rule wins, so higher-stage rules have the final say on categorization. For add_tag and add_comment, every matching rule contributes.
Stage name
Priority
Purpose
baseline
0
Foundation rules — broad, default classifications
standard
10
General-purpose rules (default when no stage is specified)
refinement
50
Reacts to output from baseline and standard rules
override
100
Has the final say — overrides everything below
Supply stage as a string in the request body. You can also supply a raw priority integer (0–1000) for fine-grained ordering within a stage. If you supply both, priority wins.
Because rules run in pipeline order and share a mutable transaction context, later rules can react to what earlier rules did. A rule that assigns a category at stage 0 makes that category readable via field: "category" for any rule at stage 10 or higher in the same sync pass.
A rule with no trigger specified defaults to , which means it fires only on newly synced transactions. Use always to also run on re-synced changes, or on_change to run only when an existing transaction is modified.
The response returns a match count and a sample of matched transactions. Preview evaluates the condition in isolation — it does not simulate the full pipeline.
After creating or editing a rule, apply it to your full transaction history without waiting for the next sync:
curl -X POST \ -H "X-API-Key: bb_your_key" \ http://localhost:8080/api/v1/rules/rule_abc123/apply
Retroactive apply respects the same pipeline stage ordering as sync. It also respects — transactions whose category_override is not 'none' are skipped for set_category actions, just as they are during sync.
add_comment actions do not fire during retroactive apply. Comments are designed to narrate a specific sync event and are only written during live syncs.
If a transaction has been manually categorized (its category_override is 'user'), a rule’s set_category action is skipped for that transaction. The rule still runs — add_tag and add_comment actions fire normally — but the category is not changed. This means you can safely apply rules in bulk without worrying about undoing deliberate manual work.
The assign_series action links a matching transaction to a recurring series — a subscription or other repeating charge. It’s the series counterpart to set_category: author the rule once and every future matching charge joins the series automatically. Provide exactly one of:
series_short_id — link to an existing series by its short ID.
merchant_key + create_if_missing: true — mint a household series for that merchant the first time a charge matches, then link every future match to it.
A transaction belongs to at most one series; if several rules try to assign one, the highest-priority rule wins. Minting honors a rejected series — a rule can’t resurrect a subscription you’ve dismissed.
assign_series materializes at sync time and on single-ruleretroactive apply (POST /rules/{id}/apply) — applying that one rule links matching existing transactions. The bulk apply-all path doesn’t materialize assign_series yet, so apply the rule on its own to back-fill. You can also link a charge by hand or with the assign_series MCP tool.