Making Tax Digital for Income Tax
12 operations in the Tolvi API, version 1. Paths are relative to https://api.tolvi.co.uk. Every amount is integer pence.
List income sources
GET/api/v1/mtd-income-tax/sources
- Scopes
self_assessment:read
Part of the self_assessment product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientId | query | string (uuid) |
Responses
200 OK, application/json
Body: object (MtdItSourceList).
| Field | Type | Description |
|---|---|---|
itemsrequired | array of MtdItSource | |
items[].idrequired | string (uuid) | |
items[].clientIdrequired | string (uuid) | |
items[].kindrequired | string (MtdItSourceKind) | One of: |
items[].namerequired | string | |
items[].hmrcBusinessIdrequired | stringnullable | |
items[].periodTyperequired | string (MtdItPeriodType) | One of: |
items[].ninoMaskrequired | stringnullable | |
items[].sendingEnabledrequired | boolean |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Add an income source
POST/api/v1/mtd-income-tax/sources
- Scopes
self_assessment:write- Role
- Preparer or above
- Access
- A signed-in Tolvi session only, never an API token.
A sole trade or UK property business. Never available to API keys or connected assistants.
Needs the Preparer role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (AddMtdItSource).
| Field | Type | Description |
|---|---|---|
clientIdrequired | string (uuid) | |
kindrequired | string (MtdItSourceKind) | One of: |
namerequired | string | |
hmrcBusinessId | string | |
periodType | string (MtdItPeriodType) | One of: |
nino | string | Sent once and held encrypted. Only a mask comes back. |
Responses
200 OK, application/json
Body: object (MtdItSource).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
clientIdrequired | string (uuid) | |
kindrequired | string (MtdItSourceKind) | One of: |
namerequired | string | |
hmrcBusinessIdrequired | stringnullable | |
periodTyperequired | string (MtdItPeriodType) | One of: |
ninoMaskrequired | stringnullable | |
sendingEnabledrequired | boolean |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
The year’s four updates
GET/api/v1/mtd-income-tax/sources/{id}/obligations
- Scopes
self_assessment:read
Worked out from the dates, and what’s been accepted here. Not read from HMRC. Part of the self_assessment product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
taxYearEndrequired | query | integer |
Responses
200 OK, application/json
Body: object (MtdItObligations).
| Field | Type | Description |
|---|---|---|
sourcerequired | object (MtdItSource) | |
source.idrequired | string (uuid) | |
source.clientIdrequired | string (uuid) | |
source.kindrequired | string (MtdItSourceKind) | One of: |
source.namerequired | string | |
source.hmrcBusinessIdrequired | stringnullable | |
source.periodTyperequired | string (MtdItPeriodType) | One of: |
source.ninoMaskrequired | stringnullable | |
source.sendingEnabledrequired | boolean | |
taxYearEndrequired | integer | |
workedOutrequired | boolean | True: from the dates and accepted updates here, not from HMRC. |
obligationsrequired | array of MtdItObligation | |
obligations[].quarterrequired | integer | |
obligations[].fromrequired | string (date) | example "2026-03-31" |
obligations[].obligationEndrequired | string (date) | example "2026-03-31" |
obligations[].duerequired | string (date) | example "2026-03-31" |
obligations[].metrequired | boolean | |
updatesrequired | array of MtdItUpdate | |
updates[].idrequired | string (uuid) | |
updates[].sourceIdrequired | string (uuid) | |
updates[].taxYearEndrequired | integer | |
updates[].periodStartrequired | string (date) | example "2026-03-31" |
updates[].periodEndrequired | string (date) | example "2026-03-31" |
updates[].figuresrequired | object | Cumulative from 6 April, integer pence by HMRC’s field names. |
updates[].originrequired | string | |
updates[].statusrequired | string (MtdItUpdateStatus) | One of: |
updates[].hashrequired | string | |
updates[].lastErrorrequired | stringnullable | |
updates[].submittedAtrequired | 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).
Read a spreadsheet
POST/api/v1/mtd-income-tax/sources/{id}/read-sheet
- Scopes
self_assessment:write- Role
- Preparer or above
Two columns: HMRC’s field name, and the amount from 6 April. Keeps nothing.
Needs the Preparer role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
kindrequired | query | string | One of: |
idrequired | path | string (uuid) |
Request body
Required. application/json: object (SpreadsheetRows).
| Field | Type | Description |
|---|---|---|
rowsrequired | array of array of string | Label, then amount in pounds. |
Responses
200 OK, application/json
Body: object (MtdItSheetReading).
| Field | Type | Description |
|---|---|---|
figuresrequired | object | |
problemsrequired | array of string | |
ignoredrequired | array of string |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Save a cumulative update
PUT/api/v1/mtd-income-tax/sources/{id}/updates
- Scopes
self_assessment:write- Role
- Preparer or above
Figures from 6 April to the date. Nothing is sent.
Needs the Preparer role or above. Part of the self_assessment 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 (SaveMtdItUpdate).
| Field | Type | Description |
|---|---|---|
taxYearEndrequired | integer | |
periodEndrequired | string (date) | example "2026-03-31" |
originrequired | string (MtdItOrigin) | One of: |
rows | array of array of string | |
figures | object |
Responses
200 OK, application/json
Body: object (MtdItUpdate).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
sourceIdrequired | string (uuid) | |
taxYearEndrequired | integer | |
periodStartrequired | string (date) | example "2026-03-31" |
periodEndrequired | string (date) | example "2026-03-31" |
figuresrequired | object | Cumulative from 6 April, integer pence by HMRC’s field names. |
originrequired | string | |
statusrequired | string (MtdItUpdateStatus) | One of: |
hashrequired | string | |
lastErrorrequired | stringnullable | |
submittedAtrequired | 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).
Approve an update
POST/api/v1/mtd-income-tax/updates/{id}/approve
- Scopes
self_assessment:write- Role
- Reviewer or above
- Access
- A signed-in Tolvi session only, never an API token.
Never available to API keys or connected assistants.
Needs the Reviewer role or above. Part of the self_assessment 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 (MtdItHash).
| Field | Type | Description |
|---|---|---|
hashrequired | string |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Send an update
POST/api/v1/mtd-income-tax/updates/{id}/submit
- Scopes
self_assessment:write- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
- Retries
- Send an
Idempotency-Keyto make retries safe.
Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | 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 (SubmitMtdItUpdate).
| Field | Type | Description |
|---|---|---|
hashrequired | string | |
clientFactsrequired | object |
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).
Where a final declaration has got to
GET/api/v1/mtd-income-tax/declarations
- Scopes
self_assessment:read
Part of the self_assessment product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
taxYearEndrequired | query | integer | |
clientIdrequired | query | string (uuid) |
Responses
200 OK, application/json
Body: object (MtdItDeclaration).
| Field | Type | Description |
|---|---|---|
clientIdrequired | string (uuid) | |
taxYearEndrequired | integer | |
duerequired | string (date) | example "2026-03-31" |
stagerequired | string | |
calculationIdrequired | stringnullable | |
calculationrequired | objectnullable | |
errorsrequired | array of string | |
clientConfirmedOnrequired | string (date)nullable | example "2026-03-31" |
declaredAtrequired | string (date-time)nullable | |
sendingEnabledrequired | boolean | |
confirmationrequired | object |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Ask for the calculation
POST/api/v1/mtd-income-tax/declarations/calculate
- Scopes
self_assessment:write- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
HMRC’s intent to finalise. Errors stop the declaration. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (MtdItDeclarationStep).
| Field | Type | Description |
|---|---|---|
clientIdrequired | string (uuid) | |
taxYearEndrequired | integer | |
calculationId | string | |
approvedOn | string (date) | example "2026-03-31" |
confirmation | object | |
clientFacts | object |
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Mark the calculation reviewed
POST/api/v1/mtd-income-tax/declarations/review
- Scopes
self_assessment:write- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (MtdItDeclarationStep).
The fields are as shown above.
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Record the client’s approval
POST/api/v1/mtd-income-tax/declarations/client-approval
- Scopes
self_assessment:write- Role
- Preparer or above
- Access
- A signed-in Tolvi session only, never an API token.
Never available to API keys or connected assistants.
Needs the Preparer role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (MtdItDeclarationStep).
The fields are as shown above.
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Submit the final declaration
POST/api/v1/mtd-income-tax/declarations/submit
- Scopes
self_assessment:write- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
- Retries
- Send an
Idempotency-Keyto make retries safe.
With the calculation the client agreed to, and the agent’s confirmation. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the self_assessment product: the firm must have it and you must have access to it.
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 (MtdItDeclarationStep).
The fields are as shown above.
Responses
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 409 Conflict, 422 Unprocessable content, 429 Too many requests, as problem details (application/problem+json).