Banking execution
Read the exact action guide for prerequisites, identifier discovery, supported input, effects, captured successful and refused responses, verification and recovery. Synthetic fixture results do not authorize a live mutation or establish a provider outcome.
- List bank providers: List the banks Books can connect to and what credential each needs (Mercury: a read-only API token).
- List bank connections: List the workspace's bank connections and the bank accounts they report. Credentials are never returned; they live in Nexus.
- Connect a bank: Connect a bank with a read-only API token. The token is verified against the bank first, stored encrypted in Nexus, then the bank's accounts are recorded. Refused with bank_credential_invalid if the bank rejects it.
- Get bank connection: Read one bank connection with its accounts and sync state.
- Disconnect a bank: Disconnect a bank: the credential is revoked in Nexus first; accounts are marked disconnected and imported lines are kept as statement history.
- Sync a bank connection: Pull posted transactions for every account on the connection. The first sync takes the whole history the bank still holds; later syncs are incremental. Pass
fromto re-read every account from that date. Idempotent on the bank's transaction id. - List bank accounts: List the bank accounts reported by connected banks, with cached balances and the ledger account each maps to. linkedOnly returns just the accounts pointed at a ledger account.
- Add a manual bank account: Add a bank, card or cash account that has no feed. Its statement lines arrive through bank.statements.import. Optionally link it to an asset or liability ledger account.
- Import a bank statement: Import a statement export (CSV with columns detected from the header, OFX/QFX, QIF, CAMT.053 ISO 20022 XML or SWIFT MT940) into a bank account. Previews by default (dryRun true): each line is create, skip_duplicate (already held: same date, amount and description) or error. Pass dryRun false to store the new lines; dateOrder settles day-first vs month-first dates.
- Remove duplicate bank accounts: Fold each imported duplicate bank account into the account carrying the live bank feed: the imported copy and its statement lines are removed, its ledger link moves across, and its provider id is recorded against the survivor so a re-import resolves there. Re-run the import afterwards to refill the periods the live feed does not cover. Requires literal REPAIR confirmation.
- Update bank account mapping: Set the nickname and the ledger account (asset or liability) a bank account maps to. Everything else about the account is the bank's.
- List bank lines: List statement lines, filtered by account, match status or date, searched across description, counterparty, memo and the bank's transaction id, and sorted by posted date, amount, description or match status. Newest first unless you say otherwise; linkedOnly restricts them to accounts linked to a ledger account.
- Suggest how to reconcile a bank line: For one unmatched statement line: open invoices (money in) or bills (money out) it could be settling, scored by amount, a number or contact named in the description and date; the opposite line in another of our accounts that makes it a transfer; and the accounts lines like it were coded to before, with how often. Best first.
- Code a bank line to an account: Post the line as a journal between the bank's ledger account and the chosen account (optionally with a contact, tax rate and memo) and mark the line matched. Keyed by the line, so it never posts twice. Refused with bank_account_unlinked when the bank account has no ledger account, and coding_to_bank_account when the chosen account is the bank itself.
- Reconcile a provider payout: Read the exact Stripe balance transactions included in a payout, automatically clear posted Books payments by their balance-transaction reference, require an explicit ledger account for every remaining non-zero item, then post one balanced bank journal. Nothing posts while any amount is missing, guessed or does not exactly match the bank line.
- Match a bank line to a document: Record the line as a payment against the invoice (money in) or bill (money out) it settled, dated the line's date and posted to the ledger against the bank account, and mark the line matched. amountMinor defaults to the smaller of the line and what is outstanding. Refused when the direction or currency does not fit.
- Reconcile a transfer between two bank accounts: Pair this line with its opposite in another of our bank accounts: one journal between the two ledger accounts, both lines matched. Refused unless the amounts are equal and opposite in the same currency and both accounts are linked to the ledger.
- Exclude a bank line: Leave a statement line out of the books (a duplicate, the bank's own noise). Nothing posts; the line is marked excluded and can be unmatched later.
- Unmatch a bank line: Put a line back to unmatched: a coding or transfer journal is reversed (both lines of a transfer return), an exclusion is lifted. A line matched to a document payment is refused, since the payment is the record.
- Get the bank reconciliation report: At a date (default today): the statement balance (every line the bank sent up to the date, duplicates left out), the bank's own reported balance when a feed supplies one, the balance of the linked ledger account, the unmatched lines with their total, the excluded and matched totals, and the difference (statement minus ledger, unmatched and excluded) that names what is in the ledger but not on the statement. reconciled is true when nothing is unmatched and the difference is zero. Includes the latest sign-off.
- List bank reconciliation sign-offs: Every sign-off recorded for the bank account, newest first, with the figures as they stood when it was signed.
- Sign off a bank reconciliation: Record that the statement and the ledger agree at a date, with the figures as they stand and who signed. Refused with unreconciled_lines while any line up to the date is unmatched, bank_account_unlinked while the account has no ledger account, and reconciliation_difference when the two sides disagree unless acceptDifference is true with a note explaining it.
- List bank rules: The rules that code statement lines automatically, lowest priority number first; archived ones only with includeArchived true. Each says what it looks at (description, counterparty or either), how it matches (contains, equals, starts_with), the direction and amount range it applies to, the bank account it is limited to, where it codes (account, contact, tax rate, memo) and how many times it has run.
- Create a bank rule: Add a rule: when an unmatched statement line matches matchText in matchField (case-insensitive), moves in the given direction and within the amount range, code it to accountId with the optional contact, tax rate and memo. Lower priority numbers run first. The account must be active; the rule is refused with coding_to_bank_account when applied to lines of the bank account it names.
- Update a bank rule: Change any field of a rule. Lines already coded by it are unchanged.
- Archive a bank rule: Stop the rule running. Lines it coded keep its id as their provenance.
- Restore a bank rule: Put an archived rule back into the run order.
- Apply bank rules: Run the active rules over unmatched lines in linked bank accounts (optionally one bank account or a list of lines). The first rule that fits a line codes it: one journal between the bank's ledger account and the rule's account, the line marked matched with coded_by_rule_id set, the rule's times_applied advanced. dryRun true lists what would be coded without posting. Lines no rule fits are counted in unmatched; a line a rule fits but cannot code (locked period, archived account) is listed in skipped with the refusal code.
Evidence
Actual Books route handlers and the exported Worker were exercised against five local SQLite D1 concern databases with all committed migrations, the real posting Durable Object and local R2. Route captures use synthetic verified Auth; Worker captures use synthetic Auth transports. Nexus, Brand, Notify, Pay, Mercury and Xero responses are explicitly simulated at the provider transport boundary. Captures prove local request/response behavior and canonical SDK projection, not live bank access, payment movement, email delivery, provider eligibility, tax compliance, encrypted custody, scheduled execution, deployment or production completion. Fixture identities, credentials, addresses and records authorize no live operation.