create_transaction_rule (single or batch via the rules array), update_transaction_rule, delete_transaction_rule, and apply_rules.
list_transaction_rules
Lists transaction rules with optional filters. Agents should always call this before creating new rules to avoid duplicates. Returns each rule’s actions, trigger, priority, hit count, and last-hit timestamp — useful for spotting stale or never-matching rules. Scope: Read Mirrors:GET /api/v1/rules
Parameters
Filter to rules that set this category.
true for only enabled, false for only disabled, omit for both.Search by rule name. Comma-separated values are ORed.
contains, words, or fuzzy.Max 500.
Pagination cursor.
Example input
Example output
Example output
query_transaction_rules
Richer, filterable query over the rule set — the rules analogue ofquery_transactions. Adds trigger, creator type, hit-count, and unused filters that list_transaction_rules doesn’t expose, plus sorting by impact. Use this to audit coverage (“which agent-created rules have never fired?”) or prune dead rules (only_unused: true) without loading the full roster.
Scope: Read
Mirrors: GET /api/v1/rules
Parameters
Filter to rules whose
set_category action targets this category slug.true for only enabled, false for only disabled, omit for both.Filter by firing trigger:
on_create, on_change (alias on_update), or always.Filter by who created the rule:
user, agent, or system.Search by rule name. Comma-separated values are ORed.
contains, words, or fuzzy.Return only rules whose
hit_count is at least this value. Surfaces high-impact rules. Ignored when only_unused is true.When
true, return only rules that have never fired (hit_count = 0) — dead or over-specific rules worth reviewing for deletion.Sort column:
priority (pipeline execution order), hit_count, last_hit_at, created_at, or name.asc or desc. Default per column: desc for hit_count, last_hit_at, created_at; asc for priority and name.Max 500.
Pagination cursor. Only applies to the default
priority sort — an explicit sort_by returns a single top-N page with no next_cursor.Comma-separated fields to include. Omit for the summary projection (
name, enabled, priority, trigger, category, hit_count, last_hit_at — no conditions or actions trees). Pass fields=all for every field.Example — find dead rules
Example — highest-impact rules for a category
preview_rule
Dry-run a condition tree against existing transactions — no writes, no hit-count bump. Returns the match count, total scanned, and a sample of matching transactions. Agents use this to test a condition before committing to a rule. Scope: ReadParameters
Condition tree. Same grammar as
create_transaction_rule.conditions. Leaf: {"field":"...","op":"...","value":...}. Combinators: {"and":[...]}, {"or":[...]}, {"not":{...}}.Number of sample matching transactions to return. Max 50. The
match_count reflects the full match set regardless of sample size.Example input
Example output
Example output
Condition grammar
Full DSL is in the Breadbox repo’sdocs/rule-dsl.md. Short form:
- Fields —
name,merchant_name,amount,category_primary,category_detailed,category(the assigned slug, live-updated by earlier-stage rules),pending,provider,account_id,account_name,user_id,user_name,tags. - Operators —
- String/category:
eq,neq,contains,not_contains,matches(RE2),in. - Numeric:
eq,neq,gt,gte,lt,lte. - Bool:
eq,neq. - Tags:
contains,not_contains,in.
- String/category:
- Combinators —
and,or,not(nest freely, max depth 10).
{} (or omit conditions entirely on rule creation) to match every transaction.
find_matching_rules
Reports which existing active rules already match a given transaction or merchant — the inverse ofpreview_rule. Call this before creating a rule to answer “is this merchant already covered?” without loading the entire rule set into context.
Scope: Read
Parameters
A transaction ID or short ID to evaluate the full active rule set against. Every condition field (amount, category, tags, provider, account, …) is checked against the row’s real values. Provide exactly one of
transaction_id or merchant.Free-text merchant name to check name-based rule coverage for. Builds a synthetic context with only the name fields set — rules that condition on amount, category, or tags won’t match and that is the correct, conservative behavior. Provide exactly one of
transaction_id or merchant.Example input
Example output
Example output
Response fields
Number of matching rules. Zero means no existing rule covers this transaction or merchant — safe to create a new one.
Matching rules ordered by priority ascending — the same order the sync pipeline would apply them.
Trigger is not filtered — a rule is reported if its condition matches, regardless of
on_create/on_change. This answers coverage questions, not sync-time simulation. A rule with match_all: true covers every transaction but is not a meaningful merchant match.