Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions connections/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ A **connection** in Breadbox is the link between your self-hosted instance and a

## Providers supported

Breadbox currently supports three ways to bring in bank data. If you're setting up for the first time, **Teller is the easiest starting point**: the free Development tier connects to real accounts immediately, with no production approval process to wait on.
Breadbox currently supports four ways to bring in bank data. If you're setting up for the first time, **Teller is the easiest starting point**: the free Development tier connects to real accounts immediately, with no production approval process to wait on.

<Columns cols={3}>
<Columns cols={2}>
<Card title="Teller" icon="landmark" href="/connections/teller">
Recommended starter. Real bank connections on the free Development tier without a production approval process. Uses mTLS-based authentication.
</Card>
Expand All @@ -18,6 +18,10 @@ Breadbox currently supports three ways to bring in bank data. If you're setting
Widest US coverage — thousands of institutions, automatic sync, webhooks, and balance tracking. Worth the extra setup once you're ready for production.
</Card>

<Card title="SimpleFIN" icon="bridge" href="/connections/simplefin">
Token-paste aggregator via the SimpleFIN Bridge. One token spans every bank linked at the bridge, and new banks added there appear automatically on the next sync.
</Card>

<Card title="CSV import" icon="file-spreadsheet" href="/connections/csv-import">
Works for any institution, with no API credentials. Useful for banks Plaid and Teller don't cover, historical data, and migrations from other tools. <Badge color="blue" icon="hammer">BETA</Badge>
</Card>
Expand Down Expand Up @@ -77,7 +81,7 @@ The same operations are available programmatically via the [Connections API](/ap

## Next steps

<Columns cols={3}>
<Columns cols={2}>
<Card title="Connect with Teller" icon="plug" href="/connections/teller">
Configure Teller and enroll a bank using the Teller Connect flow.
</Card>
Expand All @@ -86,6 +90,10 @@ The same operations are available programmatically via the [Connections API](/ap
Set up Plaid credentials and link your first bank account.
</Card>

<Card title="Connect with SimpleFIN" icon="bridge" href="/connections/simplefin">
Paste a SimpleFIN setup token to pull in every bank linked at your bridge.
</Card>

<Card title="Import from CSV" icon="upload" href="/connections/csv-import">
Upload a CSV export from your bank and map columns to Breadbox fields.
</Card>
Expand Down
94 changes: 94 additions & 0 deletions connections/simplefin.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: "Connect banks with SimpleFIN"
description: "Paste a SimpleFIN setup token to bring banks into Breadbox through the SimpleFIN Bridge — including banks you add at the bridge after connecting."
sidebarTitle: "SimpleFIN"
---

[SimpleFIN](https://www.simplefin.org/protocol.html) is a token-paste, poll-only bank-data protocol commonly used by the self-hosting community via the hosted [SimpleFIN Bridge](https://bridge.simplefin.org) or a self-run server. It is the simplest provider Breadbox supports: no OAuth dialog, no SDK, no webhooks — just paste a setup token and Breadbox starts polling.

Use SimpleFIN when you already use the SimpleFIN Bridge, when your bank isn't covered by [Plaid](/connections/plaid) or [Teller](/connections/teller), or when you want a single token that spans multiple banks.

## What you need

- A **SimpleFIN account** at [bridge.simplefin.org](https://bridge.simplefin.org) (or a self-run server) with at least one bank linked at the bridge.
- A **setup token** generated from your bridge's setup page. Setup tokens are one-time-use and short-lived — generate one immediately before pasting it into Breadbox.
- The `simplefin_enabled` opt-in toggle set to `true` in Breadbox (either via the `SIMPLEFIN_ENABLED` environment variable or **Settings → Providers**). There is no per-server credential to configure.

## Connect a bank

<Steps>
<Step title="Generate a setup token at your bridge">
Sign in at [bridge.simplefin.org](https://bridge.simplefin.org), link your banks if you haven't already, and click **Create Token**. Copy the base64 setup token — it is single-use.
</Step>
<Step title="Start a new connection in Breadbox">
Go to **Connections** → **Connect New Bank**, select the household member who will own this connection, and choose **SimpleFIN** as the provider.
</Step>
<Step title="Paste the setup token">
Paste the token into the prompt and submit. Breadbox claims the token (exchanging it for an access URL), stores the credential encrypted, and discovers the accounts available at the bridge.
</Step>
<Step title="Wait for the initial sync">
Breadbox polls the bridge for about one year of transaction history on the first sync. Status flips to **Active** once the initial sync completes.
</Step>
</Steps>

One SimpleFIN connection covers **every bank you have linked at the bridge** — you don't run the connect flow once per bank.

## Automatic account discovery on every sync

SimpleFIN is an aggregator: the same access URL covers every bank you've linked at the bridge, and you can keep adding banks there at any time. To handle this, **every sync re-reads the full account list** from the bridge and Breadbox upserts any new accounts before processing transactions.

That means:

- A bank you link at the bridge **after** connecting Breadbox shows up automatically on the next scheduled sync — there is no "rescan accounts" button to hit and no need to re-paste your token.
- Existing accounts keep their settings (display name, exclusion flag, owner override). Only metadata is upserted on discovery — balances refresh on their normal path.
- If you want a newly added bank to appear sooner than the next scheduled run, click **Sync now** on the connection.

Plaid and Teller pin the account set at connect time, so this behavior is specific to SimpleFIN.

## Mixed-owner bridges and per-account owner override

A single SimpleFIN token often spans accounts belonging to **different household members** — for example, one partner links both their and their partner's banks at the same bridge. The Breadbox connection has a single owner, but you can reassign **individual accounts** to another household member using the per-account owner override.

### Set the owner from the admin dashboard

1. Open the account from **Accounts** (or from its connection).
2. In the **Settings** section of the account-detail page, change the **Owner** select to the household member who should own this account.
3. Save. The change takes effect immediately for new and existing transactions on that account — no resync, no backfill.

Selecting **Inherit from connection** clears the override and the account falls back to the connection's owner.

### Set the owner from the API

The override is exposed on `PATCH /api/v1/accounts/{id}` as the optional `owner_user_id` field. Pass a member's `short_id` to set it, or an empty string to clear it.

```json
{
"owner_user_id": "u8Xk2p9q"
}
```

### Attribution precedence

The effective owner of each transaction resolves at read time in this order:

1. **Per-transaction attribution** (from [account links](/transactions/overview), e.g. a child's purchases routed away from the parent who owns the card).
2. **Per-account owner override** (`accounts.owner_user_id`, the field you set above).
3. **Connection owner** (`bank_connections.user_id`, set when the connection was created).

The first one that's set wins. Because attribution resolves on the read path, reassigning an account's owner re-routes **every existing transaction** on that account across per-user totals, summaries, and category aggregations without any backfill job.

## Re-authentication

SimpleFIN tokens don't expire on a schedule, but the bridge can revoke the underlying access URL (for example, if you regenerate it from the bridge UI). When a sync starts returning `403`, the connection moves to **Re-auth Needed**.

To re-authenticate, generate a fresh setup token from the bridge, click **Re-authenticate** on the connection, and paste the new token. Breadbox rotates the stored credential in place — the connection row and all of its accounts and history are preserved.

## Limitations

- **No webhooks.** Sync runs on the cron schedule you configure (every 4, 8, 12, or 24 hours). There is no near-real-time path.
- **Balances and transactions only.** SimpleFIN doesn't expose investment holdings, statements, or identity data.
- **Amounts are inverted at the protocol level** — Breadbox normalizes signs internally, so amounts in the API and dashboard follow the same convention as Plaid and Teller.

## Disconnecting

Removing a SimpleFIN connection stops future syncs and preserves all previously synced transactions. To stop the bridge itself from holding your bank credentials, revoke the access URL from the SimpleFIN Bridge UI as well.
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"pages": [
"connections/teller",
"connections/plaid",
"connections/simplefin",
"connections/csv-import"
]
}
Expand Down
12 changes: 9 additions & 3 deletions guides/on-demand-analysis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,17 @@ If the answer comes back as a single number without naming a currency, that's a

### Attribution

Breadbox supports attributing transactions to a specific household member different from the account owner — for example, a child's purchases on a shared card attributed to the child, not the parent who owns the card. Transaction queries use `COALESCE(attributed_user_id, account_owner_user_id)` to resolve the effective user, so per-user totals "do the right thing" by default. But ad-hoc questions that slice by account and then by user can double-count if you're not careful.
Breadbox supports attributing transactions to a specific household member different from the account owner — for example, a child's purchases on a shared card attributed to the child, not the parent who owns the card. The effective user resolves at read time through a three-step precedence chain:

If you ask "how much did Alice spend last month," Claude filters by `user_id` correctly. If you ask "how much spending happened on the Chase Amex last month, broken down by user," the answer will respect attribution too. But if you ask "whose transactions are on the Chase Amex," the answer might surprise you — attributed transactions show a different user than the account owner.
1. **Per-transaction attribution** (from account links, e.g. a child's purchases routed away from the parent who owns the card).
2. **Per-account owner override** (set from the account-detail Settings page, useful when a single connection — like a [SimpleFIN](/connections/simplefin) bridge — spans accounts belonging to different household members).
3. **Connection owner** (the household member who created the connection).

When in doubt, ask Claude to say whether it's using account ownership or attribution to decide who a transaction belongs to.
The first one that's set wins, so per-user totals "do the right thing" by default. But ad-hoc questions that slice by account and then by user can double-count if you're not careful.

If you ask "how much did Alice spend last month," Claude filters by `user_id` correctly. If you ask "how much spending happened on the Chase Amex last month, broken down by user," the answer will respect attribution too. But if you ask "whose transactions are on the Chase Amex," the answer might surprise you — attributed transactions show a different user than the account owner, and the account itself may have been reassigned to another member via the per-account override.

When in doubt, ask Claude to say which of the three levels (per-transaction, per-account override, or connection owner) it's using to decide who a transaction belongs to.

### One more, minor: pending transactions

Expand Down