Register your bank accounts and import a statement

Register each real account once with its purpose and its opening balance as at a date, using only the last four digits. Then export the account's transactions from internet banking as a CSV and import it into that account. The import checks the file chains onto the account's last balance before writing anything, and refuses with the expected and actual figures if it does not. Import weekly, because the export window rolls and a skipped week is a hole the close will refuse over.

Before you start

You need the last four digits of each account, and for each one an opening balance and the date it was true. The cleanest anchor is the closing balance on the last statement before you started using Biloh for money.

Step 1: register each account

Say it, or fill the form on Finance, then Bank accounts, then "Register a bank account":

"Register my everyday account, transaction, ending 1234, opening balance $2,500.00 as at 1 August."

create_bank_account stores the name, institution, a masked identifier (the last four digits, or ****1234), the kind (transaction or savings), the purpose (operating, tax_set_aside, contractor_buffer), and the opening balance with its date. A full account number or BSB is refused with identifier_not_masked; Biloh never holds one. Names must be unique within the business.

Do the same for the tax set-aside and the contractor buffer. Their purposes are what turn the envelope targets into a measured gap.

To correct an account, use update_bank_account. To retire one, set it inactive with the same tool. Accounts are never deleted, and an archived account's lines still count in completeness.

Step 2: export the statement

In internet banking, export the account's transactions for the window since your last import as a CSV. The expected shape is header-less, four columns: date as DD/MM/YYYY, signed amount (credit positive, debit negative), description, running balance. The running balance column is what makes the balance chain possible; do not strip it.

Step 3: import it into the right account

"Import this file into the everyday account."

On screen: Finance, then Reconcile, then "Import bank CSV", choose the file, pick the account under "Bank account for this statement", and "Import into this account". Over MCP the agent calls list_bank_accounts to find the account id and then import_bank_csv with the file contents and bank_account_id.

Before a single row is written the import checks that the file's implied opening balance chains onto the account: its current closing balance, its declared opening balance on a first import, or a balance it has already recorded if the window overlaps. Three outcomes:

  • It chains. Every line lands. The response says how many were inserted and how many were already present. Re-importing an overlapping window adds zero duplicates.
  • It does not chain. The whole import is refused with wrong_account_or_gap, naming the balance the account expected and the balance the file starts from, and zero rows are written. Either this is the set-aside's statement in the everyday account, or a window is missing. Export the right days and import again.
  • The gap is real and unrecoverable. Import anyway with override_chain_gap: true and an override_reason. On screen that is the "Reason for importing over the statement gap" box and "Import anyway with this reason". An empty reason is refused. The override is audit-logged and the completeness read still reports the break.

Step 4: check the feed's health

"Where has each account's feed got to?"

list_bank_accounts returns, per account, the chained current balance, the coverage span, the line count, whether the chain is intact, and a feed_health verdict of fresh, stale or never imported measured in your timezone against finance.bankfeed.stale_after_days. A stale account is named in the attention digest so it is not forgotten.

Import weekly

The internet-banking export is a rolling window of recent transactions. Skip too long and the oldest lines roll off before you export them, and that becomes a gap the close will refuse over. Weekly is the cadence the platform is designed around; the bookkeeper desk's worklist starts every session with the feed's freshness.

Starting mid-history: the cutover

If the account has years of history before Biloh, set finance.bankfeed.cutover_date to the day you started invoicing here and run ignore_pre_cutover_transactions once. Every unmatched line dated before the cutover is marked as pre-Biloh history in one call, so the reconcile worklist opens on deposits Biloh can actually settle. The sweep will not touch lines on or after finance.close.pre_cutover_boundary. See triage invoices after a billing cutover for the invoice side.

Next

Last updated 2026-09-18