Imports
16 operations in the Tolvi API, version 1. Paths are relative to https://api.tolvi.co.uk. Every amount is integer pence.
List imports
GET/api/v1/imports
- Scopes
clients:read
The firm’s latest imports, newest first, with how far each has got. Part of the hub product: the firm must have it and you must have access to it.
Responses
200 OK, application/json
Body: object (ImportBatchList).
| Field | Type | Description |
|---|---|---|
batchesrequired | array of ImportBatch | |
batches[].idrequired | string (uuid) | |
batches[].kindrequired | string (ImportKind) | One of: |
batches[].statusrequired | string (ImportStatus) | One of: |
batches[].fileNamerequired | string | |
batches[].sizeBytesrequired | integer | |
batches[].problemrequired | stringnullable | Why it stopped, in plain words. |
batches[].noticesrequired | array of string | About the file as a whole, such as columns left out. |
batches[].sheetsrequired | array of string | |
batches[].sheetrequired | stringnullable | |
batches[].headerLinerequired | integernullable | The line or row the headings were found on. |
batches[].columnsrequired | array of ImportColumn | |
batches[].columns[].columnrequired | integer | |
batches[].columns[].headerrequired | string | |
batches[].columns[].fieldrequired | stringnullable | The field it goes to, or null to ignore it. |
batches[].columns[].confidencerequired | string (ImportColumnConfidence) | One of: |
batches[].columns[].refused | string | Set when Tolvi won’t keep this column, with what it holds. |
batches[].columns[].samplesrequired | array of string | The first few values. |
batches[].clientIdrequired | string (uuid)nullable | Trial balance: whose. |
batches[].clientNamerequired | stringnullable | |
batches[].periodEndrequired | string (date)nullable | example "2026-03-31" |
batches[].userequired | string (ImportTbUse)nullable | One of: |
batches[].totalRowsrequired | integer | |
batches[].skippedRowsrequired | integer | Blank, total and heading rows left out when reading. |
batches[].doneRowsrequired | integer | |
batches[].countsrequired | object (ImportCounts) | |
batches[].counts.readyrequired | integer | |
batches[].counts.warningrequired | integer | |
batches[].counts.errorrequired | integer | |
batches[].counts.duplicaterequired | integer | |
batches[].counts.toImportrequired | integer | Rows a person has chosen to bring in. |
batches[].counts.createdrequired | integer | |
batches[].counts.updatedrequired | integer | |
batches[].counts.appliedrequired | integer | |
batches[].counts.skippedrequired | integer | |
batches[].counts.failedrequired | integer | |
batches[].counts.undonerequired | integer | |
batches[].counts.keptrequired | integer | Left in place by undo, with the reason on the row. |
batches[].createdByNamerequired | stringnullable | |
batches[].createdAtrequired | string (date-time) | |
batches[].confirmedAtrequired | string (date-time)nullable | |
batches[].completedAtrequired | string (date-time)nullable | |
batches[].undoneAtrequired | string (date-time)nullable |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Start an import
POST/api/v1/imports
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Records the file and returns where to PUT it. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (CreateImportRequest).
| Field | Type | Description |
|---|---|---|
kindrequired | string (ImportKind) | One of: |
fileNamerequired | string | |
contentType | string | |
sizeBytesrequired | integer | |
clientId | string (uuid) | Trial balance: whose. |
periodEnd | string (date) | Trial balance: the period of the accounts it goes in. example "2026-03-31" |
periodStart | string (date) | Left out: twelve months. example "2026-03-31" |
use | string (ImportTbUse) | comparatives: the file’s balances become last year’s column. One of: |
Responses
201 Created, application/json
Body: object (ImportCreated).
| Field | Type | Description |
|---|---|---|
batchrequired | object (ImportBatch) | One uploaded file on its way into Tolvi. |
batch.idrequired | string (uuid) | |
batch.kindrequired | string (ImportKind) | One of: |
batch.statusrequired | string (ImportStatus) | One of: |
batch.fileNamerequired | string | |
batch.sizeBytesrequired | integer | |
batch.problemrequired | stringnullable | Why it stopped, in plain words. |
batch.noticesrequired | array of string | About the file as a whole, such as columns left out. |
batch.sheetsrequired | array of string | |
batch.sheetrequired | stringnullable | |
batch.headerLinerequired | integernullable | The line or row the headings were found on. |
batch.columnsrequired | array of ImportColumn | |
batch.columns[].columnrequired | integer | |
batch.columns[].headerrequired | string | |
batch.columns[].fieldrequired | stringnullable | The field it goes to, or null to ignore it. |
batch.columns[].confidencerequired | string (ImportColumnConfidence) | One of: |
batch.columns[].refused | string | Set when Tolvi won’t keep this column, with what it holds. |
batch.columns[].samplesrequired | array of string | The first few values. |
batch.clientIdrequired | string (uuid)nullable | Trial balance: whose. |
batch.clientNamerequired | stringnullable | |
batch.periodEndrequired | string (date)nullable | example "2026-03-31" |
batch.userequired | string (ImportTbUse)nullable | One of: |
batch.totalRowsrequired | integer | |
batch.skippedRowsrequired | integer | Blank, total and heading rows left out when reading. |
batch.doneRowsrequired | integer | |
batch.countsrequired | object (ImportCounts) | |
batch.counts.readyrequired | integer | |
batch.counts.warningrequired | integer | |
batch.counts.errorrequired | integer | |
batch.counts.duplicaterequired | integer | |
batch.counts.toImportrequired | integer | Rows a person has chosen to bring in. |
batch.counts.createdrequired | integer | |
batch.counts.updatedrequired | integer | |
batch.counts.appliedrequired | integer | |
batch.counts.skippedrequired | integer | |
batch.counts.failedrequired | integer | |
batch.counts.undonerequired | integer | |
batch.counts.keptrequired | integer | Left in place by undo, with the reason on the row. |
batch.createdByNamerequired | stringnullable | |
batch.createdAtrequired | string (date-time) | |
batch.confirmedAtrequired | string (date-time)nullable | |
batch.completedAtrequired | string (date-time)nullable | |
batch.undoneAtrequired | string (date-time)nullable | |
uploadrequired | object (ImportUpload) | PUT the file here, then POST …/uploaded. |
upload.urlrequired | string | |
upload.methodrequired | string | |
upload.headersrequired | object |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
List what can be imported
GET/api/v1/imports/kinds
- Scopes
clients:read
Each kind of import, its fields, the file types and limits, and whether you can use it. Part of the hub product: the firm must have it and you must have access to it.
Responses
200 OK, application/json
Body: object (ImportKindList).
| Field | Type | Description |
|---|---|---|
kindsrequired | array of ImportKindInfo | |
kinds[].kindrequired | string (ImportKind) | One of: |
kinds[].labelrequired | string | |
kinds[].descriptionrequired | string | |
kinds[].availablerequired | boolean | False when this firm or person can’t use the product it goes into. |
kinds[].unavailableReasonrequired | stringnullable | |
kinds[].fieldsrequired | array of ImportField | |
kinds[].fields[].keyrequired | string | example "companyNumber" |
kinds[].fields[].labelrequired | string | example "Company number" |
kinds[].fields[].requiredrequired | boolean | |
kinds[].fields[].multiplerequired | boolean | Several columns may feed it. |
extensionsrequired | array of string | Extensions accepted. |
maxBytesrequired | integer | |
maxRowsrequired | integer |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Download a template
GET/api/v1/imports/templates/{kind}
- Scopes
clients:read
A spreadsheet with the headings Tolvi reads first and worked examples to overwrite. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
kindrequired | path | string | One of: |
format | query | string | One of: |
Responses
200 OK
A spreadsheet.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Get an import
GET/api/v1/imports/{id}
- Scopes
clients:read
Status, the columns found with what Tolvi suggests for each, and counts. Poll this while it reads, checks or imports. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into Tolvi.
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
kindrequired | string (ImportKind) | One of: |
statusrequired | string (ImportStatus) | One of: |
fileNamerequired | string | |
sizeBytesrequired | integer | |
problemrequired | stringnullable | Why it stopped, in plain words. |
noticesrequired | array of string | About the file as a whole, such as columns left out. |
sheetsrequired | array of string | |
sheetrequired | stringnullable | |
headerLinerequired | integernullable | The line or row the headings were found on. |
columnsrequired | array of ImportColumn | |
columns[].columnrequired | integer | |
columns[].headerrequired | string | |
columns[].fieldrequired | stringnullable | The field it goes to, or null to ignore it. |
columns[].confidencerequired | string (ImportColumnConfidence) | One of: |
columns[].refused | string | Set when Tolvi won’t keep this column, with what it holds. |
columns[].samplesrequired | array of string | The first few values. |
clientIdrequired | string (uuid)nullable | Trial balance: whose. |
clientNamerequired | stringnullable | |
periodEndrequired | string (date)nullable | example "2026-03-31" |
userequired | string (ImportTbUse)nullable | One of: |
totalRowsrequired | integer | |
skippedRowsrequired | integer | Blank, total and heading rows left out when reading. |
doneRowsrequired | integer | |
countsrequired | object (ImportCounts) | |
counts.readyrequired | integer | |
counts.warningrequired | integer | |
counts.errorrequired | integer | |
counts.duplicaterequired | integer | |
counts.toImportrequired | integer | Rows a person has chosen to bring in. |
counts.createdrequired | integer | |
counts.updatedrequired | integer | |
counts.appliedrequired | integer | |
counts.skippedrequired | integer | |
counts.failedrequired | integer | |
counts.undonerequired | integer | |
counts.keptrequired | integer | Left in place by undo, with the reason on the row. |
createdByNamerequired | stringnullable | |
createdAtrequired | string (date-time) | |
confirmedAtrequired | string (date-time)nullable | |
completedAtrequired | string (date-time)nullable | |
undoneAtrequired | 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).
Discard an import
DELETE/api/v1/imports/{id}
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Removes the file and what was read, before anything has come in. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
204 No content
Gone.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Say the file has uploaded
POST/api/v1/imports/{id}/uploaded
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Checks what storage holds, hands it to the malware scan and, once clean, reads it. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Choose the sheet or heading row
PUT/api/v1/imports/{id}/layout
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Reads the file again from another sheet or heading row. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Request body
Required. application/json: object (ImportLayoutRequest).
| Field | Type | Description |
|---|---|---|
sheet | string | |
headerLine | integer | The line or row the headings are on. |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Confirm the columns
PUT/api/v1/imports/{id}/mapping
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Says which column is which field, then checks every row in the background. Nothing comes in yet. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Request body
Required. application/json: object (ImportMappingRequest).
| Field | Type | Description |
|---|---|---|
columnsrequired | array of ColumnChoice | |
columns[].columnrequired | integer | |
columns[].fieldrequired | stringnullable |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
List an import’s rows
GET/api/v1/imports/{id}/rows
- Scopes
clients:read
What each row said, what’s wrong with it in plain words, any client it matches, and what happened to it. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
limit | query | integer | |
after | query | integer | |
outcome | query | string | |
status | query | string |
Responses
200 OK, application/json
Body: object (ImportRowPage).
| Field | Type | Description |
|---|---|---|
rowsrequired | array of ImportRow | |
rows[].linerequired | integer | |
rows[].labelrequired | string | |
rows[].statusrequired | string (ImportRowStatus) | One of: |
rows[].decisionrequired | string (ImportRowDecision) | One of: |
rows[].outcomerequired | string (ImportRowOutcome) | One of: |
rows[].outcomeNoterequired | stringnullable | |
rows[].errorsrequired | array of string | |
rows[].warningsrequired | array of string | |
rows[].valuesrequired | objectnullable | What was read. Money is integer pence. |
rows[].matchClientIdrequired | string (uuid)nullable | |
rows[].matchClientNamerequired | stringnullable | |
rows[].matchHowrequired | string (ImportMatchHow)nullable | One of: |
nextAfterrequired | integernullable | Pass as |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Decide one row
PATCH/api/v1/imports/{id}/rows/{line}
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Bring it in, fill the blanks on the matching client, or skip it; or give the client type or statement line it lacks. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
linerequired | path | integer |
Request body
Required. application/json: object (ImportRowPatchRequest).
| Field | Type | Description |
|---|---|---|
decision | string (ImportRowDecision) | One of: |
entityType | string | The client type, when the file didn’t give one Tolvi knows. |
statementLine | string | Trial balance: the statement line for this account. |
Responses
200 OK, application/json
Body: object (ImportRow).
One row of the file.
| Field | Type | Description |
|---|---|---|
linerequired | integer | |
labelrequired | string | |
statusrequired | string (ImportRowStatus) | One of: |
decisionrequired | string (ImportRowDecision) | One of: |
outcomerequired | string (ImportRowOutcome) | One of: |
outcomeNoterequired | stringnullable | |
errorsrequired | array of string | |
warningsrequired | array of string | |
valuesrequired | objectnullable | What was read. Money is integer pence. |
matchClientIdrequired | string (uuid)nullable | |
matchClientNamerequired | stringnullable | |
matchHowrequired | string (ImportMatchHow)nullable | One of: |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Decide every row of a status
POST/api/v1/imports/{id}/rows/decide
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
For instance, fill the blanks on every duplicate. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Request body
Required. application/json: object (ImportBulkDecisionRequest).
| Field | Type | Description |
|---|---|---|
statusrequired | string (ImportRowStatus) | One of: |
decisionrequired | string (ImportRowDecision) | One of: |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Confirm and import
POST/api/v1/imports/{id}/confirm
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Brings in the rows chosen, in the background. Safe to retry. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Request body
Required. application/json: object (ImportConfirmRequest).
A person confirming what they have seen.
| Field | Type | Description |
|---|---|---|
expectedRowsrequired | integer | How many rows the person saw would come in. Refused if that has changed. |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Carry on after a stop
POST/api/v1/imports/{id}/retry
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Rows already done are left alone. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Undo an import
POST/api/v1/imports/{id}/undo
- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Takes out what the whole file brought in. A client with work on it, or anything changed since, is kept, and the report says why. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.
Needs the Manager role or above. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (ImportBatch).
One uploaded file on its way into 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).
Download the results report
GET/api/v1/imports/{id}/report
- Scopes
clients:read
What happened to every row, as CSV. Values that a spreadsheet would run as a formula are neutralised. Part of the hub product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) |
Responses
200 OK
A CSV file.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).