Skip to main content

Books

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

Sign a business up to Tolvi Books

POST/api/v1/books/signup

Access
No authentication.

Creates the business and emails a single-use link to the address given. Following it confirms the address, has the person choose a password in the Tolvi Books app and makes them the business’s owner. No token needed.

Request body

Required. application/json: object (BooksSignUp).

A business signing up to Tolvi Books on its own.

Request body for POST /api/v1/books/signup
FieldTypeDescription
businessNamerequiredstring

up to 200 characters; example "Abbey Bakery Ltd"

entityTyperequiredstring (EntityType)

One of: LTD_FRS102_1A, LTD_FRS105_MICRO, LLP, SOLE_TRADER, INDIVIDUAL, PARTNERSHIP, TRUST, ESTATE, CHARITY_UNINCORPORATED, CHARITY_TRUST, CIO, SCIO, CHARITABLE_COMPANY

emailrequiredstring (email)

up to 254 characters

Responses

202 Accepted, application/json

Body: object (SignUpResult).

202 Accepted response for POST /api/v1/books/signup
FieldTypeDescription
emailrequiredstring (email)

Where the link to finish signing up was sent.

403 Forbidden

Sign-up is closed: people join by invitation (TOLVI_SIGNUP_OPEN is off).

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

Get the business’s profile

GET/api/v1/books/business

Scopes
books:read

Anyone who can read the books, including a linked accountant. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (Business).

A business’s profile in Tolvi Books: who it is, its VAT registration and its year end.

200 OK response for GET /api/v1/books/business
FieldTypeDescription
idrequiredstring (uuid)

The business’s tenant id (send it as x-business-id to work in its books as its accountant).

legalNamerequiredstring

example "Abbey Bakery Ltd"

tradingNamerequiredstringnullable
entityTyperequiredstring (EntityType)

One of: LTD_FRS102_1A, LTD_FRS105_MICRO, LLP, SOLE_TRADER, INDIVIDUAL, PARTNERSHIP, TRUST, ESTATE, CHARITY_UNINCORPORATED, CHARITY_TRUST, CIO, SCIO, CHARITABLE_COMPANY

companyNumberrequiredstringnullable

example "01234567"

vatRegisteredrequiredboolean
vatNumberrequiredstringnullable

9 digits (12 for a group branch), without GB.

example "123456789"

vatSchemerequiredstring (VatScheme)nullable

One of: standard, cash_accounting, flat_rate, annual_accounting

vatRegisteredFromrequiredstring (date)nullable

example "2026-03-31"

yearEndDayrequiredintegernullable

1 to 31

yearEndMonthrequiredintegernullable

1 to 12

booksStartDaterequiredstring (date)nullable

The first day the books cover.

example "2026-03-31"

baseCurrencyrequiredstring (BooksCurrency)

One of: GBP

custodianFirmIdrequiredstring (uuid)nullable

The accountancy practice that set the business up, until an owner claims it.

createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

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

Change the business’s details

PATCH/api/v1/books/business

Scopes
books:write

The business’s owners and admins (books:admin). A practice that set the business up can too, through its link, until the owner joins. Changing VAT details needs a signed-in person. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (UpdateBusiness).

Only the fields sent change. VAT details need a signed-in person.

Request body for PATCH /api/v1/books/business
FieldTypeDescription
legalNamestring

up to 200 characters

tradingNamestringnullable

up to 200 characters

entityTypestring (EntityType)

One of: LTD_FRS102_1A, LTD_FRS105_MICRO, LLP, SOLE_TRADER, INDIVIDUAL, PARTNERSHIP, TRUST, ESTATE, CHARITY_UNINCORPORATED, CHARITY_TRUST, CIO, SCIO, CHARITABLE_COMPANY

companyNumberstringnullable

pattern ^[A-Za-z0-9 ]{8,10}$

vatRegisteredboolean
vatNumberstringnullable
vatSchemestring (VatScheme)nullable

One of: standard, cash_accounting, flat_rate, annual_accounting

vatRegisteredFromstring (date)nullable

example "2026-03-31"

yearEndDayintegernullable

1 to 31

yearEndMonthintegernullable

1 to 12

booksStartDatestring (date)nullable

example "2026-03-31"

Responses

200 OK, application/json

Body: object (Business).

A business’s profile in Tolvi Books: who it is, its VAT registration and its year end.

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 business’s accountants

GET/api/v1/books/accountants

Scopes
books:read

Every practice link, live or ended. A linked accountant sees only their own firm’s link. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: array of PracticeLink.

An accountancy practice’s access to a business’s books, as either side sees it.

200 OK response for GET /api/v1/books/accountants
FieldTypeDescription
[].​idrequiredstring (uuid)
[].​statusrequiredstring (PracticeLinkStatus)

invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again.

One of: invited_by_business, requested_by_firm, active, ended

[].​accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

[].​vatAgentrequiredboolean

The practice may prepare (and, once built, submit) VAT returns. At most one practice at a time.

[].​billedByrequiredstring (LinkBilledBy)

Who the business said should pay, on its link.

One of: business, firm

[].​consentBasisrequiredstring (LinkConsentBasis)

One of: owner_consent, practice_provisioned

[].​businessIdrequiredstring (uuid)nullable
[].​businessNamerequiredstringnullable
[].​firmIdrequiredstring (uuid)nullable
[].​firmNamerequiredstringnullable
[].​invitedEmailrequiredstringnullable
[].​requestedEmailrequiredstringnullable
[].​expiresAtrequiredstring (date-time)nullable
[].​createdAtrequiredstring (date-time)
[].​activatedAtrequiredstring (date-time)nullable
[].​endedAtrequiredstring (date-time)nullable
[].​endedBySiderequiredstring (LinkSide)nullable

One of: business, firm

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

Invite an accountant

POST/api/v1/books/accountants/invitations

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

Emails a single-use link to the accountant, who accepts while signed in to their practice. Signed-in owners and admins only. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accountants/invitations
NameInTypeDescription
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 (InviteAccountant).

Request body for POST /api/v1/books/accountants/invitations
FieldTypeDescription
emailrequiredstring (email)

The accountant who will accept, signed in to their practice in Tolvi.

up to 254 characters

accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

vatAgentboolean

Responses

201 Created, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

201 Created response for POST /api/v1/books/accountants/invitations
FieldTypeDescription
idrequiredstring (uuid)
statusrequiredstring (PracticeLinkStatus)

invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again.

One of: invited_by_business, requested_by_firm, active, ended

accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

vatAgentrequiredboolean

The practice may prepare (and, once built, submit) VAT returns. At most one practice at a time.

billedByrequiredstring (LinkBilledBy)

Who the business said should pay, on its link.

One of: business, firm

consentBasisrequiredstring (LinkConsentBasis)

One of: owner_consent, practice_provisioned

businessIdrequiredstring (uuid)nullable
businessNamerequiredstringnullable
firmIdrequiredstring (uuid)nullable
firmNamerequiredstringnullable
invitedEmailrequiredstringnullable
requestedEmailrequiredstringnullable
expiresAtrequiredstring (date-time)nullable
createdAtrequiredstring (date-time)
activatedAtrequiredstring (date-time)nullable
endedAtrequiredstring (date-time)nullable
endedBySiderequiredstring (LinkSide)nullable

One of: business, firm

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

Change an accountant’s access

PATCH/api/v1/books/accountants/{linkId}

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

Access level, VAT agent (one practice at a time) and who pays. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for PATCH /api/v1/books/accountants/{linkId}
NameInTypeDescription
linkIdrequiredpathstring (uuid)

Request body

Required. application/json: object (ChangePracticeLink).

Only the fields sent change.

Request body for PATCH /api/v1/books/accountants/{linkId}
FieldTypeDescription
accessstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

vatAgentboolean
billedBystring (LinkBilledBy)

Who the business said should pay, on its link.

One of: business, firm

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

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).

End an accountant’s access

POST/api/v1/books/accountants/{linkId}/end

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

Takes effect from their next request, in the database itself. Also withdraws an invitation. An ended link is never active again. Allowed even while Tolvi 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/accountants/{linkId}/end
NameInTypeDescription
linkIdrequiredpathstring (uuid)

Request body

Optional. application/json: object (EndPracticeLink).

Request body for POST /api/v1/books/accountants/{linkId}/end
FieldTypeDescription
reasonstring

up to 500 characters

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

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).

List practices’ requests for access

GET/api/v1/books/accountants/requests

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

Requests sent to your verified email address, waiting for an answer. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: array of PracticeLink.

An accountancy practice’s access to a business’s books, as either side sees it.

The fields are as shown above.

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

Approve a practice’s request

POST/api/v1/books/accountants/requests/{linkId}/approve

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

Links the practice to this business with the access you choose. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accountants/requests/{linkId}/approve
NameInTypeDescription
linkIdrequiredpathstring (uuid)

Request body

Optional. application/json: object (ApprovePracticeLinkRequest).

Request body for POST /api/v1/books/accountants/requests/{linkId}/approve
FieldTypeDescription
accessstring (PracticeAccess)

Defaults to what the practice asked for.

One of: read_only, year_end, full_bookkeeping

vatAgentboolean

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

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).

Decline a practice’s request

POST/api/v1/books/accountants/requests/{linkId}/decline

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

Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accountants/requests/{linkId}/decline
NameInTypeDescription
linkIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

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).

Ask a business for access to its books

POST/api/v1/practice/books/requests

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

Emails the owner, who approves or declines in Tolvi Books.

Parameters

Parameters for POST /api/v1/practice/books/requests
NameInTypeDescription
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 (RequestBooksAccess).

Request body for POST /api/v1/practice/books/requests
FieldTypeDescription
emailrequiredstring (email)

The business owner’s email: they approve in Tolvi Books.

up to 254 characters

accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

Responses

201 Created, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

The fields are as shown above.

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

See what a business’s invitation offers

POST/api/v1/practice/books/link-invitations/preview

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

The token from the email, in the body (never the URL).

Request body

Required. application/json: object (PracticeLinkToken).

The token from the invitation email.

Request body for POST /api/v1/practice/books/link-invitations/preview
FieldTypeDescription
tokenrequiredstring

20 to 200 characters

Responses

200 OK, application/json

Body: object (PracticeLinkInvitationPreview).

200 OK response for POST /api/v1/practice/books/link-invitations/preview
FieldTypeDescription
businessNamerequiredstringnullable
accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

vatAgentrequiredboolean
expiresAtrequiredstring (date-time)nullable
expiredrequiredboolean

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

Accept a business’s invitation

POST/api/v1/practice/books/link-invitations/accept

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

The person it was emailed to accepts, signed in to their practice. Single use.

Request body

Required. application/json: object (PracticeLinkToken).

The token from the invitation email.

Request body for POST /api/v1/practice/books/link-invitations/accept
FieldTypeDescription
tokenrequiredstring

20 to 200 characters

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

The fields are as shown above.

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

End the firm’s access to a business’s books

POST/api/v1/practice/books/links/{linkId}/end

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

Also withdraws a request. An ended link is never active again.

Parameters

Parameters for POST /api/v1/practice/books/links/{linkId}/end
NameInTypeDescription
linkIdrequiredpathstring (uuid)

Request body

Optional. application/json: object (EndPracticeLink).

Request body for POST /api/v1/practice/books/links/{linkId}/end
FieldTypeDescription
reasonstring

up to 500 characters

Responses

200 OK, application/json

Body: object (PracticeLink).

An accountancy practice’s access to a business’s books, as either side sees it.

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).

Set Tolvi Books up for a client

POST/api/v1/practice/books/businesses

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

Creates the business with the firm as its accountant (full bookkeeping) under the firm’s engagement letter. The firm looks after it until the owner joins.

Parameters

Parameters for POST /api/v1/practice/books/businesses
NameInTypeDescription
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 (ProvisionBusiness).

A practice setting Tolvi Books up for a client. The practice looks after it until the owner joins.

Request body for POST /api/v1/practice/books/businesses
FieldTypeDescription
legalNamerequiredstring

up to 200 characters

tradingNamestringnullable

up to 200 characters

entityTyperequiredstring (EntityType)

One of: LTD_FRS102_1A, LTD_FRS105_MICRO, LLP, SOLE_TRADER, INDIVIDUAL, PARTNERSHIP, TRUST, ESTATE, CHARITY_UNINCORPORATED, CHARITY_TRUST, CIO, SCIO, CHARITABLE_COMPANY

companyNumberstringnullable
yearEndDayintegernullable

1 to 31

yearEndMonthintegernullable

1 to 12

booksStartDatestring (date)nullable

example "2026-03-31"

billedBystring (LinkBilledBy)

Who pays for Tolvi Books. Defaults to the practice.

One of: business, firm

ownerEmailstring (email)

Invite the owner now (they can also be invited later).

Responses

201 Created, application/json

Body: object (ProvisionedBusiness).

The business a practice set up, and the practice’s link to it.

201 Created response for POST /api/v1/practice/books/businesses
FieldTypeDescription
businessrequiredobject (Business)

A business’s profile in Tolvi Books: who it is, its VAT registration and its year end.

business.​idrequiredstring (uuid)

The business’s tenant id (send it as x-business-id to work in its books as its accountant).

business.​legalNamerequiredstring

example "Abbey Bakery Ltd"

business.​tradingNamerequiredstringnullable
business.​entityTyperequiredstring (EntityType)

One of: LTD_FRS102_1A, LTD_FRS105_MICRO, LLP, SOLE_TRADER, INDIVIDUAL, PARTNERSHIP, TRUST, ESTATE, CHARITY_UNINCORPORATED, CHARITY_TRUST, CIO, SCIO, CHARITABLE_COMPANY

business.​companyNumberrequiredstringnullable

example "01234567"

business.​vatRegisteredrequiredboolean
business.​vatNumberrequiredstringnullable

9 digits (12 for a group branch), without GB.

example "123456789"

business.​vatSchemerequiredstring (VatScheme)nullable

One of: standard, cash_accounting, flat_rate, annual_accounting

business.​vatRegisteredFromrequiredstring (date)nullable

example "2026-03-31"

business.​yearEndDayrequiredintegernullable

1 to 31

business.​yearEndMonthrequiredintegernullable

1 to 12

business.​booksStartDaterequiredstring (date)nullable

The first day the books cover.

example "2026-03-31"

business.​baseCurrencyrequiredstring (BooksCurrency)

One of: GBP

business.​custodianFirmIdrequiredstring (uuid)nullable

The accountancy practice that set the business up, until an owner claims it.

business.​createdAtrequiredstring (date-time)
business.​updatedAtrequiredstring (date-time)
linkrequiredobject (PracticeLink)

An accountancy practice’s access to a business’s books, as either side sees it.

link.​idrequiredstring (uuid)
link.​statusrequiredstring (PracticeLinkStatus)

invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again.

One of: invited_by_business, requested_by_firm, active, ended

link.​accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

link.​vatAgentrequiredboolean

The practice may prepare (and, once built, submit) VAT returns. At most one practice at a time.

link.​billedByrequiredstring (LinkBilledBy)

Who the business said should pay, on its link.

One of: business, firm

link.​consentBasisrequiredstring (LinkConsentBasis)

One of: owner_consent, practice_provisioned

link.​businessIdrequiredstring (uuid)nullable
link.​businessNamerequiredstringnullable
link.​firmIdrequiredstring (uuid)nullable
link.​firmNamerequiredstringnullable
link.​invitedEmailrequiredstringnullable
link.​requestedEmailrequiredstringnullable
link.​expiresAtrequiredstring (date-time)nullable
link.​createdAtrequiredstring (date-time)
link.​activatedAtrequiredstring (date-time)nullable
link.​endedAtrequiredstring (date-time)nullable
link.​endedBySiderequiredstring (LinkSide)nullable

One of: business, firm

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

Invite the owner of a business the firm set up

POST/api/v1/practice/books/businesses/{businessId}/owner-invitation

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

Only while the firm still looks after it (before an owner has joined).

Parameters

Parameters for POST /api/v1/practice/books/businesses/{businessId}/owner-invitation
NameInTypeDescription
businessIdrequiredpathstring (uuid)

Request body

Required. application/json: object (OwnerInvitation).

Request body for POST /api/v1/practice/books/businesses/{businessId}/owner-invitation
FieldTypeDescription
emailrequiredstring (email)

up to 254 characters

Responses

200 OK, application/json

Body: object (OwnerInvitation).

200 OK response for POST /api/v1/practice/books/businesses/{businessId}/owner-invitation
FieldTypeDescription
emailrequiredstring (email)

up to 254 characters

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

List clients’ books

GET/api/v1/practice/books/clients

Scopes
client_books:read

Every business whose Tolvi Books the firm reaches (live and ended links), the client it is linked to, and for live links the books at a glance: entries posted, when last posted, receipts to review, VAT registration (bank lines to explain and VAT due appear once those are available).

Responses

200 OK, application/json

Body: object (ClientsBooksList).

200 OK response for GET /api/v1/practice/books/clients
FieldTypeDescription
rowsrequiredarray of ClientsBooksRow
rows[].​practiceLinkIdrequiredstring (uuid)
rows[].​businessIdrequiredstring (uuid)
rows[].​businessNamerequiredstringnullable
rows[].​linkStatusrequiredstring (PracticeLinkStatus)

invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again.

One of: invited_by_business, requested_by_firm, active, ended

rows[].​accessrequiredstring (PracticeAccess)

read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.

One of: read_only, year_end, full_bookkeeping

rows[].​consentBasisrequiredstring (LinkConsentBasis)

One of: owner_consent, practice_provisioned

rows[].​clientIdrequiredstring (uuid)nullable

The firm’s client these books are, once linked.

rows[].​clientNamerequiredstringnullable
rows[].​healthrequiredobject (BooksHealth)nullable

Null when the link has ended.

rows[].​health.​entriesrequiredinteger

Ledger entries posted.

at least 0

rows[].​health.​lastPostedAtrequiredstring (date-time)nullable
rows[].​health.​lastEntryDaterequiredstring (date)nullable

The latest date any entry is dated.

example "2026-03-31"

rows[].​health.​receiptsToReviewrequiredinteger

Receipts read and waiting to be confirmed.

at least 0

rows[].​health.​unexplainedBankLinesrequiredintegernullable

Bank lines not yet explained. Null until bank feeds are available.

at least 0

rows[].​health.​vatRegisteredrequiredboolean
rows[].​health.​vatSchemerequiredstringnullable

example "standard"

rows[].​health.​nextVatDuerequiredstring (date)nullable

The next VAT return due. Null until MTD VAT returns are available.

example "2026-03-31"

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

Get the chart of accounts

GET/api/v1/books/accounts

Scopes
books:read

Every account, with its balance now and whether it has been used. Set up from the template for the business’s entity type when the business joined. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksChartOfAccounts).

The business’s chart of accounts, and the template version it started from.

200 OK response for GET /api/v1/books/accounts
FieldTypeDescription
templateIdrequiredstring

example "ltd_frs102_1a"

templateVersionrequiredstring

example "2026-11"

entityTyperequiredstring

example "LTD_FRS102_1A"

accountsrequiredarray of BooksAccount
accounts[].​idrequiredstring (uuid)
accounts[].​coderequiredstring

Unique in the business; never changes.

example "6110"

accounts[].​namerequiredstring

The accountant’s name.

example "Light, heat and power"

accounts[].​ownerNamerequiredstring

What owners see.

example "Gas and electricity"

accounts[].​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

accounts[].​ownerCategoryLabelrequiredstring

example "Premises"

accounts[].​hintrequiredstringnullable

One sentence for owners on what goes here.

accounts[].​classrequiredstring (BooksAccountClass)

One of: asset, liability, equity, income, expense

accounts[].​normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

accounts[].​subtyperequiredstring

example "overhead"

accounts[].​leadLinerequiredstringnullable

The Working Papers lead schedule line the account maps to.

example "M.adm"

accounts[].​sa103requiredstringnullable

The SA103 line (sole traders).

accounts[].​systemRolerequiredstringnullable

Set for accounts Tolvi keeps (control accounts, suspense, retained earnings or capital): they can’t be archived or take a manual journal.

accounts[].​defaultVatCodeIdrequiredstringnullable

The VAT code suggested for new lines.

example "S20"

accounts[].​fromTemplaterequiredboolean

Created from the chart template when the business signed up.

accounts[].​archivedrequiredboolean
accounts[].​archivedAtrequiredstring (date-time)nullable
accounts[].​usedrequiredboolean

Posted to at least once: it can then be archived, never deleted.

accounts[].​balancePencerequiredinteger

The balance now, in pence (debit positive, credit negative).

accounts[].​createdAtrequiredstring (date-time)
accounts[].​updatedAtrequiredstring (date-time)

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

Add an account

POST/api/v1/books/accounts

Scopes
books:write
Retries
Send an Idempotency-Key to make retries safe.

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Give a name and a category: Tolvi picks a free code and copies the mapping from a similar account. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accounts
NameInTypeDescription
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 (BooksCreateAccount).

Add an account. Give a name and a category; Tolvi picks a free code and copies the mapping from a similar account unless you say otherwise.

Request body for POST /api/v1/books/accounts
FieldTypeDescription
namerequiredstring

up to 120 characters; example "Software subscriptions"

ownerNamestring

What owners see; defaults to the name.

up to 120 characters

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

classstring (BooksAccountClass)

Needed only where a category spans classes (bank and cash, tax, you and the business).

One of: asset, liability, equity, income, expense

codestring

Defaults to the next free code in the category’s range.

up to 20 characters

leadLinestring

Working Papers lead schedule line (accountants).

sa103string

SA103 line (accountants, sole traders).

subtypestring
hintstringnullable

up to 300 characters

defaultVatCodeIdstringnullable

example "S20"

likeAccountIdstring (uuid)

Copy the mapping from this account.

Responses

201 Created, application/json

Body: object (BooksAccount).

An account in the business’s chart of accounts. Owners see ownerName under ownerCategoryLabel; accountants see the code, name and class.

201 Created response for POST /api/v1/books/accounts
FieldTypeDescription
idrequiredstring (uuid)
coderequiredstring

Unique in the business; never changes.

example "6110"

namerequiredstring

The accountant’s name.

example "Light, heat and power"

ownerNamerequiredstring

What owners see.

example "Gas and electricity"

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

ownerCategoryLabelrequiredstring

example "Premises"

hintrequiredstringnullable

One sentence for owners on what goes here.

classrequiredstring (BooksAccountClass)

One of: asset, liability, equity, income, expense

normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

subtyperequiredstring

example "overhead"

leadLinerequiredstringnullable

The Working Papers lead schedule line the account maps to.

example "M.adm"

sa103requiredstringnullable

The SA103 line (sole traders).

systemRolerequiredstringnullable

Set for accounts Tolvi keeps (control accounts, suspense, retained earnings or capital): they can’t be archived or take a manual journal.

defaultVatCodeIdrequiredstringnullable

The VAT code suggested for new lines.

example "S20"

fromTemplaterequiredboolean

Created from the chart template when the business signed up.

archivedrequiredboolean
archivedAtrequiredstring (date-time)nullable
usedrequiredboolean

Posted to at least once: it can then be archived, never deleted.

balancePencerequiredinteger

The balance now, in pence (debit positive, credit negative).

createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

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

Rename or recategorise an account

PATCH/api/v1/books/accounts/{accountId}

Scopes
books:write

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Codes and classes never change. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for PATCH /api/v1/books/accounts/{accountId}
NameInTypeDescription
accountIdrequiredpathstring (uuid)

Request body

Required. application/json: object (BooksUpdateAccount).

Rename or recategorise an account. Codes and classes never change.

Request body for PATCH /api/v1/books/accounts/{accountId}
FieldTypeDescription
namestring

up to 120 characters

ownerNamestring

up to 120 characters

ownerCategorystring (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

hintstringnullable

up to 300 characters

defaultVatCodeIdstringnullable

Responses

200 OK, application/json

Body: object (BooksAccount).

An account in the business’s chart of accounts. Owners see ownerName under ownerCategoryLabel; accountants see the code, name and class.

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).

Delete an unused account

DELETE/api/v1/books/accounts/{accountId}

Scopes
books:write

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Only an account nothing has ever been posted to; once used, archive it instead (409). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for DELETE /api/v1/books/accounts/{accountId}
NameInTypeDescription
accountIdrequiredpathstring (uuid)

Responses

204 No content

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

Archive an account

POST/api/v1/books/accounts/{accountId}/archive

Scopes
books:write

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Its history stays; it is no longer offered for new entries. Refused for accounts Tolvi keeps and for accounts with a balance. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accounts/{accountId}/archive
NameInTypeDescription
accountIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (BooksAccount).

An account in the business’s chart of accounts. Owners see ownerName under ownerCategoryLabel; accountants see the code, name and class.

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).

Restore an archived account

POST/api/v1/books/accounts/{accountId}/restore

Scopes
books:write

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/accounts/{accountId}/restore
NameInTypeDescription
accountIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (BooksAccount).

An account in the business’s chart of accounts. Owners see ownerName under ownerCategoryLabel; accountants see the code, name and class.

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 one account’s ledger

GET/api/v1/books/accounts/{accountId}/ledger

Scopes
books:read

Postings between two dates with the balance brought forward and a running balance (debit positive). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/accounts/{accountId}/ledger
NameInTypeDescription
accountIdrequiredpathstring (uuid)
toquerystring (date)

Last day (inclusive). Defaults to today.

fromquerystring (date)

First day (inclusive). Defaults to the start of the financial year containing to.

Responses

200 OK, application/json

Body: object (BooksAccountLedger).

One account’s postings between two dates, with the balance brought forward and a running balance.

200 OK response for GET /api/v1/books/accounts/{accountId}/ledger
FieldTypeDescription
accountrequiredobject (BooksAccount)

An account in the business’s chart of accounts. Owners see ownerName under ownerCategoryLabel; accountants see the code, name and class.

account.​idrequiredstring (uuid)
account.​coderequiredstring

Unique in the business; never changes.

example "6110"

account.​namerequiredstring

The accountant’s name.

example "Light, heat and power"

account.​ownerNamerequiredstring

What owners see.

example "Gas and electricity"

account.​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

account.​ownerCategoryLabelrequiredstring

example "Premises"

account.​hintrequiredstringnullable

One sentence for owners on what goes here.

account.​classrequiredstring (BooksAccountClass)

One of: asset, liability, equity, income, expense

account.​normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

account.​subtyperequiredstring

example "overhead"

account.​leadLinerequiredstringnullable

The Working Papers lead schedule line the account maps to.

example "M.adm"

account.​sa103requiredstringnullable

The SA103 line (sole traders).

account.​systemRolerequiredstringnullable

Set for accounts Tolvi keeps (control accounts, suspense, retained earnings or capital): they can’t be archived or take a manual journal.

account.​defaultVatCodeIdrequiredstringnullable

The VAT code suggested for new lines.

example "S20"

account.​fromTemplaterequiredboolean

Created from the chart template when the business signed up.

account.​archivedrequiredboolean
account.​archivedAtrequiredstring (date-time)nullable
account.​usedrequiredboolean

Posted to at least once: it can then be archived, never deleted.

account.​balancePencerequiredinteger

The balance now, in pence (debit positive, credit negative).

account.​createdAtrequiredstring (date-time)
account.​updatedAtrequiredstring (date-time)
fromrequiredstring (date)

example "2026-03-31"

torequiredstring (date)

example "2026-03-31"

openingPencerequiredinteger

Integer pence (GBP).

closingPencerequiredinteger

Integer pence (GBP).

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

example "2026-03-31"

lines[].​kindrequiredstring (BooksEntryKind)

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

lines[].​descriptionrequiredstring
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

lines[].​runningBalancePencerequiredinteger

Integer pence (GBP).

lines[].​viarequiredstring (BooksPostedVia)

One of: web, api, mcp, bank_rule, ai_accepted, import, system

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

List posted entries

GET/api/v1/books/entries

Scopes
books:read

Newest first, with their lines. Posted entries never change. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/entries
NameInTypeDescription
limitqueryinteger

1 to 100; default 50

beforeSeqqueryinteger

The page before this entry number (from nextBeforeSeq).

at least 1

accountIdquerystring (uuid)

Only entries with a line on this account.

kindquerystring

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

toquerystring (date)

Entries dated on or before.

fromquerystring (date)

Entries dated on or after.

Responses

200 OK, application/json

Body: object (BooksEntryPage).

200 OK response for GET /api/v1/books/entries
FieldTypeDescription
itemsrequiredarray of BooksEntry
items[].​idrequiredstring (uuid)
items[].​seqrequiredinteger

Numbered from 1 per business, without gaps.

items[].​kindrequiredstring (BooksEntryKind)

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

items[].​daterequiredstring (date)

example "2026-03-31"

items[].​taxPointrequiredstring (date)nullable

example "2026-03-31"

items[].​descriptionrequiredstring
items[].​sourcerequiredobject (BooksEntrySource)nullable
items[].​source.​typerequiredstring

example "journal"

items[].​source.​idrequiredstring
items[].​source.​keyrequiredstringnullable
items[].​reversesSeqrequiredintegernullable
items[].​reversedBySeqrequiredintegernullable

The entry that reversed this one.

items[].​postedAtrequiredstring (date-time)
items[].​postedByrequiredobject (BooksActor)
items[].​postedBy.​kindrequiredstring (BooksActorKind)

One of: person, rule, link, system

items[].​postedBy.​idrequiredstring
items[].​postedBy.​versionrequiredintegernullable
items[].​viarequiredstring (BooksPostedVia)

One of: web, api, mcp, bank_rule, ai_accepted, import, system

items[].​actingFirmIdrequiredstring (uuid)nullable

The practice that posted it through its link.

items[].​practiceLinkIdrequiredstring (uuid)nullable
items[].​prevHashrequiredstringnullable
items[].​hashrequiredstring

example "sha256:…"

items[].​journalIdrequiredstring (uuid)nullable

The manual journal it posted from.

items[].​linesrequiredarray of BooksEntryLine
items[].​lines[].​lineIndexrequiredinteger
items[].​lines[].​accountIdrequiredstring (uuid)
items[].​lines[].​accountCoderequiredstring
items[].​lines[].​accountNamerequiredstring
items[].​lines[].​accountOwnerNamerequiredstring
items[].​lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

items[].​lines[].​descriptionrequiredstringnullable
items[].​lines[].​contactIdrequiredstring (uuid)nullable
items[].​lines[].​vatrequiredobject (BooksLineVat)nullable

VAT on a posted line, worked once at posting and never recomputed.

items[].​lines[].​vat.​vatCodeIdrequiredstring

example "S20"

items[].​lines[].​vat.​siderequiredstring (BooksVatSide)nullable

One of: sale, purchase

items[].​lines[].​vat.​netPencerequiredinteger

Integer pence (GBP).

items[].​lines[].​vat.​vatPencerequiredinteger

Integer pence (GBP).

items[].​lines[].​vat.​rateVersionrequiredstringnullable

example "S20@2011-01-04"

items[].​lines[].​vat.​taxPointrequiredstring (date)nullable

When it differs from the entry’s.

example "2026-03-31"

items[].​lines[].​vat.​cashBasisDaterequiredstring (date)nullable

example "2026-03-31"

items[].​lines[].​vat.​boxesrequiredarray of BooksVatBoxContribution
items[].​lines[].​vat.​boxes[].​boxrequiredinteger

example 1

items[].​lines[].​vat.​boxes[].​amountPencerequiredinteger

Integer pence (GBP).

items[].​lines[].​vat.​capitalGoodsrequiredbooleannullable
items[].​lines[].​vat.​frsRelevantGoodsrequiredbooleannullable
items[].​lines[].​vat.​frsOutsideSchemerequiredbooleannullable
nextBeforeSeqrequiredintegernullable

Pass as beforeSeq for the next (older) page; null on the last page.

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

Get a posted entry

GET/api/v1/books/entries/{entryId}

Scopes
books:read

Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/entries/{entryId}
NameInTypeDescription
entryIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (BooksEntry).

A posted entry. Posted entries never change: a correction is a reversal and a new entry. hash chains each entry to the one before.

200 OK response for GET /api/v1/books/entries/{entryId}
FieldTypeDescription
idrequiredstring (uuid)
seqrequiredinteger

Numbered from 1 per business, without gaps.

kindrequiredstring (BooksEntryKind)

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

daterequiredstring (date)

example "2026-03-31"

taxPointrequiredstring (date)nullable

example "2026-03-31"

descriptionrequiredstring
sourcerequiredobject (BooksEntrySource)nullable
source.​typerequiredstring

example "journal"

source.​idrequiredstring
source.​keyrequiredstringnullable
reversesSeqrequiredintegernullable
reversedBySeqrequiredintegernullable

The entry that reversed this one.

postedAtrequiredstring (date-time)
postedByrequiredobject (BooksActor)
postedBy.​kindrequiredstring (BooksActorKind)

One of: person, rule, link, system

postedBy.​idrequiredstring
postedBy.​versionrequiredintegernullable
viarequiredstring (BooksPostedVia)

One of: web, api, mcp, bank_rule, ai_accepted, import, system

actingFirmIdrequiredstring (uuid)nullable

The practice that posted it through its link.

practiceLinkIdrequiredstring (uuid)nullable
prevHashrequiredstringnullable
hashrequiredstring

example "sha256:…"

journalIdrequiredstring (uuid)nullable

The manual journal it posted from.

linesrequiredarray of BooksEntryLine
lines[].​lineIndexrequiredinteger
lines[].​accountIdrequiredstring (uuid)
lines[].​accountCoderequiredstring
lines[].​accountNamerequiredstring
lines[].​accountOwnerNamerequiredstring
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

lines[].​descriptionrequiredstringnullable
lines[].​contactIdrequiredstring (uuid)nullable
lines[].​vatrequiredobject (BooksLineVat)nullable

VAT on a posted line, worked once at posting and never recomputed.

lines[].​vat.​vatCodeIdrequiredstring

example "S20"

lines[].​vat.​siderequiredstring (BooksVatSide)nullable

One of: sale, purchase

lines[].​vat.​netPencerequiredinteger

Integer pence (GBP).

lines[].​vat.​vatPencerequiredinteger

Integer pence (GBP).

lines[].​vat.​rateVersionrequiredstringnullable

example "S20@2011-01-04"

lines[].​vat.​taxPointrequiredstring (date)nullable

When it differs from the entry’s.

example "2026-03-31"

lines[].​vat.​cashBasisDaterequiredstring (date)nullable

example "2026-03-31"

lines[].​vat.​boxesrequiredarray of BooksVatBoxContribution
lines[].​vat.​boxes[].​boxrequiredinteger

example 1

lines[].​vat.​boxes[].​amountPencerequiredinteger

Integer pence (GBP).

lines[].​vat.​capitalGoodsrequiredbooleannullable
lines[].​vat.​frsRelevantGoodsrequiredbooleannullable
lines[].​vat.​frsOutsideSchemerequiredbooleannullable

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

Reverse an entry

POST/api/v1/books/entries/{entryId}/reverse

Scopes
books:write
Retries
Send an Idempotency-Key to make retries safe.

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. For opening balances and adjustments posted without a journal: every line is negated, dated on the original’s date or the first open day after it. Void or amend a journal instead; change a bank line or invoice where it came from (409). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/entries/{entryId}/reverse
NameInTypeDescription
entryIdrequiredpathstring (uuid)
Idempotency-Keyheaderstring

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

1 to 255 characters

Request body

Optional. application/json: object (BooksReverseEntry).

Reverse an opening balances entry or an adjustment that isn’t a journal’s (void a journal instead).

Request body for POST /api/v1/books/entries/{entryId}/reverse
FieldTypeDescription
datestring (date)

Defaults to the original’s date, or the first open day after it.

example "2026-03-31"

descriptionstring

up to 500 characters

Responses

201 Created, application/json

Body: object (BooksEntry).

A posted entry. Posted entries never change: a correction is a reversal and a new entry. hash chains each entry to the one before.

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 journals

GET/api/v1/books/journals

Scopes
books:read

Newest first. Drafts carry the problems that stop them being posted. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/journals
NameInTypeDescription
statusquerystring

One of: draft, posted, voided

Responses

200 OK, application/json

Body: array of BooksJournal.

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

200 OK response for GET /api/v1/books/journals
FieldTypeDescription
[].​idrequiredstring (uuid)
[].​statusrequiredstring (BooksJournalStatus)

One of: draft, posted, voided

[].​kindrequiredstring (BooksJournalKind)

One of: journal, year_end_adjustment

[].​daterequiredstring (date)

example "2026-03-31"

[].​descriptionrequiredstring
[].​referencerequiredstringnullable
[].​linesrequiredarray of BooksJournalLine
[].​lines[].​accountIdrequiredstring (uuid)
[].​lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative. With VAT, the net.

[].​lines[].​descriptionstringnullable

up to 200 characters

[].​lines[].​vatobject (BooksJournalLineVat)nullable
[].​lines[].​vat.​vatCodeIdrequiredstring

example "S20"

[].​lines[].​vat.​sidestring (BooksVatSide)nullable

One of: sale, purchase

[].​lines[].​vat.​netPenceintegernullable

Integer pence (GBP).

Defaults to the line’s amount.

[].​lines[].​vat.​vatPenceintegernullable

Integer pence (GBP).

Worked from the rate when left out.

[].​lines[].​vat.​taxPointstring (date)nullable

example "2026-03-31"

[].​lines[].​vat.​capitalGoodsbooleannullable
[].​lines[].​vat.​frsRelevantGoodsbooleannullable
[].​lines[].​vat.​frsOutsideSchemebooleannullable
[].​lines[].​vat.​workedVatPenceintegernullable

Integer pence (GBP).

Read only: the VAT as posting would work it.

[].​debitsPencerequiredinteger

Integer pence (GBP).

[].​creditsPencerequiredinteger

Integer pence (GBP).

Positive: the sum of the credit lines.

[].​vatControlPencerequiredinteger

Integer pence (GBP).

What Tolvi will post to the VAT account for VAT on the lines (debit positive).

[].​differencePencerequiredinteger

Integer pence (GBP).

Debits less credits, including the VAT line: nil when it balances.

[].​problemsrequiredarray of BooksLedgerProblem

Why it can’t be posted yet (drafts only).

[].​problems[].​coderequiredstring

example "unbalanced"

[].​problems[].​messagerequiredstring
[].​problems[].​linerequiredintegernullable

Zero-based index of the line it is about.

[].​entryIdrequiredstring (uuid)nullable
[].​entrySeqrequiredintegernullable
[].​voidEntryIdrequiredstring (uuid)nullable
[].​createdByrequiredstring (uuid)nullable
[].​createdAtrequiredstring (date-time)
[].​updatedAtrequiredstring (date-time)
[].​postedAtrequiredstring (date-time)nullable
[].​voidedAtrequiredstring (date-time)nullable

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

Start a journal

POST/api/v1/books/journals

Scopes
books:write
Retries
Send an Idempotency-Key to make retries safe.

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. A draft touches nothing until it is posted. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/journals
NameInTypeDescription
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 (BooksCreateJournal).

Request body for POST /api/v1/books/journals
FieldTypeDescription
daterequiredstring (date)

example "2026-03-31"

descriptionstring

up to 500 characters

referencestringnullable

up to 60 characters

kindstring (BooksJournalKind)

journal (default) or year_end_adjustment.

One of: journal, year_end_adjustment

linesarray of BooksJournalLine
lines[].​accountIdrequiredstring (uuid)
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative. With VAT, the net.

lines[].​descriptionstringnullable

up to 200 characters

lines[].​vatobject (BooksJournalLineVat)nullable
lines[].​vat.​vatCodeIdrequiredstring

example "S20"

lines[].​vat.​sidestring (BooksVatSide)nullable

One of: sale, purchase

lines[].​vat.​netPenceintegernullable

Integer pence (GBP).

Defaults to the line’s amount.

lines[].​vat.​vatPenceintegernullable

Integer pence (GBP).

Worked from the rate when left out.

lines[].​vat.​taxPointstring (date)nullable

example "2026-03-31"

lines[].​vat.​capitalGoodsbooleannullable
lines[].​vat.​frsRelevantGoodsbooleannullable
lines[].​vat.​frsOutsideSchemebooleannullable
lines[].​vat.​workedVatPenceintegernullable

Integer pence (GBP).

Read only: the VAT as posting would work it.

Responses

201 Created, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

201 Created response for POST /api/v1/books/journals
FieldTypeDescription
idrequiredstring (uuid)
statusrequiredstring (BooksJournalStatus)

One of: draft, posted, voided

kindrequiredstring (BooksJournalKind)

One of: journal, year_end_adjustment

daterequiredstring (date)

example "2026-03-31"

descriptionrequiredstring
referencerequiredstringnullable
linesrequiredarray of BooksJournalLine
lines[].​accountIdrequiredstring (uuid)
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative. With VAT, the net.

lines[].​descriptionstringnullable

up to 200 characters

lines[].​vatobject (BooksJournalLineVat)nullable
lines[].​vat.​vatCodeIdrequiredstring

example "S20"

lines[].​vat.​sidestring (BooksVatSide)nullable

One of: sale, purchase

lines[].​vat.​netPenceintegernullable

Integer pence (GBP).

Defaults to the line’s amount.

lines[].​vat.​vatPenceintegernullable

Integer pence (GBP).

Worked from the rate when left out.

lines[].​vat.​taxPointstring (date)nullable

example "2026-03-31"

lines[].​vat.​capitalGoodsbooleannullable
lines[].​vat.​frsRelevantGoodsbooleannullable
lines[].​vat.​frsOutsideSchemebooleannullable
lines[].​vat.​workedVatPenceintegernullable

Integer pence (GBP).

Read only: the VAT as posting would work it.

debitsPencerequiredinteger

Integer pence (GBP).

creditsPencerequiredinteger

Integer pence (GBP).

Positive: the sum of the credit lines.

vatControlPencerequiredinteger

Integer pence (GBP).

What Tolvi will post to the VAT account for VAT on the lines (debit positive).

differencePencerequiredinteger

Integer pence (GBP).

Debits less credits, including the VAT line: nil when it balances.

problemsrequiredarray of BooksLedgerProblem

Why it can’t be posted yet (drafts only).

problems[].​coderequiredstring

example "unbalanced"

problems[].​messagerequiredstring
problems[].​linerequiredintegernullable

Zero-based index of the line it is about.

entryIdrequiredstring (uuid)nullable
entrySeqrequiredintegernullable
voidEntryIdrequiredstring (uuid)nullable
createdByrequiredstring (uuid)nullable
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)
postedAtrequiredstring (date-time)nullable
voidedAtrequiredstring (date-time)nullable

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

Get a journal

GET/api/v1/books/journals/{journalId}

Scopes
books:read

Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/journals/{journalId}
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

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).

Change a draft journal

PATCH/api/v1/books/journals/{journalId}

Scopes
books:write

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Posted journals are amended instead (409). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for PATCH /api/v1/books/journals/{journalId}
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Request body

Required. application/json: object (BooksUpdateJournal).

Change a draft. Only the fields sent change; lines replaces every line.

Request body for PATCH /api/v1/books/journals/{journalId}
FieldTypeDescription
datestring (date)

example "2026-03-31"

descriptionstring

up to 500 characters

referencestringnullable

up to 60 characters

kindstring (BooksJournalKind)

One of: journal, year_end_adjustment

linesarray of BooksJournalLine
lines[].​accountIdrequiredstring (uuid)
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative. With VAT, the net.

lines[].​descriptionstringnullable

up to 200 characters

lines[].​vatobject (BooksJournalLineVat)nullable
lines[].​vat.​vatCodeIdrequiredstring

example "S20"

lines[].​vat.​sidestring (BooksVatSide)nullable

One of: sale, purchase

lines[].​vat.​netPenceintegernullable

Integer pence (GBP).

Defaults to the line’s amount.

lines[].​vat.​vatPenceintegernullable

Integer pence (GBP).

Worked from the rate when left out.

lines[].​vat.​taxPointstring (date)nullable

example "2026-03-31"

lines[].​vat.​capitalGoodsbooleannullable
lines[].​vat.​frsRelevantGoodsbooleannullable
lines[].​vat.​frsOutsideSchemebooleannullable
lines[].​vat.​workedVatPenceintegernullable

Integer pence (GBP).

Read only: the VAT as posting would work it.

Responses

200 OK, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

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).

Discard a draft journal

DELETE/api/v1/books/journals/{journalId}

Scopes
books:write

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. A posted journal is never deleted: void it (409). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for DELETE /api/v1/books/journals/{journalId}
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Responses

204 No content

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

Post a journal

POST/api/v1/books/journals/{journalId}/post

Scopes
books:write

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. It must balance to the penny, use open accounts and be dated after any lock (422 lists every problem). VAT on lines is worked at the rate in force at the tax point and posted to the VAT account by Tolvi. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/journals/{journalId}/post
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

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).

Void a posted journal

POST/api/v1/books/journals/{journalId}/void

Scopes
books:write

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Its entry is reversed, dated on the journal’s date or the first open day after it. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/journals/{journalId}/void
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Request body

Optional. application/json: object (BooksVoidJournal).

Request body for POST /api/v1/books/journals/{journalId}/void
FieldTypeDescription
datestring (date)

Defaults to the journal’s date, or the first open day after it.

example "2026-03-31"

Responses

200 OK, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

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).

Amend a posted journal

POST/api/v1/books/journals/{journalId}/amend

Scopes
books:write

Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Tolvi reverses the posted entry and posts the journal as sent, in one step. Either is dated in the first open period if its own date is locked. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/journals/{journalId}/amend
NameInTypeDescription
journalIdrequiredpathstring (uuid)

Request body

Required. application/json: object (BooksAmendJournal).

The journal as it should have been. Tolvi reverses the posted entry and posts this, in one step.

Request body for POST /api/v1/books/journals/{journalId}/amend
FieldTypeDescription
daterequiredstring (date)

example "2026-03-31"

descriptionrequiredstring

up to 500 characters

referencestringnullable

up to 60 characters

linesrequiredarray of BooksJournalLine
lines[].​accountIdrequiredstring (uuid)
lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative. With VAT, the net.

lines[].​descriptionstringnullable

up to 200 characters

lines[].​vatobject (BooksJournalLineVat)nullable
lines[].​vat.​vatCodeIdrequiredstring

example "S20"

lines[].​vat.​sidestring (BooksVatSide)nullable

One of: sale, purchase

lines[].​vat.​netPenceintegernullable

Integer pence (GBP).

Defaults to the line’s amount.

lines[].​vat.​vatPenceintegernullable

Integer pence (GBP).

Worked from the rate when left out.

lines[].​vat.​taxPointstring (date)nullable

example "2026-03-31"

lines[].​vat.​capitalGoodsbooleannullable
lines[].​vat.​frsRelevantGoodsbooleannullable
lines[].​vat.​frsOutsideSchemebooleannullable
lines[].​vat.​workedVatPenceintegernullable

Integer pence (GBP).

Read only: the VAT as posting would work it.

Responses

200 OK, application/json

Body: object (BooksJournal).

A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.

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 the trial balance at a date

GET/api/v1/books/trial-balance

Scopes
books:read

Derived from posted entries, never stored. Debit positive, credit negative. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/trial-balance
NameInTypeDescription
includeZeroquerystring

One of: true, false

throughSeqqueryinteger

The ledger as it stood after this entry.

at least 0

yearStartquerystring (date)

Defaults to the start of the financial year containing asAt, from the business’s year end.

asAtquerystring (date)

Defaults to today.

Responses

200 OK, application/json

Body: object (BooksTrialBalance).

The trial balance at a date, derived from posted entries (nothing is stored). Profit and loss before the year start is in retained earnings or the capital account. throughSeq and ledgerHash pin exactly which entries it reflects.

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

example "2026-03-31"

yearStartrequiredstring (date)

example "2026-03-31"

throughSeqrequiredinteger
ledgerHashrequiredstringnullable
rowsrequiredarray of BooksTrialBalanceRow
rows[].​accountIdrequiredstring (uuid)
rows[].​coderequiredstring
rows[].​namerequiredstring
rows[].​ownerNamerequiredstring
rows[].​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

rows[].​ownerCategoryLabelrequiredstring
rows[].​classrequiredstring (BooksAccountClass)

One of: asset, liability, equity, income, expense

rows[].​normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

rows[].​leadLinerequiredstringnullable
rows[].​balancePencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

totalDebitsPencerequiredinteger

Integer pence (GBP).

totalCreditsPencerequiredinteger

Integer pence (GBP).

Positive: the sum of credit balances.

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

List changes since a ledger point

GET/api/v1/books/ledger/changes

Scopes
books:read

Postings made after throughSeq that change a balance on or before asAt. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/ledger/changes
NameInTypeDescription
asAtrequiredquerystring (date)

The period end it was taken for.

throughSeqrequiredqueryinteger

The ledger point a trial balance was taken at.

at least 0

Responses

200 OK, application/json

Body: object (BooksLedgerChanges).

Postings made after a ledger point (throughSeq) that change a balance on or before asAt: what explains a difference since a trial balance was taken.

200 OK response for GET /api/v1/books/ledger/changes
FieldTypeDescription
throughSeqrequiredinteger
asAtrequiredstring (date)

example "2026-03-31"

headSeqrequiredinteger

The latest entry now.

changesrequiredarray of BooksLedgerChange
changes[].​entryIdrequiredstring (uuid)
changes[].​seqrequiredinteger
changes[].​lineIndexrequiredinteger
changes[].​accountIdrequiredstring (uuid)
changes[].​accountCoderequiredstring
changes[].​daterequiredstring (date)

example "2026-03-31"

changes[].​descriptionrequiredstring
changes[].​amountPencerequiredinteger

Integer pence (GBP).

changes[].​postedAtrequiredstring (date-time)
changes[].​kindrequiredstring (BooksEntryKind)

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

changes[].​viarequiredstring (BooksPostedVia)

One of: web, api, mcp, bank_rule, ai_accepted, import, system

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

Check the ledger’s hash chain

GET/api/v1/books/ledger/integrity

Scopes
books:read

Re-walks every entry from the first: numbered without gaps, each unchanged since it was posted, each balanced. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksLedgerIntegrity).

The hash chain re-walked from the first entry: numbering without gaps, each entry unchanged since posting and balanced.

200 OK response for GET /api/v1/books/ledger/integrity
FieldTypeDescription
okrequiredboolean
entriesrequiredinteger
headSeqrequiredinteger
headHashrequiredstringnullable
problemrequiredobject (BooksLedgerIntegrityProblem)nullable
problem.​seqrequiredinteger
problem.​kindrequiredstring (BooksIntegrityProblemKind)

One of: sequence_gap, prev_hash_mismatch, hash_mismatch, unbalanced

problem.​messagerequiredstring

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

Get the period locks

GET/api/v1/books/locks

Scopes
books:read

The locks in force, their history and the first open date. Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/books/locks
NameInTypeDescription
datequerystring (date)

A date to check: dateProblem says why it can’t take an entry. Defaults to today.

Responses

200 OK, application/json

Body: object (BooksLocks).

The locks in force. owner: the business closed its books to a date (it or its practice can move it). accountant: the practice locked them after year-end sign-off (only it can reopen them). vatFiled: set by Tolvi when HMRC accepts a VAT return; never lifted.

200 OK response for GET /api/v1/books/locks
FieldTypeDescription
ownerrequiredobject (BooksLockState)nullable
owner.​throughrequiredstring (date)

Nothing new may be dated on or before this day.

example "2026-03-31"

owner.​atrequiredstring (date-time)
owner.​byKindrequiredstring (BooksLockBy)

One of: owner, practice, system

owner.​byNamerequiredstringnullable

The practice’s name, for an accountant’s lock.

owner.​linkIdrequiredstring (uuid)nullable
owner.​referencerequiredstringnullable
accountantrequiredobject (BooksLockState)nullable
accountant.​throughrequiredstring (date)

Nothing new may be dated on or before this day.

example "2026-03-31"

accountant.​atrequiredstring (date-time)
accountant.​byKindrequiredstring (BooksLockBy)

One of: owner, practice, system

accountant.​byNamerequiredstringnullable

The practice’s name, for an accountant’s lock.

accountant.​linkIdrequiredstring (uuid)nullable
accountant.​referencerequiredstringnullable
vatFiledrequiredobject (BooksLockState)nullable
vatFiled.​throughrequiredstring (date)

Nothing new may be dated on or before this day.

example "2026-03-31"

vatFiled.​atrequiredstring (date-time)
vatFiled.​byKindrequiredstring (BooksLockBy)

One of: owner, practice, system

vatFiled.​byNamerequiredstringnullable

The practice’s name, for an accountant’s lock.

vatFiled.​linkIdrequiredstring (uuid)nullable
vatFiled.​referencerequiredstringnullable
firstOpenDaterequiredstring (date)

example "2026-03-31"

daterequiredstring (date)

example "2026-03-31"

dateProblemrequiredstringnullable
eventsrequiredarray of BooksLockEvent
events[].​idrequiredstring (uuid)
events[].​kindrequiredstring (BooksLockKind)

One of: owner, vat_filed, accountant

events[].​actionrequiredstring (BooksLockAction)

One of: lock, unlock

events[].​throughrequiredstring (date)nullable

example "2026-03-31"

events[].​atrequiredstring (date-time)
events[].​byKindrequiredstring (BooksLockBy)

One of: owner, practice, system

events[].​byNamerequiredstringnullable
events[].​byUserIdrequiredstring (uuid)nullable
events[].​linkIdrequiredstring (uuid)nullable
events[].​reasonrequiredstringnullable
events[].​referencerequiredstringnullable

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

Lock or unlock the books

POST/api/v1/books/locks

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

Needs a signed-in person (never a token or connected app). The owner lock: the business’s owners and admins, or a linked practice that can post. The accountant’s year-end lock: only a linked practice, and only the practice that set it can reopen the year, with a reason. The VAT lock is set by Tolvi when HMRC accepts a return and can’t be changed here. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksChangeLock).

Lock the books through a date, or move a lock back (with through) or lift it (no through).

Request body for POST /api/v1/books/locks
FieldTypeDescription
kindrequiredstring (BooksPersonLockKind)

owner: the business’s own lock. accountant: the practice’s year-end lock (practices only).

One of: owner, accountant

actionrequiredstring (BooksLockAction)

One of: lock, unlock

throughstring (date)nullable

example "2026-03-31"

reasonstring

Needed to reopen a year the accountant locked.

up to 500 characters

referencestring

e.g. the engagement behind a year-end lock.

up to 100 characters

Responses

200 OK, application/json

Body: object (BooksLocks).

The locks in force. owner: the business closed its books to a date (it or its practice can move it). accountant: the practice locked them after year-end sign-off (only it can reopen them). vatFiled: set by Tolvi when HMRC accepts a VAT return; never lifted.

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 opening balances in force

GET/api/v1/books/opening-balances

Scopes
books:read

The opening entry in force, if any, the suggested start date, and the accounts each plain-English question posts to. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksOpeningStatus).

Whether the books have a start, and what the opening balances screen needs.

200 OK response for GET /api/v1/books/opening-balances
FieldTypeDescription
suggestedStartDaterequiredstring (date)

The first day of this financial year.

example "2026-03-31"

standingrequiredobject (BooksOpeningStanding)nullable

The opening entry in force.

standing.​entryIdrequiredstring (uuid)
standing.​seqrequiredinteger
standing.​entryDaterequiredstring (date)

example "2026-03-31"

standing.​startDaterequiredstring (date)

The first day the books cover.

example "2026-03-31"

standing.​fromWorkingPapersrequiredboolean

Posted from a final trial balance in Working Papers.

standing.​postedAtrequiredstring (date-time)
standing.​linesrequiredarray of BooksOpeningEntryLine
standing.​lines[].​accountIdrequiredstring (uuid)
standing.​lines[].​accountCoderequiredstring
standing.​lines[].​accountNamerequiredstring
standing.​lines[].​ownerNamerequiredstring
standing.​lines[].​normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

standing.​lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

standing.​lines[].​contactNamerequiredstringnullable

The customer or supplier, on a control account line split by unpaid invoice or bill.

standing.​suspensePencerequiredinteger

Integer pence (GBP).

standing.​unpaidInvoicesrequiredarray of BooksOpeningStandingInvoice
standing.​unpaidInvoices[].​idrequiredstring (uuid)
standing.​unpaidInvoices[].​numberrequiredstring
standing.​unpaidInvoices[].​customerNamerequiredstring
standing.​unpaidInvoices[].​amountPencerequiredinteger

Integer pence (GBP).

standing.​unpaidInvoices[].​outstandingPencerequiredinteger

Integer pence (GBP).

standing.​unpaidBillsrequiredarray of BooksOpeningStandingBill
standing.​unpaidBills[].​idrequiredstring (uuid)
standing.​unpaidBills[].​referencerequiredstring
standing.​unpaidBills[].​supplierNamerequiredstring
standing.​unpaidBills[].​amountPencerequiredinteger

Integer pence (GBP).

standing.​unpaidBills[].​outstandingPencerequiredinteger

Integer pence (GBP).

guidedrequiredobject (BooksOpeningGuidedAccounts)

The accounts each plain-English question posts to.

guided.​bankrequiredarray of BooksOpeningAccountRef
guided.​bank[].​coderequiredstring
guided.​bank[].​namerequiredstring
guided.​bank[].​ownerNamerequiredstring
guided.​debtorsrequiredobject (BooksOpeningAccountRef)nullable
guided.​debtors.​coderequiredstring
guided.​debtors.​namerequiredstring
guided.​debtors.​ownerNamerequiredstring
guided.​creditorsrequiredobject (BooksOpeningAccountRef)nullable
guided.​creditors.​coderequiredstring
guided.​creditors.​namerequiredstring
guided.​creditors.​ownerNamerequiredstring
guided.​vatrequiredobject (BooksOpeningAccountRef)nullable
guided.​vat.​coderequiredstring
guided.​vat.​namerequiredstring
guided.​vat.​ownerNamerequiredstring
guided.​loanrequiredobject (BooksOpeningAccountRef)nullable
guided.​loan.​coderequiredstring
guided.​loan.​namerequiredstring
guided.​loan.​ownerNamerequiredstring
guided.​worthrequiredobject (BooksOpeningAccountRef)nullable

Where the difference goes when it is what the business was worth.

guided.​worth.​coderequiredstring
guided.​worth.​namerequiredstring
guided.​worth.​ownerNamerequiredstring
vatRegisteredrequiredboolean
vatSchemerequiredstringnullable
canSetUprequiredboolean

This person can post and reverse opening balances.

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

Post opening balances

POST/api/v1/books/opening-balances

Scopes
books:write
Retries
Send an Idempotency-Key to make retries safe.

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). One entry dated the day before the books start. Every balance must have an account (422 lists any that don’t); a difference goes to suspense. Refused while earlier opening balances stand (409). Part of the books product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/books/opening-balances
NameInTypeDescription
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 (BooksOpeningBalancesInput).

Opening balances from a trial balance (as accounts, or the CSV text of an export), at the date the books start.

Request body for POST /api/v1/books/opening-balances
FieldTypeDescription
conversionDaterequiredstring (date)

The first day the books cover; the entry is dated the day before.

example "2026-03-31"

accountsarray of object
accounts[].​coderequiredstring
accounts[].​namestring
accounts[].​balancePencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

accounts[].​leadLinestringnullable
csvstring

A trial balance export as CSV text (code, name, debit, credit or balance).

mappingobject

Source code to an account code in these books.

differenceTostring (BooksOpeningDifferenceTo)

suspense (the default): a difference is an error for the accountant to clear. equity: it is what the business was worth (capital or reserves).

One of: suspense, equity

unpaidInvoicesarray of BooksOpeningUnpaidInvoiceInput

Invoices issued before the books start and not yet paid. They are part of the debtors balance and can be paid and chased like any other.

unpaidInvoices[].​customerIdstring (uuid)
unpaidInvoices[].​customerNamestring

up to 200 characters

unpaidInvoices[].​numberrequiredstring

The number it was issued with, outside Tolvi’s own series.

up to 60 characters

unpaidInvoices[].​issueDaterequiredstring (date)

example "2026-03-31"

unpaidInvoices[].​dueDatestring (date)

Defaults to the business’s usual payment terms.

example "2026-03-31"

unpaidInvoices[].​amountPencerequiredinteger

Integer pence (GBP).

What is still owed, including any VAT.

unpaidBillsarray of BooksOpeningUnpaidBillInput

Bills dated before the books start and not yet paid. They are part of the creditors balance and can be paid and matched like any other, with no VAT breakdown.

unpaidBills[].​supplierIdstring (uuid)
unpaidBills[].​supplierNamestring

up to 200 characters

unpaidBills[].​referencerequiredstring

The supplier’s own invoice number.

up to 60 characters

unpaidBills[].​billDaterequiredstring (date)

example "2026-03-31"

unpaidBills[].​dueDatestring (date)

Defaults to the supplier’s payment terms, or 30 days.

example "2026-03-31"

unpaidBills[].​amountPencerequiredinteger

Integer pence (GBP).

What is still owed, including any VAT.

Responses

201 Created, application/json

Body: object (BooksOpeningBalancesPosted).

201 Created response for POST /api/v1/books/opening-balances
FieldTypeDescription
entryrequiredobject (BooksEntry)

A posted entry. Posted entries never change: a correction is a reversal and a new entry. hash chains each entry to the one before.

entry.​idrequiredstring (uuid)
entry.​seqrequiredinteger

Numbered from 1 per business, without gaps.

entry.​kindrequiredstring (BooksEntryKind)

One of: bank, invoice, credit_note, bill, bill_credit, receipt, expense_claim, journal, opening, reversal, year_end_adjustment, vat_settlement, fx_revaluation

entry.​daterequiredstring (date)

example "2026-03-31"

entry.​taxPointrequiredstring (date)nullable

example "2026-03-31"

entry.​descriptionrequiredstring
entry.​sourcerequiredobject (BooksEntrySource)nullable
entry.​source.​typerequiredstring

example "journal"

entry.​source.​idrequiredstring
entry.​source.​keyrequiredstringnullable
entry.​reversesSeqrequiredintegernullable
entry.​reversedBySeqrequiredintegernullable

The entry that reversed this one.

entry.​postedAtrequiredstring (date-time)
entry.​postedByrequiredobject (BooksActor)
entry.​postedBy.​kindrequiredstring (BooksActorKind)

One of: person, rule, link, system

entry.​postedBy.​idrequiredstring
entry.​postedBy.​versionrequiredintegernullable
entry.​viarequiredstring (BooksPostedVia)

One of: web, api, mcp, bank_rule, ai_accepted, import, system

entry.​actingFirmIdrequiredstring (uuid)nullable

The practice that posted it through its link.

entry.​practiceLinkIdrequiredstring (uuid)nullable
entry.​prevHashrequiredstringnullable
entry.​hashrequiredstring

example "sha256:…"

entry.​journalIdrequiredstring (uuid)nullable

The manual journal it posted from.

entry.​linesrequiredarray of BooksEntryLine
entry.​lines[].​lineIndexrequiredinteger
entry.​lines[].​accountIdrequiredstring (uuid)
entry.​lines[].​accountCoderequiredstring
entry.​lines[].​accountNamerequiredstring
entry.​lines[].​accountOwnerNamerequiredstring
entry.​lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

entry.​lines[].​descriptionrequiredstringnullable
entry.​lines[].​contactIdrequiredstring (uuid)nullable
entry.​lines[].​vatrequiredobject (BooksLineVat)nullable

VAT on a posted line, worked once at posting and never recomputed.

entry.​lines[].​vat.​vatCodeIdrequiredstring

example "S20"

entry.​lines[].​vat.​siderequiredstring (BooksVatSide)nullable

One of: sale, purchase

entry.​lines[].​vat.​netPencerequiredinteger

Integer pence (GBP).

entry.​lines[].​vat.​vatPencerequiredinteger

Integer pence (GBP).

entry.​lines[].​vat.​rateVersionrequiredstringnullable

example "S20@2011-01-04"

entry.​lines[].​vat.​taxPointrequiredstring (date)nullable

When it differs from the entry’s.

example "2026-03-31"

entry.​lines[].​vat.​cashBasisDaterequiredstring (date)nullable

example "2026-03-31"

entry.​lines[].​vat.​boxesrequiredarray of BooksVatBoxContribution
entry.​lines[].​vat.​boxes[].​boxrequiredinteger

example 1

entry.​lines[].​vat.​boxes[].​amountPencerequiredinteger

Integer pence (GBP).

entry.​lines[].​vat.​capitalGoodsrequiredbooleannullable
entry.​lines[].​vat.​frsRelevantGoodsrequiredbooleannullable
entry.​lines[].​vat.​frsOutsideSchemerequiredbooleannullable
suspensePencerequiredinteger

Integer pence (GBP).

warningsrequiredarray of string

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

Preview opening balances

POST/api/v1/books/opening-balances/preview

Scopes
books:write

The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Where each balance would go and the entry that would be posted. Nothing is saved. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksOpeningBalancesInput).

Opening balances from a trial balance (as accounts, or the CSV text of an export), at the date the books start.

The fields are as shown above.

Responses

200 OK, application/json

Body: object (BooksOpeningBalancesPreview).

Where each balance would go, the entry that would be posted, and anything that must be mapped first.

200 OK response for POST /api/v1/books/opening-balances/preview
FieldTypeDescription
conversionDaterequiredstring (date)

example "2026-03-31"

entryDaterequiredstring (date)

example "2026-03-31"

planrequiredarray of BooksOpeningPlanLine
plan[].​sourceCoderequiredstring
plan[].​sourceNamerequiredstring
plan[].​balancePencerequiredinteger

Integer pence (GBP).

plan[].​targetCoderequiredstring
plan[].​targetNamerequiredstring
plan[].​viarequiredstring (BooksOpeningPlanVia)

One of: mapping, code, lead_line

unmappedrequiredarray of BooksOpeningUnmapped
unmapped[].​coderequiredstring
unmapped[].​namerequiredstring
unmapped[].​balancePencerequiredinteger

Integer pence (GBP).

unmapped[].​leadLinerequiredstringnullable
linesrequiredarray of BooksOpeningEntryLine
lines[].​accountIdrequiredstring (uuid)
lines[].​accountCoderequiredstring
lines[].​accountNamerequiredstring
lines[].​ownerNamerequiredstring
lines[].​normalBalancerequiredstring (BooksNormalBalance)

One of: debit, credit

lines[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive, credit negative.

lines[].​contactNamerequiredstringnullable

The customer or supplier, on a control account line split by unpaid invoice or bill.

suspensePencerequiredinteger

Integer pence (GBP).

What went to suspense to make it balance (debit positive).

equityPencerequiredinteger

Integer pence (GBP).

What went to capital or reserves to make it balance (debit positive).

warningsrequiredarray of string
problemsrequiredarray of string

What stops it being posted, in words.

unpaidInvoicesrequiredarray of BooksOpeningUnpaidInvoice
unpaidInvoices[].​customerNamerequiredstring
unpaidInvoices[].​newCustomerrequiredboolean

The customer will be added.

unpaidInvoices[].​numberrequiredstring
unpaidInvoices[].​issueDaterequiredstring (date)

example "2026-03-31"

unpaidInvoices[].​dueDaterequiredstring (date)

example "2026-03-31"

unpaidInvoices[].​amountPencerequiredinteger

Integer pence (GBP).

unpaidBillsrequiredarray of BooksOpeningUnpaidBill
unpaidBills[].​supplierNamerequiredstring
unpaidBills[].​newSupplierrequiredboolean

The supplier will be added.

unpaidBills[].​referencerequiredstring
unpaidBills[].​billDaterequiredstring (date)

example "2026-03-31"

unpaidBills[].​dueDaterequiredstring (date)

example "2026-03-31"

unpaidBills[].​amountPencerequiredinteger

Integer pence (GBP).

alreadyPostedrequiredboolean

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

Get the getting-started checklist

GET/api/v1/books/getting-started

Scopes
books:read

Six steps for a new business, each ticked from real data: business details, a bank, starting balances, how invoices look, VAT and an accountant. Part of the books product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (BooksGettingStarted).

The new business checklist, worked out from the business’s own data on every read.

200 OK response for GET /api/v1/books/getting-started
FieldTypeDescription
stepsrequiredarray of BooksGettingStartedStep
steps[].​keyrequiredstring (BooksGettingStartedKey)

One of: details, bank, opening, invoices, vat, accountant

steps[].​labelrequiredstring
steps[].​donerequiredboolean
steps[].​detailrequiredstringnullable

How it was done, when that needs saying.

doneCountrequiredinteger
completerequiredboolean

Every step is done.

hiddenrequiredboolean

The owner hid the list from Home.

notVatRegisteredrequiredboolean

The business said it isn’t registered for VAT.

noOpeningBalancesrequiredboolean

The business said it has nothing to bring forward.

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

Answer or hide the getting-started checklist

PUT/api/v1/books/getting-started

Scopes
books:write

Hide the list or bring it back, and the two answers only a person can give: not registered for VAT, and nothing to bring forward. The business’s owners and admins, or a practice with a link that can post. Part of the books product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (BooksUpdateGettingStarted).

Answers only a person can give. The ticks themselves come from the books.

Request body for PUT /api/v1/books/getting-started
FieldTypeDescription
hiddenboolean

Hide the list from Home, or bring it back.

notVatRegisteredboolean

The business isn’t registered for VAT, so that step is done.

noOpeningBalancesboolean

A brand-new business with nothing to bring forward, so the starting balances step is done.

Responses

200 OK, application/json

Body: object (BooksGettingStarted).

The new business checklist, worked out from the business’s own data on every read.

The fields are as shown above.

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