Transactions

Transactions are the core of SpeyBooks' double-entry bookkeeping system. Every transaction consists of two or more lines that must balance: the sum of all line amounts must equal zero. Positive amounts represent debits, negative amounts represent credits.

Balance Constraint

The balance equation is absolute and enforced at validation:

∑ line amounts = 0

If the submitted lines do not sum to zero, the API rejects the request before any database writes occur. There are no exceptions, tolerances, or auto-balancing. The API consumer is responsible for sending a mathematically complete journal.

VAT on Transaction Lines

Each line optionally accepts vatRate and vatTreatment fields. These are tax reporting metadata: they tell the API how to calculate the VAT component of that line's amount for HMRC reporting purposes. They do not create additional balancing lines or modify the journal balance.

When vatRate and vatTreatment are provided on a line, the API calculates and stores vatAmount as follows:

  • inclusive: the line amount already contains VAT. vatAmount = |amount| - (|amount| / (1 + rate))
  • exclusive: the line amount is net of VAT. vatAmount = |amount| * rate
  • none or omitted: no VAT calculation is performed.

For example, on a £100 net sale with 20% VAT, the API consumer must send three explicit lines:

  1. Trade Debtors (acc_1100): +12000 (debit)
  2. Sales - Products (acc_4000): -10000, vatRate: 20, vatTreatment: "exclusive"
  3. VAT on Sales (acc_2200): -2000 (credit)

The API will compute vatAmount: 2000 on the Sales line for tax reporting, but it will not inject the output VAT line. That is the consumer's responsibility.

Transaction Statuses

  • draft: excluded from reports and balances. Manual drafts can be deleted; bank-import drafts can be categorised.
  • posted: immutable, included in reports and balances. Posted transactions can be reconciled to confirm they match bank statements.

Source Types

Each transaction records its origin:

  • manual: user-created entries
  • invoice: journals generated by invoice finalisation
  • bank_import: entries created by the bank import pipeline

System-generated transactions cannot be deleted directly. Delete the source document instead.

Control accounts move only through their authorised source documents. A journal posted to one from a source it does not permit is rejected with a message naming the account and its permitted sources. The strict controls are Trade Debtors, Trade Creditors, the three VAT accounts (VAT on sales, VAT on purchases, and the VAT liability), and Bad Debts.

Bank Import Categorisation

Bank import transactions initially land with one line against the Suspense account (code 9999). The categorise endpoint moves this line to the correct account, and the suggest-category endpoint uses the categorisation rules to propose a match.

Account Ledger

The account ledger endpoint provides a traditional ledger view for any account, with opening balance, running balance, and date-range filtering. All monetary values throughout the API are in minor units (pence).

→ The Transactions object

Endpoints