Skip to main content

Books: VAT and reports

30 operations in the Tolvi API, version 1. Paths are relative to https://api.tolvi.co.uk. Every amount is integer pence.

Get the profit and loss

GET/api/v1/books/reports/profit-and-loss

Scopes
books:read

For any period, with a comparison period (by default the same dates a year earlier). Derived from posted entries. Every figure has a drillKey for the drill-down. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/profit-and-loss
NameInTypeDescription
compareToquerystring (date)

An explicit comparison period (with compareFrom).

compareFromquerystring (date)

An explicit comparison period (with compareTo).

comparequerystring

previous_year (default), previous_period or none. Ignored when explicit comparison dates are given.

One of: previous_year, previous_period, none

toquerystring (date)

Defaults to today.

fromquerystring (date)

Defaults to the start of the financial year containing to.

Responses

200 OK, application/json

Body: object (BooksProfitAndLoss).

Profit and loss for a period, with an optional comparison period (FRS 102 Section 1A layout, grouped by each account’s lead schedule line), and the same figures grouped for owners.

200 OK response for GET /api/v1/books/reports/profit-and-loss
FieldTypeDescription
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

compareFromrequiredstring (date)nullable

example "2026-03-31"

compareTorequiredstring (date)nullable

example "2026-03-31"

throughSeqrequiredinteger

The ledger point the report reflects.

sectionsrequiredarray of BooksReportSection
sections[].​idrequiredstring

Profit and loss: turnover, cost_of_sales, overheads, other_income, interest, tax. Balance sheet: fixed_assets, current_assets, current_liabilities, long_term_liabilities, unsorted, capital.

sections[].​labelrequiredstring
sections[].​linesrequiredarray of BooksReportLine
sections[].​lines[].​accountIdrequiredstring (uuid)nullable
sections[].​lines[].​coderequiredstring
sections[].​lines[].​namerequiredstring
sections[].​lines[].​ownerNamerequiredstring
sections[].​lines[].​ownerCategoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

sections[].​lines[].​currentPencerequiredinteger

Integer pence (GBP).

sections[].​lines[].​comparePencerequiredintegernullable

Integer pence (GBP).

Null when no comparison was asked for.

sections[].​lines[].​drillKeyrequiredstring

Pass to the drill-down to list the entries behind this figure.

sections[].​currentPencerequiredinteger

Integer pence (GBP).

sections[].​comparePencerequiredintegernullable

Integer pence (GBP).

sections[].​drillKeyrequiredstring
totalsrequiredarray of BooksReportTotal
totals[].​idrequiredstring

Profit and loss: gross_profit, operating_profit, profit_before_tax, net_profit. Balance sheet: net_current_assets, total_assets_less_current_liabilities, net_assets, capital_and_reserves.

totals[].​labelrequiredstring
totals[].​currentPencerequiredinteger

Integer pence (GBP).

totals[].​comparePencerequiredintegernullable

Integer pence (GBP).

totals[].​drillKeyrequiredstring
ownerViewrequiredobject (BooksProfitAndLossOwnerView)
ownerView.​moneyInrequiredarray of BooksReportOwnerGroup
ownerView.​moneyIn[].​categoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

ownerView.​moneyIn[].​labelrequiredstring
ownerView.​moneyIn[].​linesrequiredarray of BooksReportLine
ownerView.​moneyIn[].​lines[].​accountIdrequiredstring (uuid)nullable
ownerView.​moneyIn[].​lines[].​coderequiredstring
ownerView.​moneyIn[].​lines[].​namerequiredstring
ownerView.​moneyIn[].​lines[].​ownerNamerequiredstring
ownerView.​moneyIn[].​lines[].​ownerCategoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

ownerView.​moneyIn[].​lines[].​currentPencerequiredinteger

Integer pence (GBP).

ownerView.​moneyIn[].​lines[].​comparePencerequiredintegernullable

Integer pence (GBP).

Null when no comparison was asked for.

ownerView.​moneyIn[].​lines[].​drillKeyrequiredstring

Pass to the drill-down to list the entries behind this figure.

ownerView.​moneyIn[].​currentPencerequiredinteger

Integer pence (GBP).

ownerView.​moneyIn[].​comparePencerequiredintegernullable

Integer pence (GBP).

ownerView.​moneyIn[].​drillKeyrequiredstring
ownerView.​costsrequiredarray of BooksReportOwnerGroup
ownerView.​costs[].​categoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

ownerView.​costs[].​labelrequiredstring
ownerView.​costs[].​linesrequiredarray of BooksReportLine
ownerView.​costs[].​lines[].​accountIdrequiredstring (uuid)nullable
ownerView.​costs[].​lines[].​coderequiredstring
ownerView.​costs[].​lines[].​namerequiredstring
ownerView.​costs[].​lines[].​ownerNamerequiredstring
ownerView.​costs[].​lines[].​ownerCategoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

ownerView.​costs[].​lines[].​currentPencerequiredinteger

Integer pence (GBP).

ownerView.​costs[].​lines[].​comparePencerequiredintegernullable

Integer pence (GBP).

Null when no comparison was asked for.

ownerView.​costs[].​lines[].​drillKeyrequiredstring

Pass to the drill-down to list the entries behind this figure.

ownerView.​costs[].​currentPencerequiredinteger

Integer pence (GBP).

ownerView.​costs[].​comparePencerequiredintegernullable

Integer pence (GBP).

ownerView.​costs[].​drillKeyrequiredstring
ownerView.​moneyInPencerequiredinteger

Integer pence (GBP).

ownerView.​moneyInComparePencerequiredintegernullable

Integer pence (GBP).

ownerView.​costsPencerequiredinteger

Integer pence (GBP).

ownerView.​costsComparePencerequiredintegernullable

Integer pence (GBP).

netProfitPencerequiredinteger

Integer pence (GBP).

netProfitComparePencerequiredintegernullable

Integer pence (GBP).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the balance sheet

GET/api/v1/books/reports/balance-sheet

Scopes
books:read

What the business owns and owes at a date, with a comparison date. Profit for the year so far is a line in capital and reserves. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/balance-sheet
NameInTypeDescription
compareAsAtquerystring (date)

An explicit comparison date.

comparequerystring

previous_year (default: a year earlier), previous_period (the end of the previous financial year) or none.

One of: previous_year, previous_period, none

asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksBalanceSheet).

What the business owns and owes at a date, with an optional comparison date. Profit for the year so far is a line in capital and reserves.

200 OK response for GET /api/v1/books/reports/balance-sheet
FieldTypeDescription
asAtrequiredstring (date)

example "2026-03-31"

yearStartrequiredstring (date)

example "2026-03-31"

compareAsAtrequiredstring (date)nullable

example "2026-03-31"

compareYearStartrequiredstring (date)nullable

example "2026-03-31"

throughSeqrequiredinteger
sectionsrequiredarray of BooksReportSection
sections[].​idrequiredstring

Profit and loss: turnover, cost_of_sales, overheads, other_income, interest, tax. Balance sheet: fixed_assets, current_assets, current_liabilities, long_term_liabilities, unsorted, capital.

sections[].​labelrequiredstring
sections[].​linesrequiredarray of BooksReportLine
sections[].​lines[].​accountIdrequiredstring (uuid)nullable
sections[].​lines[].​coderequiredstring
sections[].​lines[].​namerequiredstring
sections[].​lines[].​ownerNamerequiredstring
sections[].​lines[].​ownerCategoryrequiredstring (BooksOwnerCategory)

One of: sales, other_income, direct_costs, staff, premises, travel, office, marketing, professional, finance_costs, other_costs, write_offs, tax, bank_and_cash, owed_to_you, you_owe, equipment, stock, owner, behind_the_scenes

sections[].​lines[].​currentPencerequiredinteger

Integer pence (GBP).

sections[].​lines[].​comparePencerequiredintegernullable

Integer pence (GBP).

Null when no comparison was asked for.

sections[].​lines[].​drillKeyrequiredstring

Pass to the drill-down to list the entries behind this figure.

sections[].​currentPencerequiredinteger

Integer pence (GBP).

sections[].​comparePencerequiredintegernullable

Integer pence (GBP).

sections[].​drillKeyrequiredstring
totalsrequiredarray of BooksReportTotal
totals[].​idrequiredstring

Profit and loss: gross_profit, operating_profit, profit_before_tax, net_profit. Balance sheet: net_current_assets, total_assets_less_current_liabilities, net_assets, capital_and_reserves.

totals[].​labelrequiredstring
totals[].​currentPencerequiredinteger

Integer pence (GBP).

totals[].​comparePencerequiredintegernullable

Integer pence (GBP).

totals[].​drillKeyrequiredstring
balancedrequiredboolean

Net assets equal capital and reserves.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get aged debtors (who owes the business)

GET/api/v1/books/reports/aged-debtors

Scopes
books:read

By customer and by how overdue. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/aged-debtors
NameInTypeDescription
asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksAgedReport).

Who owes the business (debtors) or whom it owes (creditors), by how overdue. Worked from unpaid invoices and bills where they exist (basis: documents), otherwise from the trade debtors or creditors control account by contact, payments set against the oldest amounts first and amounts assumed due termsDays after their date (basis: ledger). The control account balance is shown beside the total.

200 OK response for GET /api/v1/books/reports/aged-debtors
FieldTypeDescription
siderequiredstring (BooksAgedSide)

One of: debtors, creditors

asAtrequiredstring (date)

example "2026-03-31"

basisrequiredstring (BooksAgedBasis)

One of: documents, ledger

termsDaysrequiredintegernullable
contactsrequiredarray of BooksAgedContact
contacts[].​contactIdrequiredstringnullable
contacts[].​namerequiredstring
contacts[].​bucketsrequiredobject (BooksAgedBuckets)

Pence by how overdue: not yet due, 1–30, 31–60, 61–90 and over 90 days.

contacts[].​buckets.​currentrequiredinteger
contacts[].​buckets.​days_1_30requiredinteger
contacts[].​buckets.​days_31_60requiredinteger
contacts[].​buckets.​days_61_90requiredinteger
contacts[].​buckets.​over_90requiredinteger
contacts[].​totalPencerequiredinteger

Integer pence (GBP).

contacts[].​overduePencerequiredinteger

Integer pence (GBP).

contacts[].​itemsrequiredarray of BooksAgedItem
contacts[].​items[].​referencerequiredstring
contacts[].​items[].​daterequiredstring (date)

example "2026-03-31"

contacts[].​items[].​dueDaterequiredstring (date)nullable

example "2026-03-31"

contacts[].​items[].​daysOverduerequiredinteger
contacts[].​items[].​bucketrequiredstring (BooksAgedBucket)

One of: current, days_1_30, days_31_60, days_61_90, over_90

contacts[].​items[].​outstandingPencerequiredinteger

Integer pence (GBP).

Still owed; negative for money paid on account.

contacts[].​items[].​documentIdrequiredstringnullable

The invoice or bill, when worked from documents.

contacts[].​items[].​entryIdrequiredstring (uuid)nullable

The ledger entry, when worked from the ledger.

totalsrequiredobject (BooksAgedBuckets)

Pence by how overdue: not yet due, 1–30, 31–60, 61–90 and over 90 days.

totals.​currentrequiredinteger
totals.​days_1_30requiredinteger
totals.​days_31_60requiredinteger
totals.​days_61_90requiredinteger
totals.​over_90requiredinteger
totalPencerequiredinteger

Integer pence (GBP).

overduePencerequiredinteger

Integer pence (GBP).

controlBalancePencerequiredinteger

Integer pence (GBP).

The control account at asAt; owed is positive.

differencePencerequiredinteger

Integer pence (GBP).

Control balance less the aged total (nil on the ledger basis).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get aged creditors (whom the business owes)

GET/api/v1/books/reports/aged-creditors

Scopes
books:read

By supplier and by how overdue. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/aged-creditors
NameInTypeDescription
asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksAgedReport).

Who owes the business (debtors) or whom it owes (creditors), by how overdue. Worked from unpaid invoices and bills where they exist (basis: documents), otherwise from the trade debtors or creditors control account by contact, payments set against the oldest amounts first and amounts assumed due termsDays after their date (basis: ledger). The control account balance is shown beside the total.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the VAT owed per the books

GET/api/v1/books/reports/vat

Scopes
books:read

The VAT control account over a period, explained. The VAT return itself is worked separately from each transaction’s VAT. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/vat
NameInTypeDescription
toquerystring (date)

Defaults to today.

fromquerystring (date)

Defaults to the start of the financial year containing to.

Responses

200 OK, application/json

Body: object (BooksVatOwed).

The VAT control account over a period: owed to HMRC at the start, VAT on sales, VAT on purchases, payments to or from HMRC, other adjustments, and owed at the end. Owed to HMRC is positive. This is what the books say; the VAT return is worked from each transaction’s VAT by tax point.

200 OK response for GET /api/v1/books/reports/vat
FieldTypeDescription
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

accountIdrequiredstring (uuid)
openingPencerequiredinteger

Integer pence (GBP).

salesPencerequiredinteger

Integer pence (GBP).

purchasesPencerequiredinteger

Integer pence (GBP).

Negative: VAT you can reclaim reduces what is owed.

paymentsPencerequiredinteger

Integer pence (GBP).

Negative for a payment to HMRC.

otherPencerequiredinteger

Integer pence (GBP).

closingPencerequiredinteger

Integer pence (GBP).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get cash flow by month

GET/api/v1/books/reports/cash-flow

Scopes
books:read

Money in and out of the bank, cash and card accounts, month by month, with the balance at each month end. Moving money between the business’s own accounts is neither. Up to five years. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/cash-flow
NameInTypeDescription
toquerystring (date)

Defaults to today.

fromquerystring (date)

Defaults to the start of the financial year containing to.

Responses

200 OK, application/json

Body: object (BooksCashFlow).

Money in and out of the bank, cash and card accounts, by month. Moving money between the business’s own accounts is neither.

200 OK response for GET /api/v1/books/reports/cash-flow
FieldTypeDescription
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

openingPencerequiredinteger

Integer pence (GBP).

monthsrequiredarray of BooksCashFlowMonth
months[].​monthrequiredstring

example "2026-10"

months[].​fromrequiredstring (date)

example "2026-03-31"

months[].​torequiredstring (date)

example "2026-03-31"

months[].​inPencerequiredinteger

Integer pence (GBP).

months[].​outPencerequiredinteger

Integer pence (GBP).

months[].​netPencerequiredinteger

Integer pence (GBP).

months[].​closingPencerequiredinteger

Integer pence (GBP).

Across bank, cash and card accounts at the end of the month.

inPencerequiredinteger

Integer pence (GBP).

outPencerequiredinteger

Integer pence (GBP).

netPencerequiredinteger

Integer pence (GBP).

closingPencerequiredinteger

Integer pence (GBP).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get SA103 totals (sole traders)

GET/api/v1/books/reports/sa103

Scopes
books:read

The income and expense boxes of HMRC’s SA103F (boxes 15 to 31 and 32 to 46, net profit or loss in 47 or 48), added up from each account’s SA103 line on the chart. An aid for the return, never a filing. The balance sheet boxes aren’t included. 422 unless the business is a sole trader. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/sa103
NameInTypeDescription
taxYearqueryinteger

By the year it starts: 2026 is 2026/27. Defaults to the current tax year.

2024 to 2100

Responses

200 OK, application/json

Body: object (BooksSa103Totals).

The income and expense boxes of HMRC’s SA103F for a sole trader, added up from the chart. An aid for the return, never a filing.

200 OK response for GET /api/v1/books/reports/sa103
FieldTypeDescription
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

taxYearrequiredinteger

The tax year, by the year it starts: 2026 is 2026/27.

taxYearLabelrequiredstring
sourcerequiredstring

The HMRC form the box numbers come from.

incomerequiredarray of BooksSa103IncomeBox
income[].​boxrequiredinteger
income[].​labelrequiredstring
income[].​amountPencerequiredinteger

Integer pence (GBP).

income[].​accountsrequiredarray of BooksSa103Account
income[].​accounts[].​coderequiredstring
income[].​accounts[].​namerequiredstring
income[].​accounts[].​amountPencerequiredinteger

Integer pence (GBP).

income[].​accounts[].​drillKeyrequiredstring

Pass to the drill-down (report profit-and-loss) to list the entries.

expensesrequiredarray of BooksSa103ExpenseBox
expenses[].​boxrequiredinteger
expenses[].​labelrequiredstring
expenses[].​amountPencerequiredinteger

Integer pence (GBP).

expenses[].​accountsrequiredarray of BooksSa103Account
expenses[].​accounts[].​coderequiredstring
expenses[].​accounts[].​namerequiredstring
expenses[].​accounts[].​amountPencerequiredinteger

Integer pence (GBP).

expenses[].​accounts[].​drillKeyrequiredstring

Pass to the drill-down (report profit-and-loss) to list the entries.

expenses[].​disallowableBoxrequiredinteger
expenses[].​disallowablePencerequiredinteger

Integer pence (GBP).

The part of this box tax doesn’t allow.

totalExpensesBoxrequiredinteger
totalExpensesPencerequiredinteger

Integer pence (GBP).

totalDisallowableBoxrequiredinteger
totalDisallowablePencerequiredinteger

Integer pence (GBP).

netProfitBoxrequiredinteger
netLossBoxrequiredinteger
netPencerequiredinteger

Integer pence (GBP).

Income less expenses; negative is a loss.

netPoundsrequiredinteger

The net figure in whole pounds, rounded down, without a sign.

notTradingrequiredarray of BooksSa103Account

Income left out: it goes on SA100.

notTrading[].​coderequiredstring
notTrading[].​namerequiredstring
notTrading[].​amountPencerequiredinteger

Integer pence (GBP).

notTrading[].​drillKeyrequiredstring

Pass to the drill-down (report profit-and-loss) to list the entries.

unmappedrequiredarray of BooksSa103Account

Income or cost accounts with no SA103 line.

unmapped[].​coderequiredstring
unmapped[].​namerequiredstring
unmapped[].​amountPencerequiredinteger

Integer pence (GBP).

unmapped[].​drillKeyrequiredstring

Pass to the drill-down (report profit-and-loss) to list the entries.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

List the entries behind a report figure

GET/api/v1/books/reports/drill-down

Scopes
books:read

The postings that make up one figure, adding up to it. 422 for a figure that isn’t in the report. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/drill-down
NameInTypeDescription
asAtquerystring (date)

Balance sheet: the date (defaults to today); lines run from the year start.

toquerystring (date)

Profit and loss: the period end (defaults to today).

fromquerystring (date)

Profit and loss: the period start (defaults to the year start).

keyrequiredquerystring

A figure’s drillKey, e.g. account:6100, section:overheads, category:premises, total:net_profit.

up to 80 characters

reportrequiredquerystring

One of: profit-and-loss, balance-sheet

Responses

200 OK, application/json

Body: object (BooksDrillDown).

The postings behind one report figure. Lines are in the figure’s sense (sense), so they add up to it; a balance sheet figure starts from the balance brought forward at the start of the year (including earlier years’ profit in reserves).

200 OK response for GET /api/v1/books/reports/drill-down
FieldTypeDescription
reportrequiredstring (BooksDrillReport)

One of: profit-and-loss, balance-sheet

keyrequiredstring
labelrequiredstring
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

senserequiredstring (BooksNormalBalance)

One of: debit, credit

accountsrequiredarray of BooksDrillAccount
accounts[].​accountIdrequiredstring (uuid)
accounts[].​coderequiredstring
accounts[].​namerequiredstring
accounts[].​ownerNamerequiredstring
openingPencerequiredinteger

Integer pence (GBP).

linesrequiredarray of BooksDrillLine
lines[].​entryIdrequiredstring (uuid)
lines[].​seqrequiredinteger
lines[].​lineIndexrequiredinteger
lines[].​daterequiredstring (date)

example "2026-03-31"

lines[].​kindrequiredstring
lines[].​descriptionrequiredstring
lines[].​accountIdrequiredstring (uuid)
lines[].​accountCoderequiredstring
lines[].​amountPencerequiredinteger

Integer pence (GBP).

In the figure’s sense, so the lines add up to it.

lines[].​runningPencerequiredinteger

Integer pence (GBP).

closingPencerequiredinteger

Integer pence (GBP).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Estimate the tax to set aside

GET/api/v1/books/reports/tax-estimate

Scopes
books:read

Income tax and Class 4 National Insurance (sole traders) or corporation tax (companies) on the profit so far, annualised. Uses the extra information the owner saved for the tax year (other income, PAYE and pension contributions; a director’s salary and dividends), if any, and says which figures it used. Always an estimate, with its working and assumptions; never a figure for filing. 422 for a partnership or LLP, whose partners are taxed on their shares. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/tax-estimate
NameInTypeDescription
otherIncomePencequeryinteger

Sole traders: other non-savings income for the year (a salary, say), in pence, assumed already taxed. When given, it is used instead of the extra information saved for the tax year (PUT /books/tax-details/{taxYear}).

at least 0

asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksTaxEstimate).

An estimate (never a calculation for filing) of the tax to set aside: income tax and Class 4 National Insurance for a sole trader, corporation tax for a company, on the profit so far annualised over the year. Shows its working and what it assumed.

200 OK response for GET /api/v1/books/reports/tax-estimate
FieldTypeDescription
estimaterequiredboolean

One of: true

kindrequiredstring (BooksTaxEstimateKind)

One of: sole_trader, company

periodFromrequiredstring (date)

example "2026-03-31"

periodTorequiredstring (date)

example "2026-03-31"

asAtrequiredstring (date)

example "2026-03-31"

daysElapsedrequiredinteger
daysInPeriodrequiredinteger
profitBeforeTaxPencerequiredinteger

Integer pence (GBP).

addBacksrequiredarray of BooksTaxWorkingLine

Costs tax doesn’t allow, added back.

addBacks[].​accountIdrequiredstring (uuid)nullable
addBacks[].​coderequiredstring
addBacks[].​namerequiredstring
addBacks[].​amountPencerequiredinteger

Integer pence (GBP).

notTradingrequiredarray of BooksTaxWorkingLine

Income that isn’t trading income, taken out (sole traders).

notTrading[].​accountIdrequiredstring (uuid)nullable
notTrading[].​coderequiredstring
notTrading[].​namerequiredstring
notTrading[].​amountPencerequiredinteger

Integer pence (GBP).

profitToDatePencerequiredinteger

Integer pence (GBP).

Taxable profit so far, whole pounds (floored).

annualisedProfitPencerequiredinteger

Integer pence (GBP).

For the whole year at the same rate, whole pounds (floored).

taxYearLabelrequiredstringnullable

example "2026/27"

financialYearsrequiredarray of integer

Companies: the financial years whose rates were used.

otherIncomePencerequiredinteger

Integer pence (GBP).

linesrequiredarray of BooksTaxEstimateLine
lines[].​keyrequiredstring (BooksTaxEstimateLineKey)

other_income_tax: a sole trader’s tax on their other income less what PAYE took (only when they entered other income).

One of: income_tax, other_income_tax, class4_nic, corporation_tax

lines[].​labelrequiredstring
lines[].​annualPencerequiredinteger

Integer pence (GBP).

For the whole year, if profit carries on at the same rate.

lines[].​toDatePencerequiredinteger

Integer pence (GBP).

The share to have set aside by now.

annualTaxPencerequiredinteger

Integer pence (GBP).

setAsideToDatePencerequiredinteger

Integer pence (GBP).

effectiveRateBpsrequiredinteger

Annual tax as a share of annualised profit, basis points.

assumptionsrequiredarray of string
extraInfoTaxYearrequiredinteger

The tax year the owner’s extra information is for (starting year): the one containing the year end. Use it with /books/tax-details/{taxYear}.

extraInfoTaxYearLabelrequiredstring

example "2026/27"

basedOnrequiredobject (BooksTaxEstimateBasedOn)nullable

The owner’s extra information used, or null when none was entered.

basedOn.​otherIncomerequiredinteger

Sole traders: employment, pensions, property profits and savings interest added up.

basedOn.​taxPaidThroughPayerequiredinteger

Sole traders: tax already taken under PAYE.

basedOn.​pensionContributionsrequiredinteger

Sole traders: personal pension contributions paid in.

basedOn.​directorSalaryrequiredinteger

Companies: the director’s planned salary.

basedOn.​dividendsrequiredinteger

Companies: the director’s planned dividends.

ownerDividendTaxrequiredobject (BooksOwnerDividendTax)nullable

Companies with planned dividends: the director’s own tax on them.

ownerDividendTax.​taxYearrequiredinteger
ownerDividendTax.​taxYearLabelrequiredstring

example "2026/27"

ownerDividendTax.​directorSalaryrequiredinteger
ownerDividendTax.​dividendsrequiredinteger
ownerDividendTax.​dividendTaxrequiredinteger

Income tax on the dividends, after the salary uses the personal allowance and bands first.

ownerDividendTax.​assumptionsrequiredarray of string

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Download a report as CSV or PDF

GET/api/v1/books/reports/{report}/export

Scopes
books:read

The same figures as the report (same query parameters), as a CSV (RFC 4180; amounts in pounds with two decimals, minus for negatives) or an A4 PDF (credits in brackets). Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/reports/{report}/export
NameInTypeDescription
reportrequiredpathstring

One of: profit-and-loss, balance-sheet, aged-debtors, aged-creditors, vat, drill-down, cash-flow, sa103

drillReportquerystring

drill-down only: profit-and-loss or balance-sheet.

One of: profit-and-loss, balance-sheet

keyquerystring

drill-down only: the figure’s drillKey.

up to 80 characters

taxYearqueryinteger

sa103 only: the year the tax year starts.

compareAsAtquerystring (date)
compareToquerystring (date)
compareFromquerystring (date)
comparequerystring

previous_year (default), previous_period or none. Ignored when explicit comparison dates are given.

One of: previous_year, previous_period, none

asAtquerystring (date)
toquerystring (date)
fromquerystring (date)
formatrequiredquerystring

One of: csv, pdf

Responses

200 OK, text/csv

The file, as an attachment.

Body: string (binary).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

Get the home screen figures

GET/api/v1/books/home

Scopes
books:read

How the business is doing (money in and out this month, profit so far this year, cash across accounts, who owes it and whom it owes, VAT owed), the tax to set aside (an estimate) and what needs the owner. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/home
NameInTypeDescription
asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksHome).

The owner’s home screen: money in and out this month, profit so far this year, cash across accounts, who owes the business and whom it owes, VAT owed, the tax to set aside (an estimate) and what needs the owner.

200 OK response for GET /api/v1/books/home
FieldTypeDescription
asAtrequiredstring (date)

example "2026-03-31"

businessNamerequiredstring
yearStartrequiredstring (date)

example "2026-03-31"

yearEndrequiredstring (date)

example "2026-03-31"

thisMonthrequiredobject (BooksMoneyInOut)

Money in and out of bank, cash and card accounts; moves between the business’s own accounts are neither.

thisMonth.​fromrequiredstring (date)

example "2026-03-31"

thisMonth.​torequiredstring (date)

example "2026-03-31"

thisMonth.​inPencerequiredinteger

Integer pence (GBP).

thisMonth.​outPencerequiredinteger

Integer pence (GBP).

lastMonthrequiredobject (BooksMoneyInOut)

Money in and out of bank, cash and card accounts; moves between the business’s own accounts are neither.

lastMonth.​fromrequiredstring (date)

example "2026-03-31"

lastMonth.​torequiredstring (date)

example "2026-03-31"

lastMonth.​inPencerequiredinteger

Integer pence (GBP).

lastMonth.​outPencerequiredinteger

Integer pence (GBP).

profitrequiredobject (BooksHomeProfit)

Profit for the year so far, with the same stretch of last year when the books go back that far.

profit.​fromrequiredstring (date)

example "2026-03-31"

profit.​torequiredstring (date)

example "2026-03-31"

profit.​profitPencerequiredinteger

Integer pence (GBP).

profit.​moneyInPencerequiredinteger

Integer pence (GBP).

profit.​costsPencerequiredinteger

Integer pence (GBP).

profit.​compareFromrequiredstring (date)nullable

example "2026-03-31"

profit.​compareTorequiredstring (date)nullable

example "2026-03-31"

profit.​comparePencerequiredintegernullable

Integer pence (GBP).

cashrequiredobject (BooksHomeCash)
cash.​totalPencerequiredinteger

Integer pence (GBP).

cash.​accountsrequiredarray of BooksCashAccount
cash.​accounts[].​accountIdrequiredstring (uuid)
cash.​accounts[].​coderequiredstring
cash.​accounts[].​namerequiredstring
cash.​accounts[].​ownerNamerequiredstring
cash.​accounts[].​kindrequiredstring (BooksCashAccountKind)

One of: bank, cash, credit_card

cash.​accounts[].​balancePencerequiredinteger

Integer pence (GBP).

Debit positive: money held is positive, a card balance owed negative.

owedToYourequiredobject (BooksHomeOwed)
owedToYou.​totalPencerequiredinteger

Integer pence (GBP).

owedToYou.​overduePencerequiredinteger

Integer pence (GBP).

owedToYou.​contactsrequiredinteger

Customers (or suppliers) with something outstanding.

owedToYou.​basisrequiredstring (BooksAgedBasis)

One of: documents, ledger

youOwerequiredobject (BooksHomeOwed)
youOwe.​totalPencerequiredinteger

Integer pence (GBP).

youOwe.​overduePencerequiredinteger

Integer pence (GBP).

youOwe.​contactsrequiredinteger

Customers (or suppliers) with something outstanding.

youOwe.​basisrequiredstring (BooksAgedBasis)

One of: documents, ledger

vatrequiredobject (BooksHomeVat)
vat.​registeredrequiredboolean
vat.​owedPencerequiredinteger

Integer pence (GBP).

The VAT control account: owed to HMRC is positive.

taxrequiredobject (BooksTaxEstimate)nullable

Null for partnerships and LLPs (each partner is taxed on their share).

tax.​estimaterequiredboolean

One of: true

tax.​kindrequiredstring (BooksTaxEstimateKind)

One of: sole_trader, company

tax.​periodFromrequiredstring (date)

example "2026-03-31"

tax.​periodTorequiredstring (date)

example "2026-03-31"

tax.​asAtrequiredstring (date)

example "2026-03-31"

tax.​daysElapsedrequiredinteger
tax.​daysInPeriodrequiredinteger
tax.​profitBeforeTaxPencerequiredinteger

Integer pence (GBP).

tax.​addBacksrequiredarray of BooksTaxWorkingLine

Costs tax doesn’t allow, added back.

tax.​addBacks[].​accountIdrequiredstring (uuid)nullable
tax.​addBacks[].​coderequiredstring
tax.​addBacks[].​namerequiredstring
tax.​addBacks[].​amountPencerequiredinteger

Integer pence (GBP).

tax.​notTradingrequiredarray of BooksTaxWorkingLine

Income that isn’t trading income, taken out (sole traders).

tax.​notTrading[].​accountIdrequiredstring (uuid)nullable
tax.​notTrading[].​coderequiredstring
tax.​notTrading[].​namerequiredstring
tax.​notTrading[].​amountPencerequiredinteger

Integer pence (GBP).

tax.​profitToDatePencerequiredinteger

Integer pence (GBP).

Taxable profit so far, whole pounds (floored).

tax.​annualisedProfitPencerequiredinteger

Integer pence (GBP).

For the whole year at the same rate, whole pounds (floored).

tax.​taxYearLabelrequiredstringnullable

example "2026/27"

tax.​financialYearsrequiredarray of integer

Companies: the financial years whose rates were used.

tax.​otherIncomePencerequiredinteger

Integer pence (GBP).

tax.​linesrequiredarray of BooksTaxEstimateLine
tax.​lines[].​keyrequiredstring (BooksTaxEstimateLineKey)

other_income_tax: a sole trader’s tax on their other income less what PAYE took (only when they entered other income).

One of: income_tax, other_income_tax, class4_nic, corporation_tax

tax.​lines[].​labelrequiredstring
tax.​lines[].​annualPencerequiredinteger

Integer pence (GBP).

For the whole year, if profit carries on at the same rate.

tax.​lines[].​toDatePencerequiredinteger

Integer pence (GBP).

The share to have set aside by now.

tax.​annualTaxPencerequiredinteger

Integer pence (GBP).

tax.​setAsideToDatePencerequiredinteger

Integer pence (GBP).

tax.​effectiveRateBpsrequiredinteger

Annual tax as a share of annualised profit, basis points.

tax.​assumptionsrequiredarray of string
tax.​extraInfoTaxYearrequiredinteger

The tax year the owner’s extra information is for (starting year): the one containing the year end. Use it with /books/tax-details/{taxYear}.

tax.​extraInfoTaxYearLabelrequiredstring

example "2026/27"

tax.​basedOnrequiredobject (BooksTaxEstimateBasedOn)nullable

The owner’s extra information used, or null when none was entered.

tax.​basedOn.​otherIncomerequiredinteger

Sole traders: employment, pensions, property profits and savings interest added up.

tax.​basedOn.​taxPaidThroughPayerequiredinteger

Sole traders: tax already taken under PAYE.

tax.​basedOn.​pensionContributionsrequiredinteger

Sole traders: personal pension contributions paid in.

tax.​basedOn.​directorSalaryrequiredinteger

Companies: the director’s planned salary.

tax.​basedOn.​dividendsrequiredinteger

Companies: the director’s planned dividends.

tax.​ownerDividendTaxrequiredobject (BooksOwnerDividendTax)nullable

Companies with planned dividends: the director’s own tax on them.

tax.​ownerDividendTax.​taxYearrequiredinteger
tax.​ownerDividendTax.​taxYearLabelrequiredstring

example "2026/27"

tax.​ownerDividendTax.​directorSalaryrequiredinteger
tax.​ownerDividendTax.​dividendsrequiredinteger
tax.​ownerDividendTax.​dividendTaxrequiredinteger

Income tax on the dividends, after the salary uses the personal allowance and bands first.

tax.​ownerDividendTax.​assumptionsrequiredarray of string
taxUnavailablerequiredstringnullable

Why there is no estimate, in plain words.

needsYourequiredarray of BooksNeedsYou
needsYou[].​keyrequiredstring (BooksNeedsYouKey)

invoices appears only when a repeating invoice has made drafts to check.

One of: inbox, receipts, vat, invoices

needsYou[].​labelrequiredstring
needsYou[].​countrequiredintegernullable

Null when Tolvi can’t count it yet.

needsYou[].​detailrequiredstringnullable
monthSentencerequiredobject (BooksMonthSentence)

"This month in a sentence": worked out from the figures with fixed wording, not written by AI.

monthSentence.​textrequiredstring
monthSentence.​partsrequiredarray of BooksMonthSentencePart
monthSentence.​parts[].​textrequiredstring
monthSentence.​parts[].​linkedrequiredboolean

A figure to link to the profit and loss for the period.

monthSentence.​fromrequiredstring (date)

example "2026-03-31"

monthSentence.​torequiredstring (date)

example "2026-03-31"

monthSentence.​hasFiguresrequiredboolean

False when nothing is in the books for the period.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the extra information for the tax estimate

GET/api/v1/books/tax-details/{taxYear}

Scopes
books:read

What the owner entered for a more accurate tax to set aside, for one tax year; every figure is nil when nothing was entered. Anyone who can read the books: the business’s own people (including view-only) and a linked practice. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/tax-details/{taxYear}
NameInTypeDescription
taxYearrequiredpathinteger

The tax year’s starting year (2026 = 2026/27). The tax estimate gives the year it uses as extraInfoTaxYear.

2000 to 2100

Responses

200 OK, application/json

Body: object (BooksTaxDetails).

Extra information the owner gave for a more accurate tax to set aside, for one tax year. All figures are optional (nil when not entered) and only ever used for the estimate.

200 OK response for GET /api/v1/books/tax-details/{taxYear}
FieldTypeDescription
taxYearrequiredinteger

The tax year’s starting year (2026 = 2026/27).

taxYearLabelrequiredstring

example "2026/27"

employmentIncomePencerequiredinteger

Integer pence (GBP).

Sole traders. Pay from a job, before tax.

employmentTaxPaidPencerequiredinteger

Integer pence (GBP).

Sole traders. Tax taken from that pay under PAYE.

pensionIncomePencerequiredinteger

Integer pence (GBP).

Sole traders. State and private pensions received, before tax.

pensionTaxPaidPencerequiredinteger

Integer pence (GBP).

Sole traders. Tax taken from pensions under PAYE.

propertyIncomePencerequiredinteger

Integer pence (GBP).

Sole traders. Profit from letting property.

savingsInterestPencerequiredinteger

Integer pence (GBP).

Sole traders. Interest from savings.

pensionContributionsPencerequiredinteger

Integer pence (GBP).

Sole traders. Personal pension contributions paid in.

directorSalaryPencerequiredinteger

Integer pence (GBP).

Companies: the director’s own figure. Planned salary.

dividendsPencerequiredinteger

Integer pence (GBP).

Companies: the director’s own figure. Planned dividends.

updatedAtrequiredstring (date-time)nullable

When it was last saved; null when nothing has been entered.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

Save the extra information for the tax estimate

PUT/api/v1/books/tax-details/{taxYear}

Scopes
books:write

Replaces the figures for the tax year (anything left out is saved as nil). Only ever used for the estimate on Home; nothing is filed. The business’s people who can change the books, or an accountant whose link lets them (year_end or full_bookkeeping). View-only people and read-only links get 403. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for PUT /api/v1/books/tax-details/{taxYear}
NameInTypeDescription
taxYearrequiredpathinteger

The tax year’s starting year (2026 = 2026/27). The tax estimate gives the year it uses as extraInfoTaxYear.

2000 to 2100

Request body

Required. application/json: object (BooksTaxDetailsUpdate).

Replaces the extra information for the tax year. A figure left out is saved as nil.

Request body for PUT /api/v1/books/tax-details/{taxYear}
FieldTypeDescription
employmentIncomePenceinteger

Integer pence (GBP).

Sole traders. Pay from a job, before tax.

at least 0

employmentTaxPaidPenceinteger

Integer pence (GBP).

Sole traders. Tax taken from that pay under PAYE.

at least 0

pensionIncomePenceinteger

Integer pence (GBP).

Sole traders. State and private pensions received, before tax.

at least 0

pensionTaxPaidPenceinteger

Integer pence (GBP).

Sole traders. Tax taken from pensions under PAYE.

at least 0

propertyIncomePenceinteger

Integer pence (GBP).

Sole traders. Profit from letting property.

at least 0

savingsInterestPenceinteger

Integer pence (GBP).

Sole traders. Interest from savings.

at least 0

pensionContributionsPenceinteger

Integer pence (GBP).

Sole traders. Personal pension contributions paid in (relief at source); Tolvi adds basic rate relief.

at least 0

directorSalaryPenceinteger

Integer pence (GBP).

Companies: the director’s own figure. Planned salary for the tax year.

at least 0

dividendsPenceinteger

Integer pence (GBP).

Companies: the director’s own figure. Planned dividends for the tax year.

at least 0

Responses

200 OK, application/json

Body: object (BooksTaxDetails).

Extra information the owner gave for a more accurate tax to set aside, for one tax year. All figures are optional (nil when not entered) and only ever used for the estimate.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

Get VAT at a glance

GET/api/v1/books/vat/summary

Scopes
books:read

The next return and its deadline, what is owed (or due back) so far, the HMRC connection, whether filing from Tolvi is switched on, and anything that needs attention. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksVatSummary).

VAT at a glance: the next deadline, what is owed so far, and anything that needs attention.

200 OK response for GET /api/v1/books/vat/summary
FieldTypeDescription
registeredrequiredboolean
configuredrequiredboolean
schemerequiredstring (VatScheme)nullable

One of: standard, cash_accounting, flat_rate, annual_accounting

connectionrequiredobject (BooksHmrcConnection)

Tolvi’s authority to file VAT returns for the business at HMRC.

connection.​statusrequiredstring (BooksHmrcConnectionStatus)

One of: connected, needs_reconnect, disconnected, not_connected, not_available

connection.​environmentrequiredstringnullable

sandbox, production, custom, or fake (development).

connection.​connectedAtrequiredstring (date-time)nullable
connection.​grantExpiresAtrequiredstring (date-time)nullable

HMRC’s authority lasts 18 months, then you connect again.

connection.​reconnectSoonrequiredboolean
connection.​messagerequiredstring
submissionEnabledrequiredboolean

Whether returns can be sent to HMRC from this Tolvi (switched on once HMRC approves Tolvi).

submissionMessagerequiredstringnullable
nextrequiredobject (BooksVatNextReturn)nullable
next.​periodKeyrequiredstring
next.​startrequiredstring (date)

example "2026-03-31"

next.​endrequiredstring (date)

example "2026-03-31"

next.​duerequiredstring (date)

example "2026-03-31"

next.​sourcerequiredstring (BooksVatObligationSource)

One of: hmrc, expected

next.​statusrequiredstring (BooksVatPeriodStatus)

One of: open, filed, overdue, not_ended

next.​receivedrequiredstring (date)nullable

example "2026-03-31"

next.​box5requiredinteger

What is owed (or due back) so far, in pence.

next.​directionrequiredstring (BooksVatDirection)

One of: pay, repay, nil

lastFiledrequiredobject (BooksVatSubmission)nullable

A return sent to HMRC, with HMRC’s receipt once accepted. The figures never change.

lastFiled.​idrequiredstring (uuid)
lastFiled.​periodKeyrequiredstring

example "26AC"

lastFiled.​startrequiredstring (date)

example "2026-03-31"

lastFiled.​endrequiredstring (date)

example "2026-03-31"

lastFiled.​duerequiredstring (date)nullable

example "2026-03-31"

lastFiled.​statusrequiredstring (BooksVatSubmissionStatus)

pending (being sent), accepted, rejected, or unknown (no answer from HMRC: Tolvi checks with HMRC before trying again).

One of: pending, accepted, rejected, unknown

lastFiled.​boxesrequiredobject (BooksVatBoxes)

The nine boxes in pence. Boxes 6 to 9 are whole pounds (123400 is £1,234). Box 5 is never negative: see direction.

lastFiled.​boxes.​box1requiredinteger
lastFiled.​boxes.​box2requiredinteger
lastFiled.​boxes.​box3requiredinteger
lastFiled.​boxes.​box4requiredinteger
lastFiled.​boxes.​box5requiredinteger
lastFiled.​boxes.​box6requiredinteger
lastFiled.​boxes.​box7requiredinteger
lastFiled.​boxes.​box8requiredinteger
lastFiled.​boxes.​box9requiredinteger
lastFiled.​directionrequiredstring (BooksVatDirection)

One of: pay, repay, nil

lastFiled.​declaredAtrequiredstring (date-time)
lastFiled.​declaredByNamerequiredstringnullable
lastFiled.​asAgentrequiredboolean

Filed by an accountant for the business.

lastFiled.​processingDaterequiredstring (date-time)nullable
lastFiled.​formBundleNumberrequiredstringnullable

example "123456789012"

lastFiled.​paymentIndicatorrequiredstringnullable

DD: HMRC collects by Direct Debit. BANK: HMRC repays to the bank account it holds.

lastFiled.​chargeRefNumberrequiredstringnullable
lastFiled.​errorMessagerequiredstringnullable
problemsrequiredarray of BooksVatProblem
problems[].​coderequiredstring
problems[].​severityrequiredstring (BooksVatFindingSeverity)

One of: check, info

problems[].​messagerequiredstring

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the VAT settings

GET/api/v1/books/vat/settings

Scopes
books:read

The VAT number, return periods (stagger), registration date and the schemes over time, with the flat rate business types. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksVatSettings).

The business’s VAT registration, return periods and schemes.

200 OK response for GET /api/v1/books/vat/settings
FieldTypeDescription
registeredrequiredboolean
configuredrequiredboolean

False until VAT settings are saved (the return periods are then a guess).

vrnrequiredstringnullable
staggerrequiredstring (BooksVatStagger)

One of: stagger_1, stagger_2, stagger_3, monthly, annual

staggerLabelrequiredstring
annualEndMonthrequiredintegernullable
registeredFromrequiredstring (date)nullable

example "2026-03-31"

schemerequiredstring (VatScheme)nullable

One of: standard, cash_accounting, flat_rate, annual_accounting

schemesrequiredarray of BooksVatSchemePeriod
schemes[].​fromrequiredstring (date)

example "2026-03-31"

schemes[].​torequiredstring (date)nullable

example "2026-03-31"

schemes[].​accountingrequiredstring (BooksVatAccounting)

One of: accrual, cash

schemes[].​flatRateSectorrequiredstringnullable
schemes[].​flatRateSectorLabelrequiredstringnullable
schemes[].​flatRatePercentBpsrequiredintegernullable

The flat rate percentage in basis points today (the sector’s, less 1% in the first year).

schemes[].​firstYearDiscountrequiredboolean
schemes[].​annualAccountingrequiredboolean
filedTorequiredstring (date)nullable

Returns are filed up to this date: earlier scheme stretches can’t change.

example "2026-03-31"

flatRateSectorsrequiredarray of BooksVatFlatRateSectorOption
flatRateSectors[].​keyrequiredstring
flatRateSectors[].​labelrequiredstring
flatRateSectors[].​percentBpsrequiredinteger

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Change the VAT settings

PUT/api/v1/books/vat/settings

Scopes
books:admin
Access
A signed-in Tolvi session only, never an API token.

The business’s owners and admins, signed in. The VAT number’s check digits are checked. A change of scheme (cash accounting, flat rate, annual accounting) starts a new stretch from schemeFrom; nothing a filed return covers can change. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksUpdateVatSettings).

The business’s VAT registration and scheme. Changing the scheme starts a new stretch from schemeFrom; stretches covering a filed return never change.

Request body for PUT /api/v1/books/vat/settings
FieldTypeDescription
vrnrequiredstring

The 9-digit VAT registration number, with or without GB. Its check digits are checked.

example "123456782"

staggerrequiredstring (BooksVatStagger)

One of: stagger_1, stagger_2, stagger_3, monthly, annual

annualEndMonthintegernullable

Annual accounting: the month the VAT year ends.

registeredFromrequiredstring (date)

The effective date of registration.

example "2026-03-31"

accountingrequiredstring (BooksVatAccounting)

accrual (invoice dates) or cash (when money moves, Notice 731).

One of: accrual, cash

flatRateobject (BooksVatFlatRateChoice)nullable

The flat rate scheme; leave it out (or null) when not on it.

flatRate.​sectorrequiredstring (BooksVatFlatRateSector)

One of: accountancy-or-book-keeping, advertising, agricultural-services, any-other-activity, architect-engineer-or-surveyor, boarding-or-care-of-animals, business-services, catering, computer-and-it-consultancy, computer-repair, entertainment-or-journalism, estate-agency-or-property-management, farming-or-agriculture, film-radio-tv-or-video-production, financial-services, forestry-or-fishing, general-building-or-construction, hairdressing-or-beauty, hiring-or-renting-goods, hotel-or-accommodation, investigation-or-security, labour-only-building-or-construction, laundry-or-dry-cleaning, lawyer-or-legal-services, library-archive-museum-or-cultural, management-consultancy, manufacturing-fabricated-metal-products, manufacturing-food, manufacturing-other, manufacturing-yarn-textiles-or-clothing, membership-organisation, mining-or-quarrying, packaging, photography, post-offices, printing, publishing, pubs, real-estate-other, repairing-personal-or-household-goods, repairing-vehicles, retailing-food-confectionery-tobacco-newspapers-childrens-clothing, retailing-pharmaceuticals-medical-cosmetics-toiletries, retailing-other, retailing-vehicles-or-fuel, secretarial-services, social-work, sport-or-recreation, transport-or-storage, travel-agency, veterinary-medicine, wholesaling-agricultural-products, wholesaling-food, wholesaling-other

flatRate.​firstYearDiscountrequiredboolean

The 1% reduction in the first year of VAT registration (Notice 733 para 4.7).

annualAccountingboolean
schemeFromstring (date)

example "2026-03-31"

Responses

200 OK, application/json

Body: object (BooksVatSettings).

The business’s VAT registration, return periods and schemes.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

List the VAT periods

GET/api/v1/books/vat/obligations

Scopes
books:read

HMRC’s obligations as last fetched; before Tolvi is connected to HMRC, the periods expected from the return periods. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksVatPeriods).

200 OK response for GET /api/v1/books/vat/obligations
FieldTypeDescription
periodsrequiredarray of BooksVatPeriod
periods[].​periodKeyrequiredstring
periods[].​startrequiredstring (date)

example "2026-03-31"

periods[].​endrequiredstring (date)

example "2026-03-31"

periods[].​duerequiredstring (date)

example "2026-03-31"

periods[].​sourcerequiredstring (BooksVatObligationSource)

One of: hmrc, expected

periods[].​statusrequiredstring (BooksVatPeriodStatus)

One of: open, filed, overdue, not_ended

periods[].​receivedrequiredstring (date)nullable

example "2026-03-31"

fetchedAtrequiredstring (date-time)nullable

When HMRC was last asked (null: never, the periods are expected ones).

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get a VAT return

GET/api/v1/books/vat/returns/{periodKey}

Scopes
books:read

Worked out from the books now, with Tolvi’s own checks and the latest check before filing; once filed, the figures HMRC accepted and its receipt. returnHash identifies these exact figures. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/vat/returns/{periodKey}
NameInTypeDescription
periodKeyrequiredpathstring

HMRC’s period key (4 characters; # written as %23).

example "26AC"

Responses

200 OK, application/json

Body: object (BooksVatReturn).

A VAT return for one period: worked out from the books until it is filed, then the figures HMRC accepted.

200 OK response for GET /api/v1/books/vat/returns/{periodKey}
FieldTypeDescription
periodKeyrequiredstring

example "26AC"

startrequiredstring (date)

example "2026-03-31"

endrequiredstring (date)

example "2026-03-31"

duerequiredstring (date)nullable

example "2026-03-31"

sourcerequiredstring (BooksVatPeriodSource)

hmrc (an obligation), filed, or expected (from the return periods; not connected to HMRC yet).

One of: hmrc, filed, expected

statusrequiredstring (BooksVatReturnStatus)

One of: open, filed, not_ended, sending

boxesrequiredobject (BooksVatBoxes)

The nine boxes in pence. Boxes 6 to 9 are whole pounds (123400 is £1,234). Box 5 is never negative: see direction.

boxes.​box1requiredinteger
boxes.​box2requiredinteger
boxes.​box3requiredinteger
boxes.​box4requiredinteger
boxes.​box5requiredinteger
boxes.​box6requiredinteger
boxes.​box7requiredinteger
boxes.​box8requiredinteger
boxes.​box9requiredinteger
directionrequiredstring (BooksVatDirection)

One of: pay, repay, nil

boxesInPencerequiredobject (BooksVatBoxesInPence)
boxesInPence.​box6requiredinteger
boxesInPence.​box7requiredinteger
boxesInPence.​box8requiredinteger
boxesInPence.​box9requiredinteger
lineCountrequiredinteger
lateCountrequiredinteger

Payments brought in from a period already filed (cash accounting).

flatRaterequiredobject (BooksVatFlatRateSummary)nullable
flatRate.​turnoverGrossPencerequiredinteger

Integer pence (GBP).

flatRate.​limitedCostrequiredboolean
flatRate.​explanationrequiredstring
flatRate.​bucketsrequiredarray of BooksVatFlatRateBucket
flatRate.​buckets[].​bpsrequiredinteger
flatRate.​buckets[].​turnoverGrossPencerequiredinteger

Integer pence (GBP).

flatRate.​buckets[].​vatPencerequiredinteger

Integer pence (GBP).

flatRate.​buckets[].​firstYearReductionrequiredboolean
findingsrequiredarray of BooksVatFinding

Tolvi’s own checks (no AI).

findings[].​kindrequiredstring

example "missing_receipt"

findings[].​severityrequiredstring (BooksVatFindingSeverity)

One of: check, info

findings[].​titlerequiredstring
findings[].​detailrequiredstring
findings[].​boxrequiredintegernullable
findings[].​lineRefsrequiredarray of string

The lines it is about, as seq:lineIndex.

errorNotificationrequiredobject (BooksVatErrorNotification)nullable

Corrections to earlier returns over the Notice 700/45 limit. They are not on this return: the business must tell HMRC separately (form VAT652).

errorNotification.​netErrorPencerequiredinteger

What the corrections do to box 5, in pence: positive is more owed to HMRC.

errorNotification.​limitPencerequiredinteger

The limit for this return, in pence.

errorNotification.​box6Pencerequiredinteger

Integer pence (GBP).

errorNotification.​messagerequiredstring
errorNotification.​sourcerequiredstring

The legislation or HMRC notice.

errorNotification.​lineRefsrequiredarray of string
takenBackCountrequiredinteger

Payments undone after an earlier return included them, taken back on this one.

returnHashrequiredstring

Send it back when filing: the figures filed are the ones reviewed.

checkrequiredobject (BooksVatCheck)nullable

The check before filing: Tolvi’s own checks and Tolvi AI’s suggestions. It never changes the return.

check.​idrequiredstring (uuid)
check.​createdAtrequiredstring (date-time)
check.​returnHashrequiredstring
check.​currentrequiredboolean
check.​summaryrequiredstring
check.​findingsrequiredarray of BooksVatFinding
check.​findings[].​kindrequiredstring

example "missing_receipt"

check.​findings[].​severityrequiredstring (BooksVatFindingSeverity)

One of: check, info

check.​findings[].​titlerequiredstring
check.​findings[].​detailrequiredstring
check.​findings[].​boxrequiredintegernullable
check.​findings[].​lineRefsrequiredarray of string

The lines it is about, as seq:lineIndex.

check.​airequiredboolean
submissionrequiredobject (BooksVatSubmission)nullable

A return sent to HMRC, with HMRC’s receipt once accepted. The figures never change.

submission.​idrequiredstring (uuid)
submission.​periodKeyrequiredstring

example "26AC"

submission.​startrequiredstring (date)

example "2026-03-31"

submission.​endrequiredstring (date)

example "2026-03-31"

submission.​duerequiredstring (date)nullable

example "2026-03-31"

submission.​statusrequiredstring (BooksVatSubmissionStatus)

pending (being sent), accepted, rejected, or unknown (no answer from HMRC: Tolvi checks with HMRC before trying again).

One of: pending, accepted, rejected, unknown

submission.​boxesrequiredobject (BooksVatBoxes)

The nine boxes in pence. Boxes 6 to 9 are whole pounds (123400 is £1,234). Box 5 is never negative: see direction.

submission.​boxes.​box1requiredinteger
submission.​boxes.​box2requiredinteger
submission.​boxes.​box3requiredinteger
submission.​boxes.​box4requiredinteger
submission.​boxes.​box5requiredinteger
submission.​boxes.​box6requiredinteger
submission.​boxes.​box7requiredinteger
submission.​boxes.​box8requiredinteger
submission.​boxes.​box9requiredinteger
submission.​directionrequiredstring (BooksVatDirection)

One of: pay, repay, nil

submission.​declaredAtrequiredstring (date-time)
submission.​declaredByNamerequiredstringnullable
submission.​asAgentrequiredboolean

Filed by an accountant for the business.

submission.​processingDaterequiredstring (date-time)nullable
submission.​formBundleNumberrequiredstringnullable

example "123456789012"

submission.​paymentIndicatorrequiredstringnullable

DD: HMRC collects by Direct Debit. BANK: HMRC repays to the bank account it holds.

submission.​chargeRefNumberrequiredstringnullable
submission.​errorMessagerequiredstringnullable
canSubmitrequiredboolean
cannotSubmitReasonrequiredstringnullable
declarationrequiredobject (BooksVatDeclaration)

The legal declaration to show and accept before filing (HMRC’s wording).

declaration.​versionrequiredstring
declaration.​textrequiredstring
declaration.​asAgentrequiredboolean

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

List the lines behind a VAT return

GET/api/v1/books/vat/returns/{periodKey}/lines

Scopes
books:read

Each line (or payment, under cash accounting) in the return and what it adds to each box, with why. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/vat/returns/{periodKey}/lines
NameInTypeDescription
periodKeyrequiredpathstring

HMRC’s period key (4 characters; # written as %23).

example "26AC"

boxqueryinteger

Only the lines that add to this box (1 to 9). Box 3 shows boxes 1 and 2; box 5 shows 1, 2 and 4.

1 to 9

Responses

200 OK, application/json

Body: object (BooksVatReturnLines).

200 OK response for GET /api/v1/books/vat/returns/{periodKey}/lines
FieldTypeDescription
boxrequiredintegernullable
totalPencerequiredinteger

The box’s total, in pence.

titlerequiredstring
meaningrequiredstring
linesrequiredarray of BooksVatReturnLine
lines[].​refrequiredstring

seq:lineIndex

example "12:0"

lines[].​lineIdrequiredstring (uuid)
lines[].​entryIdrequiredstring (uuid)
lines[].​entrySeqrequiredinteger
lines[].​daterequiredstring (date)

example "2026-03-31"

lines[].​taxPointrequiredstring (date)

example "2026-03-31"

lines[].​accountingDaterequiredstring (date)nullable

The date that put it in this return (the tax point, or when it was paid under cash accounting).

example "2026-03-31"

lines[].​descriptionrequiredstring
lines[].​accountCoderequiredstring
lines[].​accountNamerequiredstring
lines[].​accountOwnerNamerequiredstring
lines[].​vatCodeIdrequiredstring
lines[].​siderequiredstring (BooksVatSide)

One of: sale, purchase

lines[].​netPencerequiredinteger

Integer pence (GBP).

lines[].​vatPencerequiredinteger

Integer pence (GBP).

lines[].​boxesrequiredarray of BooksVatBoxAmount
lines[].​boxes[].​boxrequiredinteger
lines[].​boxes[].​amountPencerequiredinteger

Integer pence (GBP).

lines[].​flatRateTurnoverPencerequiredinteger

Integer pence (GBP).

lines[].​explanationrequiredstring
lines[].​laterequiredboolean
lines[].​settlementIdrequiredstring (uuid)nullable
lines[].​hasReceiptrequiredboolean

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

Check a VAT return before filing

POST/api/v1/books/vat/returns/{periodKey}/check

Scopes
books:write

Tolvi’s own checks and Tolvi AI’s suggestions: unusual movements, purchases without receipts and reverse charge oddities. Suggestions only: nothing in the return or the books changes. Included in the Books price; not available through MCP. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/vat/returns/{periodKey}/check
NameInTypeDescription
periodKeyrequiredpathstring

HMRC’s period key (4 characters; # written as %23).

example "26AC"

Responses

200 OK, application/json

Body: object (BooksVatCheck).

The check before filing: Tolvi’s own checks and Tolvi AI’s suggestions. It never changes the return.

200 OK response for POST /api/v1/books/vat/returns/{periodKey}/check
FieldTypeDescription
idrequiredstring (uuid)
createdAtrequiredstring (date-time)
returnHashrequiredstring
currentrequiredboolean
summaryrequiredstring
findingsrequiredarray of BooksVatFinding
findings[].​kindrequiredstring

example "missing_receipt"

findings[].​severityrequiredstring (BooksVatFindingSeverity)

One of: check, info

findings[].​titlerequiredstring
findings[].​detailrequiredstring
findings[].​boxrequiredintegernullable
findings[].​lineRefsrequiredarray of string

The lines it is about, as seq:lineIndex.

airequiredboolean

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

Record telling HMRC about corrections over the limit

POST/api/v1/books/vat/returns/{periodKey}/error-notification

Scopes
books:write
Access
A signed-in Tolvi session only, never an API token.

Corrections to earlier returns over the VAT Notice 700/45 limit can’t go on a return: the business tells HMRC separately (form VAT652), then records it here so they stay off every return. The business’s owners and admins, or an accountant through a full bookkeeping link (who accepts the agent’s declaration). Signed in only: never an API token, a connected app or MCP. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/vat/returns/{periodKey}/error-notification
NameInTypeDescription
periodKeyrequiredpathstring

HMRC’s period key (4 characters; # written as %23).

example "26AC"

Request body

Required. application/json: object (BooksVatRecordErrorNotification).

The business has told HMRC about corrections over the limit: they stay off every return from now on.

Request body for POST /api/v1/books/vat/returns/{periodKey}/error-notification
FieldTypeDescription
notifiedOnrequiredstring (date)

example "2026-03-31"

referencestring

Responses

200 OK, application/json

Body: object (BooksVatReturn).

A VAT return for one period: worked out from the books until it is filed, then the figures HMRC accepted.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).

File a VAT return with HMRC

POST/api/v1/books/vat/returns/{periodKey}/submit

Scopes
books:write
Access
A signed-in Tolvi session only, never an API token.
Retries
Send an Idempotency-Key to make retries safe.

The business’s owners and admins, or an accountant through a full bookkeeping link (who accepts the agent’s declaration). Signed in only: never an API token, a connected app or MCP. The person accepts HMRC’s declaration; returnHash must match the return they reviewed, or 409. A pending record is written before HMRC is called, so a lost answer is checked with HMRC rather than sent twice. When HMRC accepts, the period’s VAT lines lock. Answers 503 while filing from Tolvi is switched off (until HMRC approves Tolvi). Open even while Books is suspended. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/vat/returns/{periodKey}/submit
NameInTypeDescription
periodKeyrequiredpathstring

HMRC’s period key (4 characters; # written as %23).

example "26AC"

Idempotency-Keyheaderstring

A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.

1 to 255 characters

Request body

Required. application/json: object (BooksSubmitVatReturn).

File the return. The person accepts HMRC’s declaration; returnHash must be the preview’s, so what was reviewed is what is filed.

Request body for POST /api/v1/books/vat/returns/{periodKey}/submit
FieldTypeDescription
returnHashrequiredstring
declarationobject
declaration.​acceptedrequiredboolean

One of: true

declaration.​versionrequiredstring
checkIdstring (uuid)
clientFactsrequiredobject (BooksVatClientFacts)

What the browser knows about itself, for HMRC’s fraud prevention headers (Gov-Client-*). Send it with every request that reaches HMRC.

clientFacts.​deviceIdrequiredstring (uuid)

A UUID kept on this device (local storage).

clientFacts.​userAgentrequiredstring

navigator.userAgent

clientFacts.​screensrequiredarray of object
clientFacts.​screens[].​widthrequiredinteger
clientFacts.​screens[].​heightrequiredinteger
clientFacts.​screens[].​scalingFactorrequirednumber
clientFacts.​screens[].​colourDepthrequiredinteger
clientFacts.​windowWidthrequiredinteger
clientFacts.​windowHeightrequiredinteger
clientFacts.​timezonerequiredstring

example "UTC+01:00"

clientFacts.​appVersionstring

Responses

200 OK, application/json

Body: object (BooksVatReturn).

A VAT return for one period: worked out from the books until it is filed, then the figures HMRC accepted.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 409 Conflict, 422 Unprocessable content, 429 Too many requests, as problem details (application/problem+json).

List VAT returns sent to HMRC

GET/api/v1/books/vat/submissions

Scopes
books:read

Newest first, with HMRC’s receipts. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksVatSubmissions).

200 OK response for GET /api/v1/books/vat/submissions
FieldTypeDescription
submissionsrequiredarray of BooksVatSubmission
submissions[].​idrequiredstring (uuid)
submissions[].​periodKeyrequiredstring

example "26AC"

submissions[].​startrequiredstring (date)

example "2026-03-31"

submissions[].​endrequiredstring (date)

example "2026-03-31"

submissions[].​duerequiredstring (date)nullable

example "2026-03-31"

submissions[].​statusrequiredstring (BooksVatSubmissionStatus)

pending (being sent), accepted, rejected, or unknown (no answer from HMRC: Tolvi checks with HMRC before trying again).

One of: pending, accepted, rejected, unknown

submissions[].​boxesrequiredobject (BooksVatBoxes)

The nine boxes in pence. Boxes 6 to 9 are whole pounds (123400 is £1,234). Box 5 is never negative: see direction.

submissions[].​boxes.​box1requiredinteger
submissions[].​boxes.​box2requiredinteger
submissions[].​boxes.​box3requiredinteger
submissions[].​boxes.​box4requiredinteger
submissions[].​boxes.​box5requiredinteger
submissions[].​boxes.​box6requiredinteger
submissions[].​boxes.​box7requiredinteger
submissions[].​boxes.​box8requiredinteger
submissions[].​boxes.​box9requiredinteger
submissions[].​directionrequiredstring (BooksVatDirection)

One of: pay, repay, nil

submissions[].​declaredAtrequiredstring (date-time)
submissions[].​declaredByNamerequiredstringnullable
submissions[].​asAgentrequiredboolean

Filed by an accountant for the business.

submissions[].​processingDaterequiredstring (date-time)nullable
submissions[].​formBundleNumberrequiredstringnullable

example "123456789012"

submissions[].​paymentIndicatorrequiredstringnullable

DD: HMRC collects by Direct Debit. BANK: HMRC repays to the bank account it holds.

submissions[].​chargeRefNumberrequiredstringnullable
submissions[].​errorMessagerequiredstringnullable

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get VAT owed and paid at HMRC

GET/api/v1/books/vat/payments

Scopes
books:read

HMRC’s liabilities and payments for the last year, as last fetched. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksVatPaymentsAndLiabilities).

What HMRC says is owed and has been paid, as last fetched.

200 OK response for GET /api/v1/books/vat/payments
FieldTypeDescription
liabilitiesrequiredarray of BooksVatLiability
liabilities[].​periodStartrequiredstring (date)nullable

example "2026-03-31"

liabilities[].​periodEndrequiredstring (date)nullable

example "2026-03-31"

liabilities[].​typerequiredstring

example "VAT Return Debit Charge"

liabilities[].​originalAmountPencerequiredinteger

Integer pence (GBP).

liabilities[].​outstandingAmountPencerequiredintegernullable

Integer pence (GBP).

liabilities[].​duerequiredstring (date)nullable

example "2026-03-31"

paymentsrequiredarray of BooksVatPayment
payments[].​amountPencerequiredinteger

Integer pence (GBP).

payments[].​receivedrequiredstring (date)nullable

example "2026-03-31"

fetchedAtrequiredstring (date-time)nullable

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the HMRC connection

GET/api/v1/books/vat/hmrc

Scopes
books:read

Whether Tolvi may file for the business at HMRC, and when the authority ends (HMRC’s lasts 18 months). Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksHmrcConnection).

Tolvi’s authority to file VAT returns for the business at HMRC.

200 OK response for GET /api/v1/books/vat/hmrc
FieldTypeDescription
statusrequiredstring (BooksHmrcConnectionStatus)

One of: connected, needs_reconnect, disconnected, not_connected, not_available

environmentrequiredstringnullable

sandbox, production, custom, or fake (development).

connectedAtrequiredstring (date-time)nullable
grantExpiresAtrequiredstring (date-time)nullable

HMRC’s authority lasts 18 months, then you connect again.

reconnectSoonrequiredboolean
messagerequiredstring

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Disconnect from HMRC

DELETE/api/v1/books/vat/hmrc

Scopes
books:admin
Access
A signed-in Tolvi session only, never an API token.

The business’s owners and admins, signed in. Tolvi forgets the tokens; filed returns stay. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksHmrcConnection).

Tolvi’s authority to file VAT returns for the business at HMRC.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Start connecting to HMRC

POST/api/v1/books/vat/hmrc/authorize

Scopes
books:admin
Access
A signed-in Tolvi session only, never an API token.

The business’s owners and admins, signed in. Returns HMRC’s sign-in URL; HMRC sends the person back to the Books app, which finishes with POST /books/vat/hmrc/callback. Never through MCP. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksHmrcAuthorize).

200 OK response for POST /api/v1/books/vat/hmrc/authorize
FieldTypeDescription
urlrequiredstring

Send the person here to sign in to HMRC and give Tolvi authority.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Finish connecting to HMRC

POST/api/v1/books/vat/hmrc/callback

Scopes
books:admin
Access
A signed-in Tolvi session only, never an API token.

Called by the Books app’s HMRC return page with the code and state, as the person who started. The state is single use and lasts 10 minutes. Tokens are encrypted and never returned. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksHmrcCallback).

Request body for POST /api/v1/books/vat/hmrc/callback
FieldTypeDescription
coderequiredstring
staterequiredstring

Responses

200 OK, application/json

Body: object (BooksHmrcConnection).

Tolvi’s authority to file VAT returns for the business at HMRC.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get the VAT periods from HMRC

POST/api/v1/books/vat/hmrc/obligations/refresh

Scopes
books:write

Asks HMRC for the business’s obligations (about eight months back and four ahead) and keeps them. Send the browser’s facts for the fraud prevention headers. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksVatWithClientFacts).

Request body for POST /api/v1/books/vat/hmrc/obligations/refresh
FieldTypeDescription
clientFactsrequiredobject (BooksVatClientFacts)

What the browser knows about itself, for HMRC’s fraud prevention headers (Gov-Client-*). Send it with every request that reaches HMRC.

clientFacts.​deviceIdrequiredstring (uuid)

A UUID kept on this device (local storage).

clientFacts.​userAgentrequiredstring

navigator.userAgent

clientFacts.​screensrequiredarray of object
clientFacts.​screens[].​widthrequiredinteger
clientFacts.​screens[].​heightrequiredinteger
clientFacts.​screens[].​scalingFactorrequirednumber
clientFacts.​screens[].​colourDepthrequiredinteger
clientFacts.​windowWidthrequiredinteger
clientFacts.​windowHeightrequiredinteger
clientFacts.​timezonerequiredstring

example "UTC+01:00"

clientFacts.​appVersionstring

Responses

200 OK, application/json

Body: object (BooksVatPeriods).

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).

Get VAT owed and paid from HMRC

POST/api/v1/books/vat/hmrc/payments/refresh

Scopes
books:write

Asks HMRC for the business’s liabilities and payments over the last year and keeps them. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksVatWithClientFacts).

The fields are as shown above.

Responses

200 OK, application/json

Body: object (BooksVatPaymentsAndLiabilities).

What HMRC says is owed and has been paid, as last fetched.

The fields are as shown above.

Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).