Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Surebeans Guide

Surebeans is a privacy-focused budgeting app for Windows, macOS, Linux, and the browser.

This guide covers setup, daily usage, and advanced features. You can start with the Quick Start or jump to the Reference.

For bank transaction scraping, see Beanscrape.

Questions? Send an email or visit the community forum.

Quick Start

Create a new journal

Click ☰ → New Journal and choose how to start:

  • From Scratch: creates an empty journal with starter accounts. See Create a Journal.
  • From nYNAB export: imports a .zip file exported from YNAB. See nYNAB.
  • From nYNAB API: imports directly from the YNAB API. See nYNAB API.
  • From YNAB 4: imports a .ynab4 budget folder. See YNAB 4.

Import into an existing journal

Once you have a journal open, click ☰ → Import to add records from external sources:

All import sources open the Import Review screen before writing to your journal.

Create a Journal

A journal is a folder containing plain-text hledger files tracked by git. It holds your accounts, records (that is, transactions), categories, budget allocations, rules, and sync configuration.

my-budget/
├── .git/                  # version history
├── main.journal           # root file. references the other files
├── accounts.journal       # account definitions
├── surebeans.json         # rules, remotes, app config
└── includes/
    ├── 2025.journal       # records for 2025
    └── 2026.journal       # records for 2026

Create the journal

Desktop: Click the hamburger menu (☰) → New Journal. Pick a folder.

Browser: Click ☰ → New Journal. Enter a name.

Surebeans creates a starter journal with example accounts and sample records.

Add an account

Navigate to Plan. Your starter journal includes some default accounts. To add more, go to Records, add a record, and type a new account name. Surebeans creates it automatically.

Add a record

Navigate to Records. Click + Add.

Fill in:

FieldExample
Date2026-01-15
PayeeGrocery Store
Amount-85.50
AccountAssets:Checking
CategoryBudget:Groceries

Press Enter or click away to save.

Assign money

Navigate to Plan. This is the envelope budgeting view.

  1. Income appears in Ready to Assign at the top.
  2. Click a category’s Planned column.
  3. Enter the amount to budget for that category.
  4. Repeat until Ready to Assign reaches zero.

The Available column shows Planned - Actual for each category. Green means under budget. Red means overspent.

Plan view with assigned money

Next steps

Reference

Detailed documentation for every area of Surebeans.

SectionDescription
Open JournalOpening, cloning, and loading journals
New JournalCreating a fresh journal
PlanEnvelope budgeting: categories, planned spending, available amounts
RecordsLedger: add, edit, filter, split, delete
AccountsAccount overview and balances
ReflectReports: net worth, spending, trends, cash flow
RulesAuto-categorization rules
SyncCloud sync with git, S3, WebDAV, and more
HistoryGit-based change history, undo, redo
SettingsTheme, license, updates, Beanscrape
ImportImport from nYNAB, YNAB 4, CSV, OFX, SimpleFIN

Open Journal

Click ☰ to access journal options.

Recent

Lists up to 10 recently opened journals. Click one to open it.

Pick Folder Desktop

Opens a native folder picker. Select a folder containing a main.journal file.

Browser: Not available. Journals are stored in browser storage and appear in the Recent list.

Clone from Remote

Downloads a journal from a remote server. See Sync for supported remote types.

  1. Select remote type (GitHub, GitLab, S3, etc.).
  2. Enter connection details (URL, token, etc.).
  3. Desktop: Choose a local destination folder.
  4. Surebeans clones the journal and opens it.

Browser: Limited remote types available. See Sync for browser vs desktop support.

Load Demo

Loads a pre-built demo journal with sample accounts, records, categories, and budget allocations. Useful for exploring the app before creating your own data.

New Journal

Creates a fresh journal: a git-tracked folder of plain-text hledger files, with starter accounts and a sample record.

Desktop

  1. Click ☰ → New Journal.
  2. Pick a destination folder via the native file dialog.
  3. Surebeans creates the journal files and initializes a git repository.

Browser

  1. Click ☰ → New Journal.
  2. Enter a name (e.g., my-budget).
  3. Journal is created in browser storage at /journals/<name>.

What gets created

my-budget/
├── .git/                  # created automatically
├── main.journal           # root file with include directives
├── accounts.journal       # account definitions
├── surebeans.json         # rules, remotes, app config
└── includes/
    └── 2026.journal       # records for the current year

A git repository is initialized and an initial commit is created automatically. Surebeans adds a new includes/<year>.journal file as needed.

Plan

Envelope budgeting view. Assign income to categories (envelopes) to control spending.

Plan view

Ready to Assign

Displayed at the top. Shows unbudgeted income, i.e. money received but not yet allocated to any category. Goal: bring this to zero each month.

Category groups

Collapsible sections that organize categories. Examples: Fixed Expenses, Variable Expenses, Savings Goals. Each group row shows totals for Assigned, Activity, and Available across its categories.

  • Add group: Click + Add Group in the header.
  • Rename: Click the pencil icon next to the group name.
  • Collapse/expand: Click the group row to toggle visibility of its categories.
  • Delete: Click the trash icon on the group row. Click again to confirm (two-stage delete). Click the X to cancel.

Categories (envelopes)

Each category represents a spending envelope.

ColumnDescription
CategoryName of the envelope. Click the pencil icon to rename.
AssignedAmount budgeted this month (editable).
ActivityAmount spent this month. Click to view matching records.
AvailableCumulative balance: prior months’ carry-forward + Assigned - Activity. Shown as a colored pill: green (positive), red (overspent), grey (zero).
  • Add category: Click + Add within a group.
  • Rename: Click the pencil icon next to the category name.
  • Delete: Click the trash icon on the category row. Click again to confirm. Click the X to cancel.

Uncategorized Records

When records exist without a budget category, an Uncategorized Records row appears at the top of the plan. Its Activity column shows the total uncategorized spending. Click it to jump to those records in the Records tab.

Move Money

Click a category’s Available pill to open the Move Money popup. Enter an amount and select a target category. The budgeted amounts for both categories are adjusted so Available balances shift accordingly.

Month navigation

Use the left/right arrows or month/year picker to navigate between months. Each month has independent assigned amounts.

Responsive layout

On narrow screens (under 600px), the Plan switches from a columnar table layout to a card-based layout with each category shown as a stacked card.

Overspending

When a category’s Available goes negative (red pill), you’ve overspent that envelope. Move money from another category or add more to Assigned.

Records

Ledger showing all records across accounts.

Records view

Columns

Each row has the following columns from left to right:

Grip handle. Drag a record up or down to reorder it. Drop it between rows to change its date. The record takes the date of the row below the drop line. Dropping above the first row sets the date to today.

Status dot. A colored circle showing the record’s cleared status:

  • Blue - New
  • Orange - Pending
  • Grey - Cleared

Click the dot to cycle through statuses. If multiple records are selected, clicking any selected dot cycles all of them together. Hover for a tooltip describing the current status and next action.

These map to hledger’s record status markers: New has no marker, Pending is !, and Cleared is *. You can use any workflow you like -for example, mark imported records as Pending and flip them to Cleared once you’ve verified them against your bank statement.

Date, Payee, Memo, Account, Category, Amount, Balance. Standard record fields. Balance is visible only when a single account is selected.

Selecting records

Click a row to select it.

Cmd+Click (macOS) or Ctrl+Click (Windows/Linux) to toggle individual rows in and out of the selection.

Shift+Click to select a range of rows from the current selection anchor to the clicked row.

Filter bar

Narrow the visible records.

Date range. Select a preset (Today, This Month, This Year, All) or a custom date range.

Account. Select one account. When a single account is selected, a cumulative running balance column appears.

Category. Filter to records in a specific budget category.

Search. Free-text search across payee and memo fields.

Adding a record

Click + Add. Fill in date, payee, amount, account, category, and optionally memo. Press Enter or click away to save.

A record is committed to your journal immediately.

Editing a record

Click a field to edit inline. Changes save when you click away or press Enter.

Editable fields: date, payee, amount, account, category, memo.

Splitting a record

Expand a row to view its postings. Split one record across multiple categories (e.g., a store receipt split between Groceries and Household).

Deleting records

Select one or more records. Click Delete or press the Delete key. A confirmation banner appears -press Delete again to confirm, or Escape to cancel (two-stage delete). Selected rows are highlighted in red while pending confirmation.

Renaming multiple records

Click Rename to open the bulk find-and-replace tool. Select a scope (payee, memo, category, or account), search for a value, and replace it across matching records.

Transfers

A transfer is a record between two asset/liability accounts. Enter both account names in the record. Surebeans marks the movement as a transfer. Click the swap icon on a transfer row to filter and show both sides.

Reordering records

Drag a row by its grip handle (the leftmost column). A blue line shows where the record will land. The record takes the date of the row below the drop line, or today’s date if dropped above the first row.

Reconciliation

Click the status dot to cycle a record’s cleared status: New (blue) → Pending (orange) → Cleared (grey). When multiple records are selected, clicking any dot in the selection cycles all selected records to the same status.

Infinite scroll

Records load progressively as you scroll. No pagination controls needed.

Keyboard shortcuts

KeyAction
EnterSave current edit
EscapeCancel current edit / cancel pending delete
DeleteMark selected for deletion (first press), confirm (second press)
F2Enter edit mode on selected cell
Cmd/Ctrl+ClickToggle row selection
Shift+ClickRange select

Accounts

Overview of all accounts and their balances, grouped by type.

Accounts view

Account groups

Accounts are organized into hierarchical groups:

  • Assets: checking, savings, cash
  • Liabilities: credit cards, loans
  • Income: salary, freelance, interest
  • Expenses: spending categories

Each group shows a total balance. Expand to see individual accounts.

Viewing account records

Click an account name to navigate to Records filtered to that account. The cumulative balance column becomes visible.

Account balances

Balances are computed from all records in the journal. They update in real time as you add or edit them.

Reflect

Reports and analytics. Select a report type from the pill bar at the top.

Reflect view

ReportDescription
Net WorthAssets minus liabilities over time
SpendingBreakdown by expense category
TrendsSpending patterns over time
Income vs ExpenseMonthly income and expense comparison
Cash FlowInflows and outflows
BufferDays of runway based on spending rate

Net Worth

Tracks your total assets minus total liabilities over time.

Net worth chart

Reading the chart

  • Assets (top line): Sum of all asset accounts (checking, savings, investments).
  • Liabilities (bottom line): Sum of all liability accounts (credit cards, loans).
  • Net Worth (middle area): Assets minus liabilities.

The chart shows monthly data points. Hover over a point to see exact values.

Date range

Adjust the date range to zoom in on a specific period or view the full history.

Spending

Breakdown of expenses by category for a given period.

Spending breakdown

Reading the chart

Shows each expense category’s share of total spending. Categories are sorted by amount.

Date range

Select a month or custom range to analyze spending for that period.

Trends

Spending patterns over time, broken down by category.

Spending trends

Reading the chart

Line chart showing monthly spending per category. Identify categories where spending is increasing or decreasing.

Date range

Adjust the range to view short-term or long-term trends.

Income vs Expense

Monthly comparison of total income and total expenses.

Income vs expense chart

Reading the chart

  • Income bars: Total income received each month.
  • Expense bars: Total expenses each month.
  • Net: The difference. Positive = you saved money. Negative = you spent more than you earned.

Date range

Shows monthly bars for the selected period.

Cash Flow

Inflows and outflows of money over time.

Cash flow chart

Reading the chart

  • Inflows: Money coming in (income, refunds, transfers in).
  • Outflows: Money going out (expenses, transfers out).

Helps identify months with cash shortfalls or surpluses.

Date range

Adjust to view monthly, quarterly, or yearly cash flow patterns.

Buffer

How many days of expenses your current balances can cover.

Buffer days chart

Reading the chart

Buffer = total liquid assets / average daily spending. A buffer of 30 means you could cover 30 days of expenses with no income.

Interpretation

BufferMeaning
< 30 daysLiving paycheck to paycheck
30-90 daysOne to three month cushion
> 90 daysSolid financial buffer

Track this over time to see if your financial resilience is improving.

Rules

Automate record categorization. Rules match records by pattern and apply actions (set category, memo, etc.).

Rules list

How rules work

When you run rules, Surebeans evaluates each uncategorized record against the rule list from top to bottom. The first matching rule wins. If no rule matches, the record is unchanged.

Rule structure

Each rule has:

  • Condition: Pattern to match against payee and/or memo (e.g., AMAZON matches any record containing “AMAZON”).
  • Action: What to do when matched (set category, set memo, etc.).
  • Match count: Number of existing records this rule would match.

Rule editor

Operations

ActionDescription
AddCreate a new rule
EditModify an existing rule’s condition or action
Move upIncrease rule priority (rules are evaluated top-to-bottom)
Move downDecrease rule priority
DuplicateCopy a rule as a starting point for a new one
DeleteRemove a rule (two-stage confirmation)
RunApply this rule to all matching records
Run AllApply all rules in order to all uncategorized records

Tips

  • Put more specific rules higher in the list.
  • Use Run on a single rule to preview its effect before running all.
  • Rules only apply to records that don’t already have a category (unless the rule is configured to override).

Sync

Sync your journal to a remote server for backup and multi-device access. Sync is manual: click Sync Now to push/pull changes.

Sync view

How it works

Your journal is a git repository. Sync pushes and pulls commits to/from a remote. If both sides changed since the last sync, Surebeans merges the changes. Conflicts are rare but handled with a resolution UI if they occur.

Adding a remote

  1. Navigate to Sync.
  2. Click Add Remote.
  3. Select a remote type and enter connection details.
  4. Click Sync Now to perform the first sync.

Supported remotes

RemoteDesktopBrowser
GitHubYesYes
GitLabYesYes
GiteaYesYes
Generic GitYesNo
S3YesYes
WebDAVYesYes
SFTPYesNo
DropboxYesYes

Managing remotes

  • Edit: Change connection details for an existing remote.
  • Delete: Remove a remote (two-stage confirmation). Does not delete remote data.
  • Last sync: Timestamp of the most recent successful sync.

Conflict resolution

If a merge conflict occurs, Surebeans shows the conflicting changes side-by-side. Choose which version to keep or manually edit the result.

Browser limitations

Some remote types require native network access not available in the browser. See the table above. For browser-compatible remotes that require CORS, Surebeans can use a CORS proxy.

GitHub

Sync your journal to a GitHub repository.

Setup

  1. Create a private repository on github.com.
  2. In Surebeans: SyncAdd RemoteGitHub.
  3. Enter the repository URL.
  4. Authenticate with one of the methods below.

GitHub remote setup

Option A: Personal Access Token

  1. Generate a Personal Access Token with repo scope.
  2. Paste the token into the Token field.

Option B: OAuth

  1. Toggle Use OAuth in the sync setup.
  2. Click Sign in. Your browser opens for GitHub authorization.
  3. Approve the request and return to Surebeans.

A default GitHub client ID is built in, so no additional configuration is needed.

Configuration

FieldRequiredNotes
Repository URLYeshttps://github.com/you/my-budget
TokenPAT onlyghp_xxxxxxxxxxxx
Use OAuthOAuth onlyToggle on, then click Sign in

Platform support

PlatformSupported
DesktopYes
BrowserYes

Tips

  • Use a private repo to keep financial data confidential.
  • The token is stored locally and never sent anywhere except GitHub.

GitLab

Sync your journal to a GitLab repository.

Setup

  1. Create a private project on gitlab.com (or your self-hosted instance).
  2. In Surebeans: SyncAdd RemoteGitLab.
  3. Enter the repository URL.
  4. Authenticate with one of the methods below.

GitLab remote setup

Option A: Personal Access Token

  1. Generate a Personal Access Token with write_repository scope.
  2. Paste the token into the Token field.

Option B: OAuth

  1. Create an OAuth application in your GitLab account or instance (SettingsApplications).
  2. Enter the Client ID in Surebeans.
  3. Click Sign in. On desktop, a redirect flow opens your browser. In the browser version, the device flow is used instead.
  4. Approve the request and return to Surebeans.

Configuration

FieldRequiredNotes
Repository URLYeshttps://gitlab.com/you/my-budget
TokenPAT onlyglpat-xxxxxxxxxxxx
Client IDOAuth onlyFrom your GitLab OAuth application

Platform support

PlatformSupported
DesktopYes
BrowserYes

Gitea

Sync your journal to a Gitea instance.

Setup

  1. Create a private repository on your Gitea server.
  2. In Surebeans: SyncAdd RemoteGitea.
  3. Enter the repository URL.
  4. Authenticate with one of the methods below.

Gitea remote setup

Option A: Access Token

  1. Generate an access token in SettingsApplications on your Gitea instance.
  2. Paste the token into the Token field.

Option B: OAuth

  1. Create an OAuth application on your Gitea instance (SettingsApplicationsManage OAuth2 Applications).
  2. Enter the Client ID in Surebeans.
  3. Click Sign in. A redirect flow opens your browser for authorization.
  4. Approve the request and return to Surebeans.

Configuration

FieldRequiredNotes
Repository URLYeshttps://gitea.example.com/you/my-budget
TokenToken onlyxxxxxxxxxx
Client IDOAuth onlyFrom your Gitea OAuth application

Platform support

PlatformSupported
DesktopYes
BrowserYes

Generic Git

Sync to any git remote accessible via SSH or HTTPS.

Setup

  1. Set up a bare git repository on your server.
  2. In Surebeans: SyncAdd RemoteGeneric Git.
  3. Enter the remote URL.

Configuration

FieldExample
Remote URL[email protected]:budget.git or https://yourserver.com/budget.git

Authentication depends on the transport:

  • SSH: Uses your system SSH key.
  • HTTPS: Enter username and password/token.

Platform support

PlatformSupported
DesktopYes
BrowserNo. Requires native git/SSH access.

S3

Sync your journal to an S3-compatible object store (AWS S3, MinIO, Cloudflare R2, Backblaze B2, etc.).

Setup

  1. Create a bucket on your S3 provider.
  2. Generate access credentials (Access Key ID + Secret Access Key).
  3. In Surebeans: SyncAdd RemoteS3.
  4. Enter bucket, region, and credentials.

Configuration

FieldExample
Bucketmy-budget-backup
Regionus-east-1
Endpointhttps://s3.amazonaws.com (or custom for non-AWS)
Access Key IDAKIAXXXXXXXXXX
Secret Access Keyxxxxxxxxxxxxxxxx

Platform support

PlatformSupported
DesktopYes
BrowserYes (may require CORS configuration on the bucket)

CORS (browser)

If syncing from the browser, configure your bucket’s CORS policy to allow requests from https://app.surebeans.net (or wherever you host the app).

WebDAV

Sync your journal to a WebDAV server (Nextcloud, ownCloud, etc.).

Setup

  1. Ensure you have a WebDAV endpoint. Nextcloud provides one at https://your-instance.com/remote.php/dav/files/USERNAME/.
  2. In Surebeans: SyncAdd RemoteWebDAV.
  3. Enter the URL and credentials.

Configuration

FieldExample
URLhttps://nextcloud.example.com/remote.php/dav/files/you/budget/
Usernameyou
Passwordxxxxxxxx

Platform support

PlatformSupported
DesktopYes
BrowserYes (may require CORS proxy)

SFTP

Sync your journal to any server with SSH/SFTP access.

Setup

  1. Ensure you have SSH access to the target server.
  2. In Surebeans: SyncAdd RemoteSFTP.
  3. Enter connection details.

Configuration

FieldExample
Hostmyserver.com
Port22
Path/home/you/budget/
Usernameyou
AuthenticationSSH key or password

Platform support

PlatformSupported
DesktopYes
BrowserNo. Requires native SSH access.

Dropbox

Sync your journal to Dropbox.

Setup

  1. In Surebeans: SyncAdd RemoteDropbox.
  2. Authorize Surebeans to access your Dropbox account.
  3. Choose a folder path within Dropbox.

Configuration

FieldExample
Folder/Apps/Surebeans/my-budget

Authorization uses OAuth. Surebeans never sees your Dropbox password.

Platform support

PlatformSupported
DesktopYes
BrowserYes

History

Every change to your journal is a git commit. History shows the full commit log.

History view

Commit log

Displays commits in reverse chronological order.

ColumnDescription
WhenTimestamp
ChangeCommit message describing what changed
IDShort git SHA

Use pagination controls (First, Previous, Next, Last) to navigate.

Revert

Select a commit to restore the journal to that point in time. This creates a new commit that undoes all changes after the selected point. No data is destroyed.

Undo / Redo

ActionShortcut
UndoCtrl+Z (Cmd+Z on macOS)
RedoCtrl+Y (Cmd+Y on macOS)

Undo reverts the most recent commit. Redo re-applies it. Both are global: they affect the entire journal, not just the current view.

How it works

Surebeans uses git under the hood. Each save operation (add record, edit record, change budget allocation, etc.) creates a git commit. The History view is a UI over git log.

This means:

  • Every change is tracked and reversible.
  • You can sync your journal to any git remote (see Sync).
  • Advanced users can interact with the journal’s git repo directly.

Settings

App configuration and status.

Settings view

Theme

Switch between Light, Dark, and Auto (follows system preference). Changes apply immediately.

Currency

Configure how currency values are displayed. This is a per-journal setting saved to the journal config file.

Presets

PresetSymbol
USD$
EUR
AUDA$
GBP£
CADC$

Select a preset or enter a custom symbol.

Symbol position

OptionExample
Before amount$1,234.56
After amount1,234.56 €
Don’t show1,234.56

License

  • Status: Shows Licensed or Trial.
  • Email: Licensed email address (if licensed).
  • Record count: Current count and trial limit.
  • Enter license key: Paste the license key you received by email or after checkout.
  • Buy: Link to purchase a license.

The trial allows a limited number of records. Purchase a license to remove the limit.

Updates Desktop

  • Check for updates: Queries for available versions.
  • Download and install: Applies the update.
  • Current version: Displayed at bottom.

Not available in the browser. The browser version updates automatically.

Beanscrape Desktop

  • Installation status: Whether Beanscrape is installed.
  • Version: Installed version number.
  • Download/Install: Install or update Beanscrape.
  • Custom path: Override the Beanscrape executable path.

For full Beanscrape documentation, see the Beanscrape section.

Import

Bring data into Surebeans from external sources.

New Journal creates a fresh journal from the import. Existing Journal adds records to a journal you already have open.

SourceNew JournalExisting JournalDescription
nYNABYesYesImport from nYNAB export
nYNAB APIYesYesImport directly from the YNAB API
YNAB 4YesYesImport from YNAB 4 budget folder
File (CSV, OFX/QFX)NoYesImport records from bank-exported files
SimpleFINNoYesImport via account aggregation service
hledgerNoYesImport from an hledger journal file
BeanscrapeNoYesImport via browser-based bank scraping

For sources that don’t support creating a new journal, create one from scratch first.

nYNAB Import

Import a budget from an nYNAB export. Can create a new journal or import into an existing one.

What gets imported

YNAB conceptSurebeans equivalent
AccountsAccounts (Assets, Liabilities)
Category GroupsCategory groups
CategoriesBudget categories (envelopes)
TransactionsRecords
Monthly budgetsPlan allocations
PayeesPayee field on records
MemosMemo field on records
Cleared statusReconciliation status

Export format

YNAB exports a .zip file containing CSV files for accounts, budgets, and records.

Incremental import

You can also add new records to an existing journal. Open the journal you want to update, then go to ☰ → ImportFrom nYNAB export…. Surebeans adds any records that are not already present rather than creating a new journal.

To skip the manual file export, use the nYNAB API import instead.

Import Review

After importing, Import Review appears.

Limitations

  • Scheduled records are not imported.
  • Goal targets are not imported.
  • Loan accounts may need manual review.

nYNAB API Import

Import records directly from the YNAB API using a Personal Access Token.

Unlike the nYNAB file import, this method connects to YNAB’s API so there is no need to manually export and upload a file.

Setup

  1. Generate a Personal Access Token in your YNAB account settings.
  2. In Surebeans: ☰ → ImportFrom nYNAB API…
  3. Paste your Personal Access Token.
  4. Select a budget from the dropdown list.
  5. Click Import.

YNAB API setup

New journal or incremental import

The API import supports two modes:

ModeWhen to use
Create new journalFirst-time import; builds a full journal from your YNAB budget
Add to existing journalIncremental import; adds new records to your current journal

To do an incremental import, open an existing journal first, then run the import. Surebeans will add any records that are not already present.

For incremental imports, the process has two steps:

  1. Conflict review: if any existing records were modified in YNAB, you choose which version to keep (local or YNAB).
  2. Record review: new and conflicting records are shown per-account in the Import Review screen.

Stored settings

Your Personal Access Token and selected budget are saved locally so you do not need to re-enter them on subsequent imports.

What gets imported

See nYNAB Import - What gets imported for the full mapping between YNAB and Surebeans concepts.

Import Review

After importing, Import Review appears.

Tips

  • The Personal Access Token is stored locally and never sent anywhere except the YNAB API.
  • Use incremental import to keep your Surebeans journal up to date without re-importing everything.
  • The YNAB API limits 200 web requests per hour. If you get errors, wait up to an hour and try again.

YNAB 4 Import

Import a budget from YNAB 4 (classic desktop version). Can create a new journal or import into an existing one.

What gets imported

Same mapping as nYNAB import: accounts, categories, records, and budget allocations.

Data format

YNAB 4 stores budgets as .ynab4 folders containing JSON/SQLite files. Surebeans reads this format directly.

Typical locations

OSPath
macOS/Linux~/Dropbox/YNAB/
WindowsC:\Users\<you>\Dropbox\YNAB\

Import Review

After importing, Import Review appears.

Limitations

  • Scheduled records are not imported.
  • YNAB 4’s “Red Arrow Right” behavior is not replicated.

File Import (CSV, OFX/QFX)

Import records from bank-exported files into an existing journal.

Supported formats

  • CSV. Comma-separated values. Columns are auto-detected from headers and can be adjusted manually.
  • OFX. Open Financial Exchange. Self-describing, no column mapping needed.
  • QFX. Quicken variant of OFX. Treated the same as OFX.

CSV options

  • Delimiter: Comma, semicolon, or tab.
  • Date format: e.g., yyyy-MM-dd, MM/dd/yyyy.
  • Invert amounts: Flip the sign (some banks export expenses as positive).
  • Split inflow/outflow: Use separate columns instead of a single amount column.
  • Account: Which account these records belong to.

OFX/QFX options

  • Account: Which account these records belong to.
  • Invert amounts: Flip the sign if needed.

Import Review

After selecting a file, Import Review appears.

SimpleFIN

Import records from your bank via SimpleFIN, an account aggregation service.

What is SimpleFIN?

SimpleFIN connects to your bank through a read-only data feed. It retrieves records without screen scraping, using official bank data feeds where available. SimpleFIN is a paid service ($1.50/month at time of writing).

Setup

  1. Create a SimpleFIN account.
  2. Connect your bank accounts within SimpleFIN.
  3. Generate a SimpleFIN access token.
  4. In Surebeans: ☰ → ImportFrom SimpleFIN.
  5. Paste the access token.
  6. Map SimpleFIN accounts to Surebeans accounts.

SimpleFIN setup

Importing records

Once configured, import fetches recent records from all connected accounts.

Import Review

After importing, Import Review appears.

SimpleFIN vs Beanscrape

SimpleFINBeanscrape
MethodBank data feedsBrowser automation
SetupCreate account, paste tokenInstall CLI, create scripts via LLM
Cost$1.50/monthFree
Bank coverageWide in the USAny bank with a website
PrivacyData passes through SimpleFIN serversFully local, no third parties

hledger Import

Import records from an hledger journal file into your Surebeans journal.

When to use

Use this when you have an existing hledger journal and want to bring its records into Surebeans. Records are matched by account, so multi-account hledger files are split across the appropriate Surebeans accounts.

How to import

  1. Open your Surebeans journal.
  2. Go to ☰ → Importhledger.
  3. Select an .journal file. Surebeans follows include directives automatically.

What gets imported

  • All transactions from the hledger file (and any included files)
  • Account names are mapped directly from hledger paths
  • Cleared status is preserved (* = Cleared, ! = Pending)

hledger rules import

If the selected file has a corresponding .csv.rules file, Surebeans can import if/account2 blocks as automation rules. Click Import Rules on the import screen to convert them.

Import Review

After importing, Import Review appears.

Limitations

  • Only works with existing journals (no “create new journal” mode)
  • Virtual postings (budget allocations) are not imported
  • Comments and tags are not preserved

Import Review

After importing records from any source, Surebeans opens the Import Review screen. This lets you inspect each incoming record and preview its effect on your running balance before committing it to the journal.

Import Review screen

Account name

Account name header

The records will be applied to the shown account.

If you imported from multiple banks, import review cycles through them one at a time.

Toolbar

Toolbar

Near the top of the screen is the toolbar.

Period

Records are grouped by time period. Choose between Day, Week, and Month.

  • By default, periods where everything matches are collapsed.
  • By default, periods with new, conflicting, or updated records are expanded.
  • Click any period header to collapse or expand it.

Each period has a summary row at the bottom showing end-of-period balances.

Tolerance

How many days apart records with different dates can be matched. They must have the same payee, memo, and amount. Default: 3 days.

For example, the incoming record 2026-01-04 | Amazon | MEMO1234 | $10.23 can match the existing record 2026-01-01 | Amazon | MEMO1234 | $10.23.

Accept All

Click this button to check Accept next to all records. Uncheck to uncheck them all.

Apply Rules

Click this button to apply automation rules on the incoming records.

Edit Rules

Click this button to navigate to the rules editor.

View Data

Click this button to see the raw imported data text, e.g. CSV, OFX, or JSON, depending on the source.

Status bar

Status bar

If all balances match, a green “All balances reconciled” bar appears. If there’s a discrepancy, a warning bar shows the amount. You can still click Apply.

Summary bar

Summary bar

Beneath the toolbar, the summary bar shows counts of each record change type: matched, updated, new, and conflict.

Records

Column headers

Record change type

Import Review compares each record to import with your existing Surebeans records and assigns a change type.

PillMeaning
matched (grey)Already in Surebeans. No action needed.
updated (blue)Amounts match but the cleared/pending status changed.
new (green)Exists in the bank but not in Surebeans.
conflict (red)Exists in both but amounts differ, or exists only in Surebeans

Date

The date from the incoming data appears here.

Payee, Memo, Category

The payee, memo, and category fields from the incoming data appear here. On rows with change type new and conflict rows, you can edit them.

Balances

When the imported data includes a running balance, the review shows Bank and Surebeans (SB) columns side-by-side, and the Diff column highlights any discrepancy in yellow.

When the imported data doesn’t include a running balance, the these columns show only the Surebeans balance.

Accepting and rejecting

Every unmatched row has an Accept checkbox, checked by default.

  • Checked accepts the bank’s value.
  • Unchecked keeps what’s already in Surebeans.

Action bar

Action bar

At the bottom is the Action bar. Use the Back and Next buttons to navigate between accounts. The Apply button appears on the last account.

Glossary

Key terms used throughout Surebeans.

Core Concepts

  • Record:A single dated transaction (date, payee, status, postings)
  • Posting:One line of a record: an account + amount
  • Transfer:A record where both postings are to asset/liability accounts
  • Virtual Posting:A posting in [brackets], used for budget allocations
  • Account:A named ledger (e.g., Assets:Checking, Expenses:Groceries)
  • Account Type:Asset, Liability, Income, Expense, Equity, Budget, Tracking
  • Journal:The ledger file containing all records

Import

  • Bank Record:A flat representation of a transaction from an external source
  • Bank ID:Source identifier on a Bank Record (e.g., "ynab", "hledger", "discover")
  • Import Tag:Per-posting deduplication tag: import:{bankId}:{6-char hash}
  • Import Review:UI for comparing imported records against existing journal records

Accounting

Account

A named ledger identified by a colon-separated path. The first segment determines the Account Type.

Examples: Assets:Checking, Expenses:Home:Groceries, Liabilities:Mortgage

The DisplayName is the last segment (e.g., Groceries). The full path is used for Postings and matching.

Account Type

Inferred from the first segment of an Account path.

PrefixTypeMeaning
Assets:AssetMoney you have (checking, savings). Both sides of a Transfer.
Liabilities:LiabilityMoney you owe (credit cards, loans). Both sides of a Transfer.
Expenses:ExpenseMoney spent
Income:IncomeMoney earned
Equity:EquityOpening balances, adjustments
Budget:BudgetEnvelope allocations
Tracking:TrackingOff-budget accounts (YNAB concept)

Bank ID

Source identifier on a Bank Record. Used to generate the Import Tag for deduplication.

Examples: "ynab", "hledger", "discover", "csv:transactions.csv"

Each importer provides its own value. Not stored in the Journal; only used transiently during import.

Bank Record

A flat (non-Double Entry) representation of a transaction from an external source. Has a single amount (inflow or outflow), payee, date, and Bank ID.

Used as an intermediate format during import. Converted to/from Records during the import process. For Transfers, the target account is preserved in the Category field during the roundtrip.

Each Bank Record generates an Import Tag for deduplication during Import Review.

Cleared Status

Reconciliation state of a Record.

StatusMarkerMeaning
Uncleared(none)Not yet confirmed
Cleared*Confirmed against bank statement
Pending!In progress (e.g., pending transaction)

Double Entry

Every Record’s Postings must sum to zero. Money always comes from somewhere and goes somewhere.

A purchase debits an expense and credits an asset:

    Assets:Checking     -$50.00
    Expenses:Groceries   $50.00

This constraint ensures the books always balance.

Envelope

A budgeting method where money is allocated to categories (envelopes) before it’s spent. When you buy groceries, the money comes from the Groceries envelope.

In Surebeans, envelopes are represented as Budget: Account Type accounts. Money is allocated via Virtual Postings:

2026-03-01 Budget allocation
    [Budget:Home:Groceries]    $500.00
    [Income:Ready to Assign]  -$500.00

This moves $500 from the shared pool (Income:Ready to Assign) into the Groceries envelope. The YNAB import flows generate these allocations automatically.

Import Tag

Per-posting deduplication identifier for matching imported Bank Records to existing Postings in the Journal. Written as the import tag inside a posting comment using hledger key:value syntax (e.g., ; import:schwab:abcdef).

Format: {bankId}:{6-char hash}

The hash covers the bank ID, date, signed amount, payee, and memo. The bank prefix is retained for debuggability — date and amount are omitted since they’re already on the posting.

Exception: YNAB API uses ynab:{transactionId} (YNAB’s stable UUID) instead of the hash-based format.

Import Review

UI for comparing imported Bank Records against existing Journal Records, per-account.

See Import Review for full documentation.

Journal

The ledger file (.journal) containing all Records and Account declarations. Uses hledger-compatible plain text format. Every record follows Double Entry rules.

Can include other files via include directives.

Records are imported from external sources via Import Review, which converts Bank Records into journal records.

Posting

One line of a Record: an Account and an amount. Every record has at least two postings that balance to zero (Double Entry).

    Assets:Discover    -$22.39    <- this is one posting
    Expenses:Groceries  $22.39    <- this is another

A posting can be a Virtual Posting (wrapped in [brackets]), used for Envelope allocations. Virtual postings don’t affect asset/liability balances.

Record

A single dated transaction. Contains a date, payee, memo, Cleared Status, and a list of Postings.

2026-03-16 Kroger
    Assets:Discover    -$22.39
    Expenses:Groceries  $22.39

A record’s postings must follow Double Entry: they sum to zero. A record with exactly two asset/liability postings is a Transfer.

Running Balance

Cumulative balance of an Account up to and including a given Record, computed by summing all Postings to that account in date order.

In Import Review, two running balances are shown when the import source provides its own (currently only Beanscrape):

  • Bank: from the bank’s reported running balance
  • SB: computed from journal records and user choices

When the source doesn’t provide running balances, the balance columns are not shown. See also Journal, Double Entry.

Transfer

A Record where both Postings are to asset or liability accounts. Represents money moving between your own accounts rather than income or expense.

2026-03-16 Transfer : Discover
    Assets:Schwab Checking  -$1,957.54
    Assets:Discover          $1,957.54

When one side is a credit card, the UI displays the payee as Payment To: / Payment From: instead of Transfer To: / Transfer From:.

Virtual Posting

A Posting wrapped in [brackets]. Used for budget Envelope allocations. Virtual postings don’t affect asset/liability balances and are excluded from Transfer detection.

2026-03-01 Budget allocation
    [Budget:Home:Groceries]    $500.00
    [Income:Ready to Assign]  -$500.00

Beanscrape

Beanscrape is a local, privacy-focused CLI tool that scrapes records from financial institution websites using browser automation.

Features

  • Fully local. Runs on your machine. No credentials or data leave your computer (except to your bank’s website).
  • Free and Open Source (FOSS). You may view, modify, and redistribute the source code.
  • Scriptable. Bank scripts are C# scripts.
  • Extensible. Create scripts for any bank using the interactive teach command and an LLM.

How it works

  1. Beanscrape opens a real browser (Chromium via Playwright).
  2. You log in to your bank. If you saved your credentials, it logs in for you.
  3. Navigates to the transaction page.
  4. Extracts transactions.
  5. Outputs JSON or CSV.

You then import the output into Surebeans (or any budgeting tool).

You agree to follow your bank’s terms of service. Most banks have a “use at your own risk” policy toward finance automation tools, but some deploy technical or contractual mechanisms to block them.

In general, accessing your own financial data via automated tools is supported by:

  • CFPB Section 1033 (Dodd-Frank Act): consumers have the right to access their financial data.
  • GDPR Article 20: right to data portability.
  • Van Buren v. United States (2021): accessing data you’re authorized to view is not a CFAA violation.

Sections

PageDescription
InstallDownload and install Beanscrape
RunScrape transactions
CredentialsStore bank login credentials securely
ScriptsBank scripts overview
TeachInteractive session to capture bank website details
Script CreationGenerate new scripts using an LLM
TroubleshootingCommon issues and fixes

Install

Beanscrape is a single-file executable. No runtime dependencies.

  1. Open Surebeans → Settings.
  2. Scroll to the Beanscrape section.
  3. Click Install.

Surebeans downloads and installs the correct version for your platform.

Beanscrape section in Settings

Manual download

Download from surebeans.net/beanscrape.

PlatformFile
Windowsbeanscrape-win-x64.exe
Windows (ARM)beanscrape-win-arm64.exe
macOS (Intel)beanscrape-osx-x64
macOS (Apple Silicon)beanscrape-osx-arm64
Linuxbeanscrape-linux-x64
Linux (ARM)beanscrape-linux-arm64

Place the executable somewhere on your PATH.

First run

On first launch, Beanscrape downloads and installs the Playwright browser engine (~150 MB). This only happens once.

$ beanscrape run amex

Playwright browsers not installed. Installing chromium...

Self-update

$ beanscrape update

Checks for and installs the latest version.

Run

Scrape transactions from one or more banks.

Basic usage

$ beanscrape run ./mybank.csx

Multiple banks

Pass multiple .csx file paths to scrape in parallel (each in its own browser tab):

$ beanscrape run ./amex.csx ./discover.csx ./schwab.csx

Options

FlagShortDescriptionDefault
--outdir-dOutput directoryoutput/
--format-fOutput format: json or csvjson
--keep-open-kKeep browser open after scraping (for review)off
--nodeNode.js mode: system, download, or autoauto
--debugEnable debug loggingoff

Output

Transactions are written to <outdir>/<bank-id>.json (or .csv).

JSON format

{
  "bank": "amex",
  "scrapedAt": "2026-01-13T21:22:25Z",
  "transactions": [
    {
      "date": "2026-01-12",
      "payee": "GROCERY STORE",
      "memo": null,
      "outflow": 85.50,
      "inflow": null,
      "runningBalance": 1228.78,
      "isPending": false,
      "category": "Supermarkets"
    }
  ]
}

CSV format

Columns: date, payee, memo, outflow, inflow, runningBalance, isPending, category.

Progress UI

While scraping, a browser panel shows real-time progress with step indicators. You can pause or cancel from this panel.

2FA

If your bank requires two-factor authentication, Beanscrape pauses and waits for you to complete the verification in the browser. Once you approve, scraping resumes automatically.

Next steps

Import the output into your ledger software, or use the JSON/CSV files directly. See Import Review for how Surebeans handles this.

Credentials

Beanscrape stores bank login credentials in your OS-native secure storage.

Storage locations

OSStorage
macOSLogin Keychain
WindowsDPAPI-encrypted file at %LOCALAPPDATA%/beanscrape/credentials.dat
Linuxfreedesktop Secret Service, or AES-256-encrypted file at ~/.local/share/beanscrape/credentials.dat

Credentials never leave your machine.

Add credentials

$ beanscrape credential add <bank-id> -u <username>
Password: ********

The password is read from stdin (not echoed).

List stored credentials

$ beanscrape credential list

Shows which bank IDs have stored credentials (passwords are not displayed).

Update credentials

$ beanscrape credential update <bank-id> -u <new-username>
Password: ********

Remove credentials

$ beanscrape credential remove <bank-id>

Environment variables

As an alternative to the credential store, set environment variables:

export [email protected]
export AMEX_PASSWORD=mysecretpassword

Variable names follow the pattern {BANKID}_USERID and {BANKID}_PASSWORD (uppercase, hyphens replaced with underscores).

You can also use a .env file in the current working directory.

Priority order: Environment variables > .env file > credential store.

Scripts

Bank scripts are C# files (.csx) that tell Beanscrape how to log in, navigate, and extract transactions from a specific bank’s website.

Running a script

Pass a .csx file path to beanscrape run:

$ beanscrape run ./mybank.csx

See Run for details.

Reviewing scripts

Scripts are plain text C# files. Open them in any editor to review what they do before running. You can verify a script doesn’t exfiltrate your credentials.

Creating scripts

See Teach and Script Creation for how to create a new script for your bank.

Teach

The teach command opens an interactive browser session to capture the details Beanscrape needs to generate a bank script.

Usage

$ beanscrape teach <bank-id>

Example:

$ beanscrape teach chase

What happens

  1. A browser window opens with the Teach UI panel.
  2. Navigate to your bank’s login page.
  3. The panel guides you to capture:
    • Login page URL
    • Username and password field selectors
    • Login button selector
    • Transaction page URL and selectors
    • Transaction table structure (date, payee, amount columns)
  4. Optionally capture screenshots of each step.

The teach panel opens alongside the bank website. Here’s what a typical session looks like:

Step 1: Navigate to your bank’s website

Navigate to bank

Step 2: Log in to your account

Login page

Step 3: Navigate to transaction history

Transactions page

Step 4: Select account and date range

Select account

Select date range

Step 5: Identify the transaction table

Select table

Step 6: Export and finish

Download file

Finish

Output

Teach generates a markdown file at ./prompts/<bank-id>.md containing:

  • Captured URLs
  • DOM selectors
  • Screenshots (as base64 or file references)
  • Structural notes about the page layout

This file is the input for Script Creation.

Options

FlagShortDescription
--output-oOverride output file path

Tips

  • Log in manually during the teach session so the panel can observe the DOM structure.
  • If your bank has multiple transaction views (recent, statements, downloads), capture all of them. You can choose the best approach when generating the script.
  • The teach session does not store credentials.

Script Creation

Generate a new bank script by combining the output of Teach with an LLM.

Workflow

  1. Run beanscrape teach <bank-id> to capture bank website details. Output: ./prompts/<bank-id>.md.
  2. Open the prompt file and the script generation guide (bundled with Beanscrape, also at docs/new-script.md in the source repo).
  3. Paste both into an LLM (Claude, ChatGPT, etc.).
  4. The LLM generates a .csx script.
  5. Save the script as <bank-id>.csx.
  6. Test: beanscrape run ./<bank-id>.csx --debug.
  7. Iterate with the LLM if the script needs adjustments.

Script structure

A bank script is a C# script (.csx) that uses Beanscrape’s runtime API:

// Required: bank metadata
BankId = "mybank";
BankName = "My Bank";
BankUrl = "https://www.mybank.com";

// Required: scrape function
Scrape = async (page) =>
{
    // 1. Navigate to login page
    await NavigateAsync(page, "https://www.mybank.com/login");

    // 2. Enter credentials
    await FillAsync(page.Locator("#username"), Env("MYBANK_USERID"));
    await FillAsync(page.Locator("#password"), Env("MYBANK_PASSWORD"));
    await ClickAsync(page.Locator("#login-button"));

    // 3. Navigate to transactions
    await NavigateAsync(page, "https://www.mybank.com/transactions");

    // 4. Extract transactions
    var rows = await page.Locator(".transaction-row").AllAsync();
    foreach (var row in rows)
    {
        AddTransaction(new Transaction
        {
            Date = ParseDate(await row.Locator(".date").TextContentAsync()),
            Payee = await row.Locator(".payee").TextContentAsync(),
            Outflow = ParseAmount(await row.Locator(".amount").TextContentAsync()),
        });
    }
};

Available API

Metadata & environment

Property/MethodDescription
BankId(Required) Unique bank identifier, used to match transactions to accounts
BankName(Required) Display name for the bank
RequiredEnvVarsArray of environment variable names the script needs
StepsArray of step names for the progress UI
ScriptPathFull path to the executing .csx file (read-only, set by runtime)
Env(name)Read environment variable or credential
Log(message)Write to debug log
StartStep(index)Mark a step as started in the progress UI

Browser helpers

MethodDescription
NavigateAsync(page, url)Navigate with retries
ClickAsync(locator)Click with human-like delay
FillAsync(locator, value)Type text with human-like delay
HumanDelayAsync(min, max)Random wait (default 500-1500ms)
WaitForSelectorAsync(page, selector)Wait for element
IsElementVisibleAsync(page, selector)Check element visibility

Parsing helpers

MethodDescription
ParseDate(string)Parse various date formats to DateOnly
ParseAmount(string)Parse currency string to decimal
ParseAmountAccounting(string)Parse accounting format (parentheses = negative)

File parsing

MethodDescription
ParseQfx(filePath)Parse OFX/QFX file to transactions
ParseQfxContent(content)Parse OFX/QFX string content

Available libraries

Scripts have access to:

  • Playwright: browser automation
  • CsvHelper: CSV parsing
  • QFXparser: OFX/QFX parsing
  • System.Text.Json: JSON handling
  • Standard .NET libraries (Linq, Regex, IO, Collections)

Tips

  • Use --debug when testing to see detailed logs.
  • Use --keep-open to inspect the browser state after a scrape.
  • Some banks serve different content based on viewport size. The default viewport works for most.
  • For banks that offer CSV/OFX download, prefer downloading the file and parsing it rather than scraping the DOM. It’s more reliable.

Troubleshooting

Browser fails to install

Beanscrape downloads Chromium via Playwright on first run. If this fails:

  1. Check your internet connection.
  2. Check firewall/proxy settings. Playwright downloads from Microsoft’s CDN.
  3. Try running again. The download resumes where it left off.

Login fails

  • Wrong credentials: Run beanscrape credential update <bank-id> to re-enter.
  • 2FA timeout: If the 2FA prompt times out, re-run the scrape. Beanscrape waits for manual 2FA completion.
  • Bank changed their login page: The script may need updating. Run beanscrape teach <bank-id> to recapture the login flow and regenerate the script.

No transactions returned

  • Date range: Some scripts only fetch recent transactions. Check the script or run with --debug to see what date range is being queried.
  • Account selection: If the bank has multiple accounts, the script may default to the first one. Check the script source.
  • Page structure changed: Bank websites change frequently. The script may need updating.

Script errors

Run with --debug for detailed error output:

$ beanscrape run ./amex.csx --debug

Common issues:

  • Selector not found: The bank’s HTML structure changed. Update the script.
  • Timeout: The page took too long to load. Try running again; bank websites can be slow.

Browser state issues

Beanscrape saves browser session state (cookies, etc.) between runs. If you’re having persistent issues:

  1. Clear browser state:
OSPath
macOS~/.config/beanscrape/browser-state/
Linux~/.local/share/beanscrape/browser-state/
Windows%LOCALAPPDATA%\beanscrape\browser-state\
  1. Delete the contents of this directory and re-run.

Getting help