> ## Documentation Index
> Fetch the complete documentation index at: https://breadbox-mintlify-7401d007.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction write MCP reference

> Compound writes for category, tags, and comments on transactions. Categorization lives on its own page.

Write tools for editing transactions. `update_transactions` is the single primitive — it covers category sets, category resets, tag adds/removes, flag toggles, and a free-form comment in one atomic op per row, for up to 50 transactions per call. The retired per-row tools (`categorize_transaction`, `batch_categorize_transactions`, `reset_transaction_category`, `bulk_recategorize`, `flag_transaction`, `unflag_transaction`) all fold into it.

All tools on this page are **Write** scope. See [Categorization](/mcp/reference/categorization) for category-only writes.

***

## update\_transactions

Compound write for up to 50 transactions at once. Each operation can set a category (`category_slug`), add tags (`tags_to_add`), remove tags (`tags_to_remove`), and attach a comment — all atomically per transaction. This is the tool for closing review work (set category + remove `needs-review` + explain) in one call.

Every change lands as a single linked annotation per operation, so the activity timeline reads as one event per transaction rather than a separate entry for each change.

### Compound op semantics

<Note>
  **What "compound" means here.** Each element in the `operations` array is a bundle of mutations targeting one transaction. Within a single operation:

  * The category, tag additions, tag removals, and comment are applied atomically — either all land or none do.
  * The annotations written for those changes are linked so the activity timeline reads as one event, not four.
  * Tag `note` fields are preserved on both `tag_added` and `tag_removed` annotations.
</Note>

### on\_error behavior

* `continue` (default) — each operation runs in its own DB transaction. A failure on row 17 doesn't roll back rows 1–16. The response returns per-row `status` so you can retry the failed ones.
* `abort` — the whole batch runs in one DB transaction. The first error rolls back every operation and the response includes `aborted: true`.

### Parameters

<ParamField path="operations" type="array of objects" required>
  Array of per-transaction operations. Max 50. See the operation shape below.
</ParamField>

<ParamField path="on_error" type="string" default="continue">
  `continue` or `abort`.
</ParamField>

### Operation shape

<ParamField path="transaction_id" type="string" required>
  UUID or short ID.
</ParamField>

<ParamField path="category_slug" type="string">
  Category slug to set. Sets `category_override = 'agent'` (skips the row if a user has already set it to `'user'`). Omit to leave the category unchanged. Mutually exclusive with `reset_category`.
</ParamField>

<ParamField path="reset_category" type="boolean" default="false">
  Drop the transaction back to uncategorized so rules can re-categorize it on the next sync. Mutually exclusive with `category_slug`. Use to undo a prior agent or rule decision.
</ParamField>

<ParamField path="tags_to_add" type="array">
  List of `{slug, note?}` entries. Auto-creates persistent tags if the slug is unknown.
</ParamField>

<ParamField path="tags_to_remove" type="array">
  List of `{slug, note?}` entries. `note` is recommended for workflow tags like `needs-review`.
</ParamField>

<ParamField path="flagged" type="boolean">
  Flag (`true`) or unflag (`false`) the transaction for human attention without changing its category. Pair `flagged: true` with a `comment` carrying the reason; retrieve flagged rows later with `query_transactions(flagged=true)`. Omit to leave the flag untouched. Replaces the retired `flag_transaction` / `unflag_transaction` tools.
</ParamField>

<ParamField path="comment" type="string">
  Free-form comment written as an annotation. Max 10000 chars. Markdown supported.
</ParamField>

### Example input

```json theme={null}
{
  "on_error": "continue",
  "operations": [
    {
      "transaction_id": "k7Xm9pQ2",
      "category_slug": "food_and_drink_groceries",
      "tags_to_remove": [
        { "slug": "needs-review", "note": "clearly groceries (Whole Foods)" }
      ]
    },
    {
      "transaction_id": "k8Yn0qR3",
      "category_slug": "transportation_ride_share",
      "tags_to_remove": [
        { "slug": "needs-review", "note": "Uber to airport" }
      ],
      "comment": "Work trip — filed to expense tracker 2026-04-20."
    }
  ]
}
```

### Example output

```json theme={null}
{
  "results": [
    { "transaction_id": "k7Xm9pQ2", "status": "ok" },
    { "transaction_id": "k8Yn0qR3", "status": "ok" }
  ],
  "succeeded": 2,
  "failed": 0
}
```

### Flagging a transaction

To mark a transaction for follow-up without changing its category, pass `flagged: true` with a `comment` carrying the reason. Retrieve flagged rows later with `query_transactions(flagged=true)`. Clearing a flag is `flagged: false`.

```json theme={null}
{
  "operations": [
    {
      "transaction_id": "k7Xm9pQ2",
      "flagged": true,
      "comment": "Charge from a merchant we don't recognize — verify before next statement."
    }
  ]
}
```
