Clients
19 operations in the Tolvi API, version 1. Paths are relative to https://api.tolvi.co.uk. Every amount is integer pence.
List a client’s links
GET/api/v1/clients/{clientId}/links
- Scopes
clients:read
Companies this person is connected with, or people connected with this company.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ClientLinkList).
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ClientLink | |
items[].idrequired | string (uuid) | |
items[].personClientIdrequired | string (uuid) | |
items[].personNamerequired | string | |
items[].companyClientIdrequired | string (uuid) | |
items[].companyNamerequired | string | |
items[].isDirectorrequired | boolean | |
items[].isShareholderrequired | boolean | |
items[].shareholdingBpsrequired | integernullable | |
items[].nameInCompanyRecordsrequired | stringnullable | |
items[].createdAtrequired | string (date-time) |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Link a person and a company
POST/api/v1/clients/{clientId}/links
- Scopes
clients:write
Both are this firm’s clients; the company must be a limited company. A link only ever produces suggestions.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Request body
Required. application/json: object (CreateClientLinkRequest).
A person is a director or shareholder of a company. Both are clients of the firm.
| Field | Type | Description |
|---|---|---|
otherClientIdrequired | string (uuid) | |
thisClientIsrequired | string (ClientLinkSide) | One of: |
isDirector | boolean | |
isShareholder | boolean | |
shareholdingBps | integernullable | Share of the dividends, in basis points: 5000 is 50%. |
nameInCompanyRecords | stringnullable | The name on the company’s accounts and CT600A, if it isn’t the client’s. |
Responses
201 Created, application/json
Body: object (ClientLink).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
personClientIdrequired | string (uuid) | |
personNamerequired | string | |
companyClientIdrequired | string (uuid) | |
companyNamerequired | string | |
isDirectorrequired | boolean | |
isShareholderrequired | boolean | |
shareholdingBpsrequired | integernullable | |
nameInCompanyRecordsrequired | stringnullable | |
createdAtrequired | string (date-time) |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Change a link
PATCH/api/v1/clients/{clientId}/links/{linkId}
- Scopes
clients:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) | |
linkIdrequired | path | string (uuid) |
Request body
Required. application/json: object (UpdateClientLinkRequest).
| Field | Type | Description |
|---|---|---|
isDirector | boolean | |
isShareholder | boolean | |
shareholdingBps | integernullable | |
nameInCompanyRecords | stringnullable |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Remove a link
DELETE/api/v1/clients/{clientId}/links/{linkId}
- Scopes
clients:write
Figures already accepted stay where they are.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) | |
linkIdrequired | path | string (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).
What a linked client’s other work suggests here
GET/api/v1/cross-product-suggestions
- Scopes
clients:read
Reads only, and only from products this person holds. Each comes with its source.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | query | string (uuid) | The return or set of accounts. |
productrequired | query | string | One of: |
Responses
200 OK, application/json
Body: object (CrossProductSuggestions).
| Field | Type | Description |
|---|---|---|
itemsrequired | array of CrossProductSuggestion | |
items[].keyrequired | string | |
items[].kindrequired | string (CrossProductSuggestionKind) | One of: |
items[].headlinerequired | string | |
items[].sourcerequired | string | Where it comes from, in words: product, client and period. |
items[].noterequired | string | What to check first. |
items[].suggestedPencerequired | integernullable | The suggested figure in integer pence. Null when it can’t be worked out, such as with no shareholding on the link. |
items[].currentPencerequired | integernullable | What the target holds now, in integer pence. |
items[].writesFigurerequired | boolean | Accepting writes a figure to the target. If false, accepting only records that a person has dealt with it. |
items[].targetrequired | stringnullable | The box or field it would change. |
items[].fingerprintrequired | string | |
decisionsrequired | array of CrossProductDecision | What people have decided already, kept for the record. |
decisions[].keyrequired | string | |
decisions[].decisionrequired | string (CrossProductDecisionKind) | One of: |
decisions[].amountPencerequired | integernullable | Integer pence (GBP). |
decisions[].sourcerequired | string | |
decisions[].decidedByNamerequired | stringnullable | |
decisions[].decidedAtrequired | string (date-time) | |
hiddenSourcesrequired | integer | Sources this person can’t see because they don’t hold that product, so what’s from them isn’t shown. |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Accept or dismiss a suggestion
POST/api/v1/cross-product-suggestions/decide
- Scopes
clients:read- Access
- A signed-in Tolvi session only, never an API token.
A signed-in person only, never an API key or connected assistant. Accepting writes through the target product’s own save, so an approved return goes back to draft. The decision is kept. A suggestion comes back if its source changes.
Request body
Required. application/json: object (DecideCrossProductSuggestionRequest).
| Field | Type | Description |
|---|---|---|
productrequired | string (CrossProductTarget) | One of: |
idrequired | string (uuid) | |
keyrequired | string | |
fingerprintrequired | string | |
decisionrequired | string (CrossProductDecisionKind) | One of: |
amountPence | integer | Integer pence: what to put in, if the person changed the figure. |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
List or search clients
GET/api/v1/clients
- Scopes
clients:read
Sorted by name. Each row has the latest engagement’s partner and manager, the bookkeeping connection and the next filing deadline.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer | 1 to 100; default 50 |
cursor | query | string | |
status | query | string (ClientStatus) | One of: |
connection | query | string (ClientConnectionState) | One of: |
yearEndMonth | query | integer | Year end month (the client’s own, or its latest engagement’s). 1 to 12 |
entityType | query | string (EntityType) | One of: |
software | query | string (Software) | One of: |
manager | query | string (uuid) | |
partner | query | string (uuid) | Partner on any of the client’s engagements. |
q | query | string | Part of the client name or company number. up to 100 characters |
Responses
200 OK, application/json
Body: object (ClientPage).
| Field | Type | Description |
|---|---|---|
rowsrequired | array of Client | |
rows[].idrequired | string (uuid) | |
rows[].firmIdrequired | string (uuid) | |
rows[].namerequired | string | example "Hartley Joinery Ltd" |
rows[].entityTyperequired | string (EntityType) | One of: |
rows[].companyNumberrequired | stringnullable | Companies House number. example "01234567" |
rows[].yearEndDayrequired | integernullable | Financial year end day (with yearEndMonth); null when not known. 1 to 31 |
rows[].yearEndMonthrequired | integernullable | Financial year end month (1-12). 1 to 12 |
rows[].createdAtrequired | string (date-time) | |
rows[].status | string (ClientStatus) | Prospect, active or former. One of: |
rows[].latestPeriodEnd | string (date)nullable | Lists only: the period end of the client’s latest engagement (null when it has none), so a year end can be shown when yearEndDay/yearEndMonth are not set. example "2026-03-31" |
rows[].partnerId | string (uuid)nullable | Lists only: the partner on the client’s latest engagement. |
rows[].managerId | string (uuid)nullable | Lists only: the manager on the client’s latest engagement. |
rows[].connection | string (ClientConnectionState) | Lists only: connected (Tolvi can read the books), reconnect (access expired or removed), error (the last call failed) or not_connected (manual upload). One of: |
rows[].connectionProvider | stringnullable | Lists only: the client’s source: connected software (xero, quickbooks, sage or freeagent), or tolvi_books when the client’s books are in Tolvi Books and that is the source in use. example "xero" |
rows[].nextDueDate | string (date)nullable | Lists only: the earliest filing deadline among engagements not yet complete. example "2026-03-31" |
nextCursorrequired | stringnullable | Opaque cursor for the next page (pass as |
pageSizerequired | integer | The page size that was used. 1 to 100 |
totalrequired | integer | Clients matching the search and filters (all pages). |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Create a client
POST/api/v1/clients
- Scopes
clients:write- Retries
- Send an
Idempotency-Keyto make retries safe.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | 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 (CreateClientRequest).
| Field | Type | Description |
|---|---|---|
namerequired | string | 1 to 200 characters |
entityTyperequired | string (EntityType) | One of: |
companyNumber | stringnullable | Companies House number (upper-cased on save). pattern ^(?:[0-9]{8}|[A-Z]{2}[0-9]{6})$ |
yearEndDay | integernullable | Financial year end day; send with yearEndMonth. 1 to 31 |
yearEndMonth | integernullable | Financial year end month. 1 to 12 |
Responses
201 Created, application/json
Body: object (Client).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
firmIdrequired | string (uuid) | |
namerequired | string | example "Hartley Joinery Ltd" |
entityTyperequired | string (EntityType) | One of: |
companyNumberrequired | stringnullable | Companies House number. example "01234567" |
yearEndDayrequired | integernullable | Financial year end day (with yearEndMonth); null when not known. 1 to 31 |
yearEndMonthrequired | integernullable | Financial year end month (1-12). 1 to 12 |
createdAtrequired | string (date-time) | |
status | string (ClientStatus) | Prospect, active or former. One of: |
latestPeriodEnd | string (date)nullable | Lists only: the period end of the client’s latest engagement (null when it has none), so a year end can be shown when yearEndDay/yearEndMonth are not set. example "2026-03-31" |
partnerId | string (uuid)nullable | Lists only: the partner on the client’s latest engagement. |
managerId | string (uuid)nullable | Lists only: the manager on the client’s latest engagement. |
connection | string (ClientConnectionState) | Lists only: connected (Tolvi can read the books), reconnect (access expired or removed), error (the last call failed) or not_connected (manual upload). One of: |
connectionProvider | stringnullable | Lists only: the client’s source: connected software (xero, quickbooks, sage or freeagent), or tolvi_books when the client’s books are in Tolvi Books and that is the source in use. example "xero" |
nextDueDate | string (date)nullable | Lists only: the earliest filing deadline among engagements not yet complete. example "2026-03-31" |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 409 Conflict, 422 Unprocessable content, 429 Too many requests, as problem details (application/problem+json).
Find existing clients a new one may duplicate
GET/api/v1/clients/duplicates
- Scopes
clients:read
Call before creating a client. Matches the name ignoring case, punctuation and spacing ("&" = "and", "Limited" = "Ltd"), and the Companies House number when given. Advisory: creating a client is never blocked, so show the matches and let the person open one or add anyway.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
companyNumber | query | string | The new client’s Companies House number. up to 8 characters |
name | query | string | The new client’s name. up to 200 characters |
Responses
200 OK, application/json
Body: object (DuplicateClients).
| Field | Type | Description |
|---|---|---|
matchesrequired | array of DuplicateClient | |
matches[].clientrequired | object (Client) | |
matches[].client.idrequired | string (uuid) | |
matches[].client.firmIdrequired | string (uuid) | |
matches[].client.namerequired | string | example "Hartley Joinery Ltd" |
matches[].client.entityTyperequired | string (EntityType) | One of: |
matches[].client.companyNumberrequired | stringnullable | Companies House number. example "01234567" |
matches[].client.yearEndDayrequired | integernullable | Financial year end day (with yearEndMonth); null when not known. 1 to 31 |
matches[].client.yearEndMonthrequired | integernullable | Financial year end month (1-12). 1 to 12 |
matches[].client.createdAtrequired | string (date-time) | |
matches[].client.status | string (ClientStatus) | Prospect, active or former. One of: |
matches[].client.latestPeriodEnd | string (date)nullable | Lists only: the period end of the client’s latest engagement (null when it has none), so a year end can be shown when yearEndDay/yearEndMonth are not set. example "2026-03-31" |
matches[].client.partnerId | string (uuid)nullable | Lists only: the partner on the client’s latest engagement. |
matches[].client.managerId | string (uuid)nullable | Lists only: the manager on the client’s latest engagement. |
matches[].client.connection | string (ClientConnectionState) | Lists only: connected (Tolvi can read the books), reconnect (access expired or removed), error (the last call failed) or not_connected (manual upload). One of: |
matches[].client.connectionProvider | stringnullable | Lists only: the client’s source: connected software (xero, quickbooks, sage or freeagent), or tolvi_books when the client’s books are in Tolvi Books and that is the source in use. example "xero" |
matches[].client.nextDueDate | string (date)nullable | Lists only: the earliest filing deadline among engagements not yet complete. example "2026-03-31" |
matches[].matchedOnrequired | array of DuplicateClientMatch | name: the same name ignoring case, punctuation and spacing ("&" = "and", "Limited" = "Ltd"); company_number: the same Companies House number. One of: |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
List a client’s own checklist steps
GET/api/v1/clients/{clientId}/checklist-steps
- Scopes
clients:read
Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: array of ClientChecklistStep.
| Field | Type | Description |
|---|---|---|
[].idrequired | string (uuid) | |
[].sectionCoderequired | string | |
[].textrequired | string | |
[].createdAtrequired | string (date-time) |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Add a checklist step for this client
POST/api/v1/clients/{clientId}/checklist-steps
- Scopes
clients:write- Retries
- Send an
Idempotency-Keyto make retries safe.
Added to the section’s checklist on each new engagement. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) | |
Idempotency-Key | header | string | 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 (CreateClientChecklistStep).
| Field | Type | Description |
|---|---|---|
sectionCoderequired | string | |
textrequired | string | 1 to 500 characters |
Responses
201 Created, application/json
Body: object (ClientChecklistStep).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
sectionCoderequired | string | |
textrequired | string | |
createdAtrequired | string (date-time) |
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).
Get a client with its settings, notes and year-end history
GET/api/v1/clients/{clientId}
- Scopes
clients:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ClientDetail).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
firmIdrequired | string (uuid) | |
namerequired | string | |
entityTyperequired | string (EntityType) | One of: |
companyNumberrequired | stringnullable | |
yearEndDayrequired | integernullable | Financial year end day; null when not known. 1 to 31 |
yearEndMonthrequired | integernullable | 1 to 12 |
createdAtrequired | string (date-time) | |
partnerIdrequired | string (uuid)nullable | From the latest engagement. |
managerIdrequired | string (uuid)nullable | |
preparerIdrequired | string (uuid)nullable | From the latest engagement. |
reviewerIdrequired | string (uuid)nullable | From the latest engagement. |
softwarerequired | string (Software) | One of: |
syncStaterequired | string (SyncState) | One of: |
overridesrequired | object (ClientOverrides) | A client’s settings that differ from the firm’s (null: use the firm default). |
overrides.riskrequired | string (RiskLevel)nullable | One of: |
overrides.workflowTemplateIdrequired | stringnullable | |
overrides.thresholdAbsPencerequired | integernullable | Integer pence (GBP). |
overrides.thresholdPctrequired | integernullable | |
overrides.materialityPencerequired | integernullable | Integer pence (GBP). |
overrides.deadlineOverriderequired | string (date)nullable | e.g. an extension or a changed accounting reference date. example "2026-03-31" |
overrides.syncIgnoreUnderPencerequired | integernullable | Integer pence (GBP). |
overrides.syncExcludeCodes | array of stringnullable | Account codes the sign-off check leaves out for this client. Always present in responses. up to 200 items |
overrides.syncOnChange | string (SyncOnChange)nullable | What the sign-off check does when this client’s books change. Always present in responses. One of: |
overrideCountrequired | integer | |
notesrequired | string | |
extraChecklistStepsrequired | array of ClientStepRef | |
extraChecklistSteps[].idrequired | string (uuid) | |
extraChecklistSteps[].sectionCoderequired | string | |
extraChecklistSteps[].textrequired | string | |
extraChecklistSteps[].createdAtrequired | string (date-time) | |
engagementsrequired | array of ClientEngagement | Year-end history, newest first. |
engagements[].idrequired | string (uuid) | |
engagements[].periodStartrequired | string (date) | example "2026-03-31" |
engagements[].periodEndrequired | string (date) | example "2026-03-31" |
engagements[].dueDaterequired | string (date) | example "2026-03-31" |
engagements[].statusrequired | string (EngagementStatus) | One of: |
engagements[].stageNamerequired | string | |
engagements[].filedOnrequired | string (date)nullable | example "2026-03-31" |
engagements[].preparerIdrequired | string (uuid)nullable | |
engagements[].reviewerIdrequired | string (uuid)nullable | |
engagements[].roundsrequired | integer | Times sent back by a reviewer (amendment rounds). at least 0 |
engagements[].openReviewPointsrequired | integer | at least 0 |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
List the client’s remembered mappings
GET/api/v1/clients/{clientId}/mappings
- Scopes
clients:read
Changing an account’s mapping in section B remembers it for the client; next year it is applied ahead of the firm rules.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: array of ClientMapping.
A remembered mapping: applied to this client’s code ahead of the firm rules.
| Field | Type | Description |
|---|---|---|
[].coderequired | string | |
[].namerequired | stringnullable | The account’s name on the latest trial balance that has it. |
[].lineIdrequired | string (LeadLineId) | One of: |
[].updatedAtrequired | string (date-time) |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Get the client’s overrides of the firm settings
GET/api/v1/clients/{clientId}/settings
- Scopes
clients:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ClientOverrides).
A client’s settings that differ from the firm’s (null: use the firm default).
| Field | Type | Description |
|---|---|---|
riskrequired | string (RiskLevel)nullable | One of: |
workflowTemplateIdrequired | stringnullable | |
thresholdAbsPencerequired | integernullable | Integer pence (GBP). |
thresholdPctrequired | integernullable | |
materialityPencerequired | integernullable | Integer pence (GBP). |
deadlineOverriderequired | string (date)nullable | e.g. an extension or a changed accounting reference date. example "2026-03-31" |
syncIgnoreUnderPencerequired | integernullable | Integer pence (GBP). |
syncExcludeCodes | array of stringnullable | Account codes the sign-off check leaves out for this client. Always present in responses. up to 200 items |
syncOnChange | string (SyncOnChange)nullable | What the sign-off check does when this client’s books change. Always present in responses. One of: |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Change the client’s overrides
PATCH/api/v1/clients/{clientId}/settings
- Scopes
clients:write- Role
- Manager or above
Send only what changes; null goes back to the firm default. Used by engagements started from now on.
Needs the Manager role or above.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Request body
Required. application/json: object (ClientOverrides).
A client’s settings that differ from the firm’s (null: use the firm default).
The fields are as shown above.
Responses
200 OK, application/json
Body: object (ClientOverrides).
A client’s settings that differ from the firm’s (null: use the firm default).
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 client’s permanent notes
GET/api/v1/clients/{clientId}/notes
- Scopes
clients:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ClientNotes).
| Field | Type | Description |
|---|---|---|
notesrequired | string | up to 20000 characters |
updatedByrequired | string (uuid)nullable | |
updatedAtrequired | string (date-time)nullable |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Replace the client’s permanent notes
PATCH/api/v1/clients/{clientId}/notes
- Scopes
clients:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) |
Request body
Required. application/json: object (SetClientNotes).
| Field | Type | Description |
|---|---|---|
notesrequired | string | up to 20000 characters |
Responses
200 OK, application/json
Body: object (ClientNotes).
| Field | Type | Description |
|---|---|---|
notesrequired | string | up to 20000 characters |
updatedByrequired | string (uuid)nullable | |
updatedAtrequired | string (date-time)nullable |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Preview starting a client’s books from its final trial balance
POST/api/v1/clients/{clientId}/books-link/opening/preview
- Scopes
review:write- Access
- A signed-in Tolvi session only, never an API token.
Uses the client’s latest engagement approved at every stage, or the one named. Each final balance is placed on the books’ account by mapping, the same code on the same lead line, or the lead line’s default account; anything else is listed to map. problems says what stands in the way. Nothing is posted. Session only; reviewers and above. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) | Client id. |
Request body
Optional. application/json: object (StartBooksFromFinalTbInput).
| Field | Type | Description |
|---|---|---|
engagementId | string (uuid) | Defaults to the client’s latest engagement approved at every stage. |
mapping | object | Final TB code to an account code in the books. |
Responses
200 OK, application/json
Body: object (StartBooksFromFinalTbPreview).
The opening entry the client’s books would get from a final trial balance, mapped through the lead lines. Nothing is posted.
| Field | Type | Description |
|---|---|---|
readyrequired | boolean | |
problemsrequired | array of string | What stands in the way, in words. |
warningsrequired | array of string | |
engagementIdrequired | string (uuid)nullable | |
periodEndrequired | string (date)nullable | example "2026-03-31" |
startDaterequired | string (date)nullable | The day after the period end. example "2026-03-31" |
businessIdrequired | string (uuid)nullable | |
businessNamerequired | stringnullable | |
alreadyPostedrequired | boolean | |
planrequired | array of BooksOpeningPlanLine | |
plan[].sourceCoderequired | string | |
plan[].sourceNamerequired | string | |
plan[].balancePencerequired | integer | Integer pence (GBP). |
plan[].targetCoderequired | string | |
plan[].targetNamerequired | string | |
plan[].viarequired | string (BooksOpeningPlanVia) | One of: |
unmappedrequired | array of BooksOpeningUnmapped | |
unmapped[].coderequired | string | |
unmapped[].namerequired | string | |
unmapped[].balancePencerequired | integer | Integer pence (GBP). |
unmapped[].leadLinerequired | stringnullable | |
linesrequired | array of BooksOpeningEntryLine | |
lines[].accountIdrequired | string (uuid) | |
lines[].accountCoderequired | string | |
lines[].accountNamerequired | string | |
lines[].ownerNamerequired | string | |
lines[].normalBalancerequired | string (BooksNormalBalance) | One of: |
lines[].amountPencerequired | integer | Integer pence (GBP). Debit positive, credit negative. |
lines[].contactNamerequired | stringnullable | The customer or supplier, on a control account line split by unpaid invoice or bill. |
suspensePencerequired | integer | Integer pence (GBP). |
accountsrequired | array of BooksOpeningAccountRef | The books’ accounts, to map an unplaced balance to. |
accounts[].coderequired | string | |
accounts[].namerequired | string | |
accounts[].ownerNamerequired | string |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Start a client’s books from its final trial balance
POST/api/v1/clients/{clientId}/books-link/opening
- Scopes
review:write- Access
- A signed-in Tolvi session only, never an API token.
- Retries
- Send an
Idempotency-Keyto make retries safe.
Posts the preview’s opening entry to the client’s books, dated the period end, through the firm’s practice link (year-end or full bookkeeping access). 409 with the reasons when the preview isn’t ready. Reversible from the books until the year is locked. Session only; reviewers and above; not available through the MCP server. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientIdrequired | path | string (uuid) | Client id. |
Idempotency-Key | header | string | 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 (StartBooksFromFinalTbInput).
| Field | Type | Description |
|---|---|---|
engagementId | string (uuid) | Defaults to the client’s latest engagement approved at every stage. |
mapping | object | Final TB code to an account code in the books. |
Responses
201 Created, application/json
Body: object (StartBooksFromFinalTbResult).
| Field | Type | Description |
|---|---|---|
entryIdrequired | string (uuid) | |
seqrequired | integer | |
startDaterequired | string (date) | example "2026-03-31" |
suspensePencerequired | integer | Integer pence (GBP). |
statusrequired | string (StartBooksFromFinalTbStatus) | One of: |
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).