Skip to main content

Sync health

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

Sync health overview

GET/api/v1/sync

Scopes
work:read

Counts by sync state (open engagements, plus completed ones the sign-off check still covers), the last and any running sign-off check, the schedule and rules, and counts by software. Part of the working_papers product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (SyncOverview).

200 OK response for GET /api/v1/sync
FieldTypeDescription
countsrequiredobject (SyncCounts)
counts.​connectedrequiredinteger

Engagements on bookkeeping software (open, plus completed ones still checked).

at least 0

counts.​manualrequiredinteger

at least 0

counts.​inSyncrequiredinteger

at least 0

counts.​changedrequiredinteger

Open engagements whose figures changed since sign-off (the Work queue’s Changed view).

at least 0

counts.​changedCompletedrequiredinteger

Completed engagements whose figures changed.

at least 0

counts.​expiredrequiredinteger

at least 0

counts.​errorrequiredinteger

at least 0

counts.​neverSyncedrequiredinteger

at least 0

counts.​manualOpenrequiredinteger

Open engagements on manual upload: not checkable.

at least 0

counts.​resolvedTodayrequiredinteger

Accepted, acknowledged or recorded as post-filing today (firm time zone).

at least 0

lastRunrequiredobject (SyncCheckRun)nullable

The last run that finished.

lastRun.​idrequiredstring (uuid)
lastRun.​triggerrequiredstring (SyncCheckTrigger)

schedule: the nightly or weekly run; manual: Run check now.

One of: schedule, manual

lastRun.​startedAtrequiredstring (date-time)
lastRun.​finishedAtrequiredstring (date-time)nullable

Null while engagements are still being checked.

lastRun.​windowStartrequiredstring (date-time)

Checks start from here; a scheduled run spreads them over windowMinutes.

lastRun.​windowMinutesrequiredinteger

at least 0

lastRun.​totalrequiredinteger

Engagements in scope.

at least 0

lastRun.​checkedrequiredinteger

Engagements checked so far.

at least 0

lastRun.​changedrequiredinteger

at least 0

lastRun.​failedrequiredinteger

Expired connections and errors.

at least 0

lastRun.​durationMinutesrequiredintegernullable

From start to finish.

at least 0

lastRun.​requestedByrequiredstring (uuid)nullable
runningrequiredobject (SyncCheckRun)nullable

A run still checking engagements.

running.​idrequiredstring (uuid)
running.​triggerrequiredstring (SyncCheckTrigger)

schedule: the nightly or weekly run; manual: Run check now.

One of: schedule, manual

running.​startedAtrequiredstring (date-time)
running.​finishedAtrequiredstring (date-time)nullable

Null while engagements are still being checked.

running.​windowStartrequiredstring (date-time)

Checks start from here; a scheduled run spreads them over windowMinutes.

running.​windowMinutesrequiredinteger

at least 0

running.​totalrequiredinteger

Engagements in scope.

at least 0

running.​checkedrequiredinteger

Engagements checked so far.

at least 0

running.​changedrequiredinteger

at least 0

running.​failedrequiredinteger

Expired connections and errors.

at least 0

running.​durationMinutesrequiredintegernullable

From start to finish.

at least 0

running.​requestedByrequiredstring (uuid)nullable
schedulerequiredobject (SyncSchedule)
schedule.​frequencyrequiredstring (SyncFrequency)

One of: nightly, weekly

schedule.​timerequiredstring

example "02:00"

schedule.​timeZonerequiredstring

example "Europe/London"

schedule.​ignoreUnderPencerequiredinteger

Integer pence (GBP).

Movements smaller than this are ignored (firm default; a client can override it).

at least 0

schedule.​comparePriorYearrequiredboolean
schedule.​onChangerequiredstring (SyncOnChange)

One of: notify, reopen, none

schedule.​digestrequiredstring (SyncDigest)

One of: daily, instant, off

bySoftwarerequiredarray of SyncSoftwareRow
bySoftware[].​softwarerequiredstring (Software)

One of: xero, qbo, sage, freeagent, tolvi_books, manual

bySoftware[].​engagementsrequiredinteger

at least 0

bySoftware[].​inSyncrequiredinteger

at least 0

bySoftware[].​changedrequiredinteger

at least 0

bySoftware[].​fixrequiredinteger

Expired, error or never synced.

at least 0

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

List engagements for Sync health

GET/api/v1/sync/engagements

Scopes
work:read

Earliest deadline first, each with its latest sign-off check result. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/sync/engagements
NameInTypeDescription
limitqueryinteger

1 to 500; default 100

includeCompletedquerystring

changed only: include completed engagements.

One of: true, false

listquerystring

changed (default), fix (reconnect or fix), manual (open manual uploads), resolved (today).

One of: changed, fix, manual, resolved

Responses

200 OK, application/json

Body: object (SyncRowPage).

200 OK response for GET /api/v1/sync/engagements
FieldTypeDescription
listrequiredstring (SyncList)

One of: changed, fix, manual, resolved

rowsrequiredarray of SyncRow

Earliest deadline first; at most limit.

rows[].​engagementIdrequiredstring (uuid)
rows[].​clientIdrequiredstring (uuid)
rows[].​clientNamerequiredstring
rows[].​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

rows[].​periodEndrequiredstring (date)

example "2026-03-31"

rows[].​dueDaterequiredstring (date)

example "2026-03-31"

rows[].​statusrequiredstring (EngagementStatus)

One of: not_started, in_progress, submitted, returned, complete

rows[].​softwarerequiredstring (Software)

One of: xero, qbo, sage, freeagent, tolvi_books, manual

rows[].​syncStaterequiredstring (SyncState)

One of: in_sync, changed, expired_token, error, never_synced, manual

rows[].​lastSyncedAtrequiredstring (date-time)nullable
rows[].​resultrequiredobject (SyncResultSummary)nullable

The latest sign-off check result.

rows[].​result.​idrequiredstring (uuid)
rows[].​result.​statusrequiredstring (SyncCheckStatus)

One of: running, in_sync, changed, acknowledged, expired_token, error

rows[].​result.​checkedAtrequiredstring (date-time)
rows[].​result.​signedOffAtrequiredstring (date-time)nullable
rows[].​result.​accountCountrequiredinteger

Accounts that moved.

at least 0

rows[].​result.​grossPencerequiredinteger

Integer pence (GBP).

Sum of the absolute current year movements.

at least 0

rows[].​result.​affectedSectionsrequiredarray of string

Affected lead sections (W/P refs).

rows[].​result.​resolutionrequiredstring (SyncResolution)nullable

One of: accepted, acknowledged, post_filing

rows[].​result.​resolvedAtrequiredstring (date-time)nullable
rows[].​result.​outcomerequiredstringnullable

The outcome in words (who resolved it and how).

rows[].​result.​messagerequiredstringnullable

Why the check could not run, in words.

totalrequiredinteger

at least 0

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

Run the sign-off check now

POST/api/v1/sync/runs

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

Starts a check of every connected engagement with a sign-off (or only engagementIds). The books are read in the background; poll GET /sync/runs/{id}. A run already in progress is returned instead of starting another. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/sync/runs
NameInTypeDescription
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 (StartSyncCheckRequest).

Request body for POST /api/v1/sync/runs
FieldTypeDescription
engagementIdsarray of string

Only these engagements (Work queue bulk action); default every engagement in scope.

up to 500 items

Responses

202 Accepted, application/json

Body: object (SyncCheckRun).

202 Accepted response for POST /api/v1/sync/runs
FieldTypeDescription
idrequiredstring (uuid)
triggerrequiredstring (SyncCheckTrigger)

schedule: the nightly or weekly run; manual: Run check now.

One of: schedule, manual

startedAtrequiredstring (date-time)
finishedAtrequiredstring (date-time)nullable

Null while engagements are still being checked.

windowStartrequiredstring (date-time)

Checks start from here; a scheduled run spreads them over windowMinutes.

windowMinutesrequiredinteger

at least 0

totalrequiredinteger

Engagements in scope.

at least 0

checkedrequiredinteger

Engagements checked so far.

at least 0

changedrequiredinteger

at least 0

failedrequiredinteger

Expired connections and errors.

at least 0

durationMinutesrequiredintegernullable

From start to finish.

at least 0

requestedByrequiredstring (uuid)nullable

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

Remind people to reconnect bookkeeping

POST/api/v1/sync/reminders

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

For engagements whose connection has expired, failed or never synced: tells the preparer (else the manager, else the partner) which clients need reconnecting, in the app and by email unless they have turned those emails off. One reminder per person. You are never reminded yourself. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/sync/reminders
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 (SyncRemindersRequest).

Request body for POST /api/v1/sync/reminders
FieldTypeDescription
engagementIdsrequiredarray of string

Engagements whose bookkeeping connection needs reconnecting or fixing (Sync health’s Reconnect or fix list).

1 to 500 items

Responses

200 OK, application/json

Body: object (SyncReminders).

Who was reminded.

200 OK response for POST /api/v1/sync/reminders
FieldTypeDescription
notifiedrequiredinteger

People sent a reminder (one each, listing their clients).

at least 0

engagementsrequiredinteger

Engagements covered by a reminder.

at least 0

skippedrequiredinteger

Engagements left out: not broken, on manual upload, or with nobody to remind but you.

at least 0

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 sign-off check run

GET/api/v1/sync/runs/{id}

Scopes
work:read

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

Parameters

Parameters for GET /api/v1/sync/runs/{id}
NameInTypeDescription
idrequiredpathstring (uuid)

Run id.

Responses

200 OK, application/json

Body: object (SyncCheckRun).

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 an engagement’s sign-off check

GET/api/v1/engagements/{id}/sync-check

Scopes
engagements:read

The latest result: account-by-account differences from the signed-off trial balance, the transactions behind them and the affected sections, with the engagement’s earlier resolutions. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/engagements/{id}/sync-check
NameInTypeDescription
idrequiredpathstring (uuid)

Engagement id.

Responses

200 OK, application/json

Body: object (SyncCheckDetail).

200 OK response for GET /api/v1/engagements/{id}/sync-check
FieldTypeDescription
engagementIdrequiredstring (uuid)
clientNamerequiredstring
periodEndrequiredstring (date)

example "2026-03-31"

statusrequiredstring (EngagementStatus)

One of: not_started, in_progress, submitted, returned, complete

filedOnrequiredstring (date)nullable

When the accounts were filed; a change after that is a post-filing change.

example "2026-03-31"

softwarerequiredstring (Software)

One of: xero, qbo, sage, freeagent, tolvi_books, manual

syncStaterequiredstring (SyncState)

One of: in_sync, changed, expired_token, error, never_synced, manual

latestrequiredobject (SyncCheckResult)nullable

The latest result; null if never checked.

latest.​idrequiredstring (uuid)
latest.​statusrequiredstring (SyncCheckStatus)

One of: running, in_sync, changed, acknowledged, expired_token, error

latest.​checkedAtrequiredstring (date-time)
latest.​signedOffAtrequiredstring (date-time)nullable
latest.​accountCountrequiredinteger

Accounts that moved.

at least 0

latest.​grossPencerequiredinteger

Integer pence (GBP).

Sum of the absolute current year movements.

at least 0

latest.​affectedSectionsrequiredarray of string

Affected lead sections (W/P refs).

latest.​resolutionrequiredstring (SyncResolution)nullable

One of: accepted, acknowledged, post_filing

latest.​resolvedAtrequiredstring (date-time)nullable
latest.​outcomerequiredstringnullable

The outcome in words (who resolved it and how).

latest.​messagerequiredstringnullable

Why the check could not run, in words.

latest.​runIdrequiredstring (uuid)
latest.​providerrequiredstring (IntegrationProvider)nullable

The OAuth provider read; null for Tolvi Books (see source).

One of: xero, quickbooks, sage, freeagent

latest.​sourcerequiredstring (BooksSource)nullable

Where the books were read: an OAuth provider, or tolvi_books (the client’s Tolvi Books, through the firm’s practice link).

One of: xero, quickbooks, sage, freeagent, tolvi_books

latest.​sourceLabelrequiredstringnullable

example "Tolvi Books"

latest.​tbVersionIdrequiredstring (uuid)nullable

The trial balance version compared against.

latest.​tbVersionrequiredintegernullable
latest.​asAtrequiredstring (date)nullable

example "2026-03-31"

latest.​priorAsAtrequiredstring (date)nullable

example "2026-03-31"

latest.​accountsrequiredarray of SyncDiffAccount
latest.​accounts[].​coderequiredstring
latest.​accounts[].​namerequiredstring
latest.​accounts[].​statusrequiredstring (SyncDiffStatus)

One of: changed, added, removed

latest.​accounts[].​signedOffrequiredobject (SyncBalances)nullable

In the trial balance that was signed off.

latest.​accounts[].​signedOff.​cyPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​signedOff.​pyPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​nowrequiredobject (SyncBalances)nullable

In the bookkeeping software now.

latest.​accounts[].​now.​cyPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​now.​pyPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​cyDiffPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​pyDiffPencerequiredinteger

Integer pence (GBP).

latest.​accounts[].​sectionsrequiredarray of string
latest.​accounts[].​transactionsrequiredarray of SyncTransaction

Postings behind the movement, when the software lists them.

latest.​accounts[].​transactions[].​idrequiredstring

The provider’s id for the source document or journal.

latest.​accounts[].​transactions[].​accountCoderequiredstring
latest.​accounts[].​transactions[].​daterequiredstring (date)

example "2026-03-31"

latest.​accounts[].​transactions[].​descriptionrequiredstring
latest.​accounts[].​transactions[].​amountPencerequiredinteger

Integer pence (GBP).

Debit positive.

latest.​accounts[].​transactions[].​updatedAtrequiredstring (date-time)nullable

When it was entered or last changed in the software.

latest.​accounts[].​transactions[].​sourceTyperequiredstringnullable
latest.​accounts[].​transactions[].​postedByrequiredstringnullable

Who entered it, when the software says (Tolvi Books does).

example "Jo Owner (the business)"

latest.​accounts[].​transactions[].​explanationrequiredstring

example "Credit note CN-0192 (Kestrel Homes), dated 28 Mar 2026, entered 14 Oct 2026"

latest.​accounts[].​unexplainedPencerequiredinteger

Integer pence (GBP).

The movement the transactions do not account for.

latest.​transactionsAvailablerequiredboolean

The software could list the transactions behind the movements. From Tolvi Books they are exactly the ledger entries posted after the signed-off trial balance’s ledger point, each with who posted it.

latest.​reasonrequiredstringnullable
latest.​noterequiredstringnullable
latest.​resolvedByrequiredstring (uuid)nullable
latest.​resolvedTbVersionIdrequiredstring (uuid)nullable

Accept and re-sync: the trial balance version created.

historyrequiredarray of SyncResultSummary

Earlier resolved results, newest first (the engagement’s sync history).

history[].​idrequiredstring (uuid)
history[].​statusrequiredstring (SyncCheckStatus)

One of: running, in_sync, changed, acknowledged, expired_token, error

history[].​checkedAtrequiredstring (date-time)
history[].​signedOffAtrequiredstring (date-time)nullable
history[].​accountCountrequiredinteger

Accounts that moved.

at least 0

history[].​grossPencerequiredinteger

Integer pence (GBP).

Sum of the absolute current year movements.

at least 0

history[].​affectedSectionsrequiredarray of string

Affected lead sections (W/P refs).

history[].​resolutionrequiredstring (SyncResolution)nullable

One of: accepted, acknowledged, post_filing

history[].​resolvedAtrequiredstring (date-time)nullable
history[].​outcomerequiredstringnullable

The outcome in words (who resolved it and how).

history[].​messagerequiredstringnullable

Why the check could not run, in words.

canResolverequiredboolean

Accept and re-sync, Acknowledge or Record as post-filing change can be used now.

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

Accept and re-sync

POST/api/v1/engagements/{id}/sync-check/accept

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

Pulls the books again into a new immutable trial balance version and reopens the affected sections; their sign-offs go stale through the content fingerprint (a new amendment round). 409 if there is no open change, or if journals would be removed without confirmJournalRemoval. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/engagements/{id}/sync-check/accept
NameInTypeDescription
idrequiredpathstring (uuid)

Engagement id.

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

Request body for POST /api/v1/engagements/{id}/sync-check/accept
FieldTypeDescription
confirmJournalRemovalboolean

Confirm removing journals on accounts no longer in the books (409 lists them otherwise).

Responses

200 OK, application/json

Body: object (SyncCheckDetail).

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

Acknowledge a change without re-syncing

POST/api/v1/engagements/{id}/sync-check/acknowledge

Scopes
review:write

Records why no action is needed (a note is required for “Other”). The same differences are not raised again by later checks. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/engagements/{id}/sync-check/acknowledge
NameInTypeDescription
idrequiredpathstring (uuid)

Engagement id.

Request body

Required. application/json: object (AcknowledgeSyncChangeRequest).

Request body for POST /api/v1/engagements/{id}/sync-check/acknowledge
FieldTypeDescription
reasonrequiredstring

1 to 200 characters; example "Posted in error by client; they will reverse it"

notestring

Required when the reason is “Other”. Shown in the sync history.

up to 2000 characters

Responses

200 OK, application/json

Body: object (SyncCheckDetail).

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

Record a post-filing change

POST/api/v1/engagements/{id}/sync-check/post-filing

Scopes
review:write

For a completed engagement: records the change as a post-filing change (tell the client; consider amended accounts or next year’s opening balances). The same differences are not raised again. Part of the working_papers product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/engagements/{id}/sync-check/post-filing
NameInTypeDescription
idrequiredpathstring (uuid)

Engagement id.

Request body

Optional. application/json: object (PostFilingChangeRequest).

Request body for POST /api/v1/engagements/{id}/sync-check/post-filing
FieldTypeDescription
notestring

up to 2000 characters

Responses

200 OK, application/json

Body: object (SyncCheckDetail).

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