Skip to main content
Tags are open-ended labels attached to transactions. They are the primitive Breadbox uses for any workflow that asks “which transactions are in this state?” — the review queue is a tag view, and you can build your own (flagged, disputed, tax-deductible) the same way. Unlike categories, tags are not hierarchical and a transaction can carry any number of them at once. The endpoints for listing, attaching, and detaching tags live on the Tags API reference; filtering transactions by tag is on Transactions API.

Anatomy of a tag

FieldDescription
slugStable URL-safe identifier (e.g., needs-review, tax-deductible). Used in rule actions and MCP tool calls.
display_nameHuman-readable label shown in the dashboard.
descriptionOptional short explanation of what the tag means.
colorHex color for the dashboard pill.
Each tag also has an 8-character alongside its internal UUID, same as every other entity in Breadbox.

Tag removal notes

When you remove a tag from a transaction, you can optionally include a short note. If provided, the note is recorded as an annotation on the transaction’s activity timeline — useful for workflow flags like or disputed, where the reason for resolution is worth keeping.

Seeded tags

Breadbox ships with one tag out of the box:
SlugWhat it’s for
needs-reviewApplied to every newly-synced transaction by a seeded on_create rule. Removing it closes a review. See the review workflow.
Everything else is yours to define. Create new tags from the Tags page in the dashboard, or via the admin API.

How tags get applied

A tag reaches a transaction one of four ways — and the activity timeline records which one:
1

Manual (user)

From the transaction detail view in the dashboard, add or remove a tag directly. Recorded as added_by_type = user.
2

Agent (MCP)

An AI agent connected over MCP calls update_transactions with tags_to_add or tags_to_remove (each entry can include an inline note). Recorded as added_by_type = agent.
3

Rule action

A transaction rule with add_tag or remove_tag in its actions fires during sync (trigger ) or retroactively (trigger on_apply). Recorded as added_by_type = rule, with the rule’s ID on the annotation so you can trace why the tag landed.
4

System

Reserved for Breadbox itself — seeds, backfills, internal workflows. You won’t normally apply system tags; they show up in the timeline when they do.

Querying by tag

Tag-based filters are available through the MCP tools (query_transactions, count_transactions) and the admin dashboard. The REST API does not currently expose tag filters on GET /api/v1/transactions — if you need to query by tag over HTTP, use MCP. See issue #624 for the V1 parity plan. MCP tools accept two filter shapes:
  • tags — all-of semantics. A transaction must carry every listed slug.
  • any_tag — any-of semantics. A transaction must carry at least one.
query_transactions(tags=["needs-review"])                      # the review backlog
query_transactions(tags=["needs-review", "high-amount"])       # both tags
query_transactions(any_tag=["flagged", "disputed"])            # either tag
In the dashboard, the transactions list page accepts ?tags=needs-review as a URL parameter and renders the matching rows — this is what powers the /reviews redirect.

Tags in rules

Tags are both a condition and an action in the rule DSL:
  • As a condition, rules can match on tags contains "needs-review" or tags not_contains "disputed" to gate which transactions they affect.
  • As an action, rules can add_tag or remove_tag to manage tag state automatically. A rule that adds a tag can be scheduled (trigger on_create during sync) or run retroactively against historical data.
This is how you build workflow tags that behave like needs-review: define a tag, then write rules that apply or remove it under the conditions you care about.

Example: a disputed-charges workflow

Suppose you want a dedicated queue for charges you intend to contest with your bank. The ingredients:
1

Create a `disputed` tag

From Tags in the dashboard, add a new tag with slug disputed and a description like “Charge we’re contesting — remove with outcome note when resolved.”
2

Apply it when you see a bad charge

Tag the transaction manually from the dashboard, or have an agent tag it by name pattern via update_transactions. No rule necessary — you apply it reactively.
3

Use `?tags=disputed` as your queue

Same pattern as review: filter the transactions list to tags=disputed and the page becomes your dispute-tracking view. No new UI needed.
4

Resolve with a note

When the bank refunds or rejects the dispute, remove the tag and record the outcome (“Refunded $42.18 on 2026-04-14”). The note is saved to the activity timeline and you can look back months later and see exactly how each dispute played out.
The review workflow is the same shape — just with a different tag slug.
Last modified on May 27, 2026