Journals
10 operations in the Tolvi API, version 1. Paths are relative to https://api.tolvi.co.uk. Every amount is integer pence.
List journals
GET/api/v1/engagements/{id}/journals
- Scopes
engagements:read
Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
Responses
200 OK, application/json
Body: array of Journal.
| Field | Type | Description |
|---|---|---|
[].idrequired | string (uuid) | |
[].refrequired | string | example "JNL-03" |
[].daterequired | string (date) | example "2026-03-31" |
[].typerequired | string (JournalType) | One of: |
[].statusrequired | string (JournalStatus) | One of: |
[].narrativerequired | string | |
[].autoKindrequired | string (JournalAutoKind)nullable | Posted by Tolvi from the tax computation (ct, deferred) or the fixed asset register (fixed_assets). One of: |
[].linesrequired | array of JournalLine | |
[].lines[].accountCoderequired | string | |
[].lines[].accountNamerequired | stringnullable | |
[].lines[].debitPencerequired | integer | Integer pence (GBP). |
[].lines[].creditPencerequired | integer | Integer pence (GBP). |
[].sectionCodesrequired | array of string | Lead sections the journal touches. |
[].lockedBySectionsrequired | array of string | Reviewed sections that lock it: only a reviewer or above can unpost or delete it. |
[].createdByrequired | string (uuid)nullable | |
[].createdAtrequired | string (date-time) | |
[].postedByrequired | string (uuid)nullable | |
[].postedAtrequired | 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).
Create a journal (draft by default)
POST/api/v1/engagements/{id}/journals
- Scopes
engagements:writeandengagements:read- Retries
- Send an
Idempotency-Keyto make retries safe.
Debits must equal credits. A draft raises an issue on every lead section it touches. Preparers, reviewers, managers and partners can all do this; the audit trail records who. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement 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
Required. application/json: object (CreateJournal).
| Field | Type | Description |
|---|---|---|
date | string (date) | Default: the period end. example "2026-03-31" |
typerequired | string (JournalType) | One of: |
narrativerequired | string | 1 to 1000 characters |
status | string (JournalStatus) | Default draft. One of: |
linesrequired | array of JournalLineInput | 2 to 200 items |
lines[].accountCoderequired | string | |
lines[].debitPencerequired | integer | Integer pence (GBP). at least 0 |
lines[].creditPencerequired | integer | Integer pence (GBP). at least 0 |
Responses
201 Created, application/json
Body: object (Journal).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
refrequired | string | example "JNL-03" |
daterequired | string (date) | example "2026-03-31" |
typerequired | string (JournalType) | One of: |
statusrequired | string (JournalStatus) | One of: |
narrativerequired | string | |
autoKindrequired | string (JournalAutoKind)nullable | Posted by Tolvi from the tax computation (ct, deferred) or the fixed asset register (fixed_assets). One of: |
linesrequired | array of JournalLine | |
lines[].accountCoderequired | string | |
lines[].accountNamerequired | stringnullable | |
lines[].debitPencerequired | integer | Integer pence (GBP). |
lines[].creditPencerequired | integer | Integer pence (GBP). |
sectionCodesrequired | array of string | Lead sections the journal touches. |
lockedBySectionsrequired | array of string | Reviewed sections that lock it: only a reviewer or above can unpost or delete it. |
createdByrequired | string (uuid)nullable | |
createdAtrequired | string (date-time) | |
postedByrequired | string (uuid)nullable | |
postedAtrequired | string (date-time)nullable |
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).
Preview what a journal change would do
POST/api/v1/engagements/{id}/journals/impact
- Scopes
engagements:read
Works out, without saving anything, which sections’ content would change and whose sign-offs would go out of date if a new journal were saved (give its lines) or a saved journal were posted, unposted or deleted (give journalId and action). Also the headline figures that would move. Read access is enough. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
Request body
Required. application/json: object (JournalImpactRequest).
Either a journal not yet saved (lines, with status) or a saved one and what would be done to it.
| Field | Type | Description |
|---|---|---|
journalId | string (uuid) | A saved journal. Give action too. |
action | string (JournalImpactAction) | One of: |
lines | array of JournalLineInput | A new journal’s lines (instead of journalId). 1 to 200 items |
lines[].accountCoderequired | string | |
lines[].debitPencerequired | integer | Integer pence (GBP). at least 0 |
lines[].creditPencerequired | integer | Integer pence (GBP). at least 0 |
status | string (JournalStatus) | For new lines: posted (default) or draft. One of: |
date | string (date) | For new lines. Default: the period end. example "2026-03-31" |
Responses
200 OK, application/json
Body: object (JournalImpact).
What a journal change would do, worked out without saving anything.
| Field | Type | Description |
|---|---|---|
sectionsrequired | array of SectionImpact | Sections whose content would change, in file order. |
sections[].coderequired | string | |
sections[].namerequired | string | |
sections[].staleSignOffsrequired | array of StaleSignOff | Live sign-offs on the section that would go out of date. |
sections[].staleSignOffs[].stageIdrequired | string | |
sections[].staleSignOffs[].stageNamerequired | string | |
sections[].staleSignOffs[].userIdrequired | string (uuid) | |
figuresrequired | array of FigureChange | Headline figures that would move. |
figures[].keyrequired | string (FigureKey) | One of: |
figures[].labelrequired | string | |
figures[].beforePencerequired | integer | Integer pence (GBP). |
figures[].afterPencerequired | integer | Integer pence (GBP). |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Post a draft journal
POST/api/v1/engagements/{id}/journals/{journalId}/post
- Scopes
engagements:writeandengagements:read
Records who posted it (postedBy). Preparers, reviewers, managers and partners can all do this; the audit trail records who. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
journalIdrequired | path | string (uuid) |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Unpost a journal
POST/api/v1/engagements/{id}/journals/{journalId}/unpost
- Scopes
engagements:writeandengagements:read
Preparers, reviewers, managers and partners can unpost; the audit trail records who. A posted journal touching a section with a current review sign-off can only be unposted by a reviewer or above (403 for a preparer). Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
journalIdrequired | path | string (uuid) |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Delete a journal
DELETE/api/v1/engagements/{id}/journals/{journalId}
- Scopes
engagements:writeandengagements:read
Same people and lock rule as unposting: a posted journal touching a reviewed section can only be deleted by a reviewer or above. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
journalIdrequired | 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).
List journal-only accounts
GET/api/v1/engagements/{id}/journal-accounts
- Scopes
engagements:read
Accounts Tolvi added for journals when the client’s bookkeeping has none (for example a corporation tax charge and creditor), and the standard ones it suggests. They are in no TB version; the final TB shows them from posted journals only. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
Responses
200 OK, application/json
Body: object (JournalAccounts).
| Field | Type | Description |
|---|---|---|
accountsrequired | array of JournalAccount | |
accounts[].coderequired | string | |
accounts[].namerequired | string | |
accounts[].lineIdrequired | string (LeadLineId)nullable | One of: |
accounts[].lineLabelrequired | stringnullable | |
accounts[].journalRefsrequired | array of string | Journals that post to it (it cannot be removed while any do). |
suggestionsrequired | array of JournalAccountSuggestion | |
suggestions[].purposerequired | string (JournalAccountPurpose) | One of: |
suggestions[].coderequired | string | |
suggestions[].namerequired | string | |
suggestions[].lineIdrequired | string (LeadLineId) | One of: |
suggestions[].neededrequired | boolean | Nothing on the TB or among Tolvi’s accounts serves this purpose yet. |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Add journal-only accounts
POST/api/v1/engagements/{id}/journal-accounts
- Scopes
engagements:writeandengagements:read- Retries
- Send an
Idempotency-Keyto make retries safe.
Each needs a code not already on the engagement and a lead schedule line. The TB version is not changed. Returns the list. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement 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
Required. application/json: object (CreateJournalAccounts).
| Field | Type | Description |
|---|---|---|
accountsrequired | array of NewJournalAccount | |
accounts[].coderequired | string | Letters, digits, - . or /; not already an account on the engagement. up to 50 characters |
accounts[].namerequired | string | up to 200 characters |
accounts[].lineIdrequired | string (LeadLineId) | One of: |
Responses
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).
Remove a journal-only account
DELETE/api/v1/engagements/{id}/journal-accounts/{code}
- Scopes
engagements:writeandengagements:read
Refused (409) while any journal posts to it, C uses it for disposal proceeds, or an asset class uses it. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
coderequired | path | string | up to 50 characters |
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).
List the accounts to choose from
GET/api/v1/engagements/{id}/accounts
- Scopes
engagements:read
Every account C’s pickers and journal lines can use: the trial balance’s accounts, Tolvi’s journal-only accounts, and the client’s chart of accounts (read from their bookkeeping software, or imported from a CSV), including accounts with no balance in this TB. Each has its lead schedule line. An account with no balance yet that a class or journal uses shows in the final TB under the client’s own code. Part of the working_papers product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | Engagement id. |
Responses
200 OK, application/json
Body: object (EngagementAccounts).
| Field | Type | Description |
|---|---|---|
sourcerequired | stringnullable | Where the client’s chart of accounts came from: xero, quickbooks, sage, freeagent or csv; null when there is none (the TB’s accounts only). |
sourceLabelrequired | stringnullable | example "Xero" |
syncedAtrequired | string (date-time)nullable | When the chart was last read or imported. |
connectedTorequired | stringnullable | The software the client’s books are connected to, so the chart can be refreshed; null when not connected. example "Xero" |
accountsrequired | array of EngagementAccount | |
accounts[].coderequired | string | |
accounts[].namerequired | string | |
accounts[].lineIdrequired | string (LeadLineId)nullable | The account’s lead schedule line: B’s mapping, else what the chart suggests. Null when unmapped. One of: |
accounts[].lineLabelrequired | stringnullable | |
accounts[].sectionCoderequired | stringnullable | The lead schedule (section) of the line. |
accounts[].inTbrequired | boolean | In the imported trial balance. False for a chart account with no balance in this TB, and for journal-only accounts. |
accounts[].journalOnlyrequired | boolean | |
accounts[].inChartrequired | boolean | On the client’s chart of accounts. |
accounts[].activerequired | boolean | False for an account archived or inactive in the client’s books. |
accounts[].finalPencerequired | integer | Final TB balance, integer pence, debit positive (nil for an account with no balance yet). |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).