Skip to main content

Self Assessment

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

List returns

GET/api/v1/self-assessment/returns

Scopes
self_assessment:read

Every client’s return, with its status and how long is left. Filter by client, tax year or status. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns
NameInTypeDescription
statusquerystring
taxYearEndqueryinteger
clientIdquerystring (uuid)

Responses

200 OK, application/json

Body: object (SaReturnList).

200 OK response for GET /api/v1/self-assessment/returns
FieldTypeDescription
itemsrequiredarray of SaReturnRow
items[].​idrequiredstring (uuid)
items[].​clientIdrequiredstring (uuid)
items[].​clientNamerequiredstring
items[].​taxYearEndrequiredinteger
items[].​returnTyperequiredstring (SaReturnType)

One of: sa100, sa800, sa900

items[].​taxYearrequiredstring

example "2025/26"

items[].​statusrequiredstring (SaReturnStatus)

One of: draft, in_review, approved, filing, filed

items[].​dueDaterequiredstring (date)

example "2026-03-31"

items[].​daysLeftrequiredinteger

Days to the online deadline; negative when overdue.

items[].​openReviewPointsrequiredinteger

Open review points.

items[].​updatedAtrequiredstring (date-time)
taxYearEndsrequiredarray of integer

Tax years Tolvi can prepare, by the year they end.

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

Start a return

POST/api/v1/self-assessment/returns

Scopes
self_assessment:write
Role
Preparer or above
Retries
Send an Idempotency-Key to make retries safe.

Preparers and above. One of each form per client and tax year: an SA100, an SA800 or an SA900. Last year’s details carry forward, and on an SA900 the tax pool.

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

Parameters for POST /api/v1/self-assessment/returns
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 (CreateSaReturnRequest).

Request body for POST /api/v1/self-assessment/returns
FieldTypeDescription
clientIdrequiredstring (uuid)
taxYearEndrequiredinteger

The year the tax year ends: 2026 is 2025/26. Tolvi can prepare 2025/26 onwards.

example 2026

returnTypestring (SaReturnType)

SA100 unless said otherwise. An SA800 needs a partnership or LLP client.

One of: sa100, sa800, sa900

Responses

201 Created, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

201 Created response for POST /api/v1/self-assessment/returns
FieldTypeDescription
idrequiredstring (uuid)
clientIdrequiredstring (uuid)
clientNamerequiredstring
taxYearEndrequiredinteger
returnTyperequiredstring (SaReturnType)

One of: sa100, sa800, sa900

taxYearrequiredstring

example "2025/26"

statusrequiredstring (SaReturnStatus)

One of: draft, in_review, approved, filing, filed

dueDaterequiredstring (date)

example "2026-03-31"

daysLeftrequiredinteger

Days to the online deadline; negative when overdue.

openReviewPointsrequiredinteger

Open review points.

updatedAtrequiredstring (date-time)
importedLastYearrequiredobject (SaPriorYearFigures)nullable

Last year’s figures brought in from other software, if any. For comparison: on no return and in no calculation.

importedLastYear.​taxYearEndrequiredinteger
importedLastYear.​figuresrequiredobject

Pence, by field.

partnersrequiredarray of SaReturnPartner

SA800 only: who shares the statement.

partners[].​namerequiredstring

As on the partnership statement.

partners[].​utrrequiredstring

Ten digits.

partners[].​shareBpsrequiredinteger

Profit share in basis points. Across the partners they add up to 10000.

partners[].​clientIdstring (uuid)nullable

Their own client record at this firm: their SA100 is offered their SA104 as a suggestion.

partners[].​dateAppointedstring (date)nullable

example "2026-03-31"

partners[].​dateCeasedstring (date)nullable

example "2026-03-31"

trustKindrequiredstringnullable

SA900 only: what the return says it is, in words.

pagesrequiredobject

Box values by page: { sa100: { INC1: 12000 }, sa102: [{ EMP1: 4000000 }] }. Money is integer pence. Sensitive boxes aren’t here.

sourcesrequiredobject

Where figures came from, keyed sa102.0.EMP1. For AI Mode: { source: "ai", evidence: [{ kind, label, quote, value, documentId, documentPage }], reviewedAt }.

masksrequiredobject

Masked National Insurance number, date of birth and bank details.

otherPaymentsrequiredobject

{ paymentsOnAccountMade, otherPaymentsMade } in pence.

prepModerequiredstring (SaPrepMode)nullable

How it’s being prepared, once someone has chosen.

One of: simple_step, ai, full

aiFiguresToConfirmrequiredinteger

Figures AI filled that a person hasn’t checked. It can’t go for review until this is nil.

calculationrequiredobject

{ c, cal, sa302, unsupported, filable }: HMRC’s calculation for the pages Tolvi covers.

problemsrequiredarray of SaProblem

What HMRC’s rules would refuse.

problems[].​pagerequiredstring

example "SA102"

problems[].​boxrequiredstring

example "EMP4"

problems[].​messagerequiredstring
returnHashrequiredstring

Send this back when approving: it fingerprints the figures.

utrrequiredstringnullable
approvedByNamerequiredstringnullable
approvedAtrequiredstring (date-time)nullable
clientApprovedOnrequiredstring (date)nullable

example "2026-03-31"

clientApprovalCurrentrequiredboolean

The client approved these figures, not earlier ones.

approverRolerequiredstring (ApproverRole)

Who may approve in this firm: partners only, or managers and partners.

One of: partner, manager

canApproverequiredboolean
cannotApproveReasonrequiredstringnullable
canSubmitrequiredboolean
cannotSubmitReasonrequiredstringnullable
filingEnabledrequiredboolean

Whether filing is switched on: off until HMRC has approved Tolvi.

filingModerequiredstring (SaFilingMode)

One of: test, test_in_live, live

declarationrequiredobject

{ version, text }: the declaration to accept before filing.

reviewPointsrequiredarray of SaReviewPoint
reviewPoints[].​idrequiredstring (uuid)
reviewPoints[].​boxKeyrequiredstringnullable
reviewPoints[].​textrequiredstring
reviewPoints[].​statusrequiredstring (SaReviewPointStatus)

One of: open, cleared

reviewPoints[].​raisedByNamerequiredstringnullable
reviewPoints[].​createdAtrequiredstring (date-time)
eventsrequiredarray of SaEvent
events[].​idrequiredstring (uuid)
events[].​kindrequiredstring
events[].​actorNamerequiredstringnullable
events[].​noterequiredstringnullable
events[].​createdAtrequiredstring (date-time)
submissionsrequiredarray of SaSubmission
submissions[].​idrequiredstring (uuid)
submissions[].​moderequiredstring (SaSubmissionMode)

test and test_in_live never reach a taxpayer’s record.

One of: test, test_in_live, live

submissions[].​statusrequiredstring (SaSubmissionStatus)

One of: pending, acknowledged, accepted, rejected, unknown

submissions[].​correlationIdrequiredstringnullable
submissions[].​irmarkrequiredstring
submissions[].​errorsrequiredarray of objectnullable

HMRC’s errors: { number, text, location }.

submissions[].​messagerequiredstringnullable

What this means, in plain words.

submissions[].​receiptAtrequiredstring (date-time)nullable
submissions[].​submittedByNamerequiredstringnullable
submissions[].​createdAtrequiredstring (date-time)

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 return

GET/api/v1/self-assessment/returns/{id}

Scopes
self_assessment:read

The boxes and where each came from, HMRC’s calculation for them, what HMRC’s rules would refuse, review points and history. The National Insurance number, date of birth and bank details are only ever masked. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Change a return

PATCH/api/v1/self-assessment/returns/{id}

Scopes
self_assessment:write
Role
Preparer or above

Preparers and above. Changing an approved or reviewed return takes it back to draft. Refused once it’s with HMRC.

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

Parameters for PATCH /api/v1/self-assessment/returns/{id}
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (UpdateSaReturnRequest).

Send only what changes. Changing an approved return takes it back to draft.

Request body for PATCH /api/v1/self-assessment/returns/{id}
FieldTypeDescription
changesarray of object

{ page, instance?, box, value, source? }. Box is HMRC’s mnemonic, such as INC1; money is integer pence; null clears.

addPagesarray of string

Pages to add: sa101, sa102, sa102m, sa103f, sa103s, sa103l, sa104f, sa104s, sa105, sa106, sa107, sa108, sa109.

removePagesarray of object

{ page, instance? } to remove.

otherPaymentsobject

{ paymentsOnAccountMade, otherPaymentsMade } in pence: payments towards this year, for the balance due.

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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 what a return needs

GET/api/v1/self-assessment/returns/{id}/plan

Scopes
self_assessment:read

The questions that decide which pages and boxes a return needs, the answers so far, and the steps they lead to. Used by Simple Step and AI Mode alike. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/plan
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaPlan).

Which pages and steps a return needs, from the answers so far. Nothing counts as a no until it’s answered.

200 OK response for GET /api/v1/self-assessment/returns/{id}/plan
FieldTypeDescription
questionnaireVersionrequiredstring
questionsrequiredarray of SaQuestion

The questions that apply, given the answers.

questions[].​idrequiredstring
questions[].​textrequiredstring
questions[].​helpstring
questions[].​kindrequiredstring (SaQuestionKind)

One of: yesno, count

questions[].​sectionstring

The SA100 section a yes opens.

questions[].​outOfScopeobject

{ form, title }: a page Tolvi can’t prepare yet, if the answer is yes.

answersrequiredobject

Answers so far.

unansweredrequiredarray of string
completerequiredboolean
pagesNeededrequiredobject

{ sa102: 2, sa103s: 0, ... }.

outOfScoperequiredarray of object

{ form, title }: pages the answers call for that can’t be filed from Tolvi.

stepsrequiredarray of SaPlanStep
steps[].​keyrequiredstring

example "sa102.0"

steps[].​titlerequiredstring
steps[].​pagerequiredstring

example "sa102"

steps[].​instancerequiredintegernullable
steps[].​boxesrequiredarray of stringnullable

The boxes on this step. Null means every box on the page.

extraPagesrequiredarray of object

{ page, instance }: pages with figures the answers no longer call for. A person decides.

prepModerequiredstring (SaPrepMode)nullable

How it’s being prepared, once someone has chosen.

One of: simple_step, ai, full

suggestedobject

{ questionId: { value, why } }: answers Tolvi can suggest from last year, the client’s record and what HMRC holds. None counts until a person accepts it.

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

Answer what a return needs

PUT/api/v1/self-assessment/returns/{id}/plan

Scopes
self_assessment:write
Role
Preparer or above

Preparers and above. Saves answers and brings the pages into line. Pages with figures are never removed: they’re listed in extraPages for a person to decide.

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

Parameters for PUT /api/v1/self-assessment/returns/{id}/plan
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SaveSaAnswersRequest).

Answers merge over what’s there. Pages are added to match, and empty pages no longer needed are removed. Pages with figures are never removed.

Request body for PUT /api/v1/self-assessment/returns/{id}/plan
FieldTypeDescription
answersrequiredobject

{ questionId: true, otherId: 2 }.

prepModestring (SaPrepMode)

How it’s being prepared, once someone has chosen.

One of: simple_step, ai, full

Responses

200 OK, application/json

Body: object (SaPlan).

Which pages and steps a return needs, from the answers so far. Nothing counts as a no until it’s answered.

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 full return

GET/api/v1/self-assessment/returns/{id}/pdf

Scopes
self_assessment:read

Every page of the return in the style of HMRC’s forms, then the calculation, as a PDF: to send the client for their approval, or to file another way until Tolvi can. Sensitive boxes appear masked. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/pdf
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK

A PDF.

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

Download the SA302

GET/api/v1/self-assessment/returns/{id}/sa302

Scopes
self_assessment:read

The tax calculation alone, in the order of HMRC’s SA302, as a PDF. Prepared from the return’s figures, and says how far the return has got; not issued by HMRC. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/sa302
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK

A PDF.

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

Set the partners on an SA800

PUT/api/v1/self-assessment/returns/{id}/partners

Scopes
self_assessment:write
Role
Preparer or above

Who shares the partnership statement and how. The statement’s figures are allocated to them, and a partner with a client record here is offered their SA104 as a suggestion on their own SA100. Changing an approved return takes it back to draft.

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

Parameters for PUT /api/v1/self-assessment/returns/{id}/partners
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SetSaPartnersRequest).

Replaces the partners and allocates the statement to them. A share a person typed over is replaced too. Changing an approved return takes it back to draft.

Request body for PUT /api/v1/self-assessment/returns/{id}/partners
FieldTypeDescription
partnersrequiredarray of SaReturnPartner
partners[].​namerequiredstring

As on the partnership statement.

partners[].​utrrequiredstring

Ten digits.

partners[].​shareBpsrequiredinteger

Profit share in basis points. Across the partners they add up to 10000.

partners[].​clientIdstring (uuid)nullable

Their own client record at this firm: their SA100 is offered their SA104 as a suggestion.

partners[].​dateAppointedstring (date)nullable

example "2026-03-31"

partners[].​dateCeasedstring (date)nullable

example "2026-03-31"

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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 an R185

POST/api/v1/self-assessment/returns/{id}/r185

Scopes
self_assessment:read

A statement for a beneficiary of a trust or estate, worked from the SA900, as a PDF. A person checks and signs it; it isn’t filed and isn’t kept. Trust management expenses aren’t taken off: send your own figures in overrides. Not issued by HMRC. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/self-assessment/returns/{id}/r185
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (MakeR185Request).

A statement for a beneficiary, worked from the SA900. Not filed. A person checks and signs it.

Request body for POST /api/v1/self-assessment/returns/{id}/r185
FieldTypeDescription
kindrequiredstring (R185Kind)

One of: trust_discretionary, trust_non_discretionary, estate, settlor

beneficiaryrequiredstring
shareBpsinteger

Their share of the income in basis points. Needed unless discretionary.

paymentIndexinteger

Which row of box 14, from 0. Needed for a discretionary statement.

overridesobject

A person’s own figures in pence, by the form’s box: { "3": 1000, "3.tax": 250 }.

deceasedNamestring
dateOfDeathstring (date)

example "2026-03-31"

Responses

200 OK

A PDF.

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

Bring in section T

POST/api/v1/self-assessment/returns/{id}/import/working-papers

Scopes
self_assessment:write
Role
Preparer or above

Fills the SA103 from a sole trader’s section T in Working Papers. Answers such as dates stay for a person to give.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/import/working-papers
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (ImportSaFromWorkingPapersRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/import/working-papers
FieldTypeDescription
engagementIdrequiredstring (uuid)

A sole trader engagement of this client, with section T worked.

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

See what HMRC holds

GET/api/v1/self-assessment/returns/{id}/hmrc-data

Scopes
self_assessment:read

As last fetched: figures you can apply, and the Self Assessment account. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/hmrc-data
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaHmrcData).

200 OK response for GET /api/v1/self-assessment/returns/{id}/hmrc-data
FieldTypeDescription
itemsrequiredarray of SaHmrcDataItem
items[].​sourcerequiredstring (SaHmrcDataSource)

One of: individual_employment, individual_income, individual_tax, individual_benefits, child_benefit, winter_fuel, national_insurance, marriage_allowance, sa_account

items[].​outcomerequiredstring (SaHmrcDataOutcome)

One of: ok, not_found, not_authorised

items[].​fetchedAtrequiredstring (date-time)
suggestionsrequiredarray of SaHmrcSuggestion
suggestions[].​pagerequiredstring
suggestions[].​instancerequiredintegernullable

Which SA102, when the return already has a page for this employer.

suggestions[].​employerPayeReferencerequiredstringnullable
suggestions[].​boxrequiredstring
suggestions[].​labelrequiredstring
suggestions[].​sourcerequiredstring
suggestions[].​valuerequiredobject

HMRC’s figure: pence for money.

suggestions[].​currentrequiredobjectnullable

The figure on the return now, or null.

accountrequiredobject (SaHmrcAccount)nullable

From View Self Assessment Account, in pence.

account.​totalBalancePencerequiredintegernullable

Integer pence (GBP).

account.​totalOverduePencerequiredintegernullable

Integer pence (GBP).

account.​totalPayablePencerequiredintegernullable

Integer pence (GBP).

account.​totalCreditPencerequiredintegernullable

Integer pence (GBP).

account.​earliestPayableDueDaterequiredstring (date)nullable

example "2026-03-31"

noterequiredstring

What HMRC doesn’t give, so nobody waits for it.

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

Ask HMRC what it holds

POST/api/v1/self-assessment/returns/{id}/hmrc-data/refresh

Scopes
self_assessment:write
Role
Preparer or above

Preparers and above, with a connected HMRC account authorised for this client.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/hmrc-data/refresh
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (RefreshSaHmrcDataRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/hmrc-data/refresh
FieldTypeDescription
agentAccountIdrequiredstring (uuid)
clientFactsrequiredobject

The browser’s facts for HMRC’s fraud prevention headers.

Responses

200 OK, application/json

Body: object (SaHmrcData).

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

Put HMRC’s figures on the return

POST/api/v1/self-assessment/returns/{id}/hmrc-data/apply

Scopes
self_assessment:write
Role
Preparer or above

The figures you choose. An SA102 is added for an employer the return doesn’t have.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/hmrc-data/apply
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (ApplySaHmrcDataRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/hmrc-data/apply
FieldTypeDescription
selectionsrequiredarray of SaHmrcSelection

The figures from what HMRC holds to put on the return.

selections[].​boxrequiredstring

example "EMP1"

selections[].​employerPayeReferencestringnullable

For an SA102: the employer.

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Send for review

POST/api/v1/self-assessment/returns/{id}/send-for-review

Scopes
self_assessment:write
Role
Preparer or above

Preparers and above, from draft.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/send-for-review
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SaNoteRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/send-for-review
FieldTypeDescription
notestring

up to 2000 characters

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Return to draft

POST/api/v1/self-assessment/returns/{id}/return-to-draft

Scopes
review:write
Role
Reviewer or above

Reviewers and above. An approval is lost.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/return-to-draft
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SaNoteRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/return-to-draft
FieldTypeDescription
notestring

up to 2000 characters

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Raise a review point

POST/api/v1/self-assessment/returns/{id}/review-points

Scopes
review:write
Role
Reviewer or above

Reviewers and above. Open points stop a return being approved.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/review-points
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (RaiseSaReviewPointRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/review-points
FieldTypeDescription
textrequiredstring

1 to 2000 characters

boxKeystring

The box it’s about, such as sa102.0.EMP1.

Responses

201 Created, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Clear a review point

POST/api/v1/self-assessment/returns/{id}/review-points/{pointId}/clear

Scopes
review:write
Role
Reviewer or above

Reviewers and above.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/review-points/{pointId}/clear
NameInTypeDescription
idrequiredpathstring (uuid)
pointIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Approve a return

POST/api/v1/self-assessment/returns/{id}/approve

Scopes
review:write
Role
Manager or above
Access
A signed-in Tolvi session only, never an API token.

A partner, signed in, or a manager where the firm allows it (403 otherwise). Refused with open review points, with anything HMRC’s rules would refuse, or if the figures moved since you reviewed them. Never available to 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

Parameters for POST /api/v1/self-assessment/returns/{id}/approve
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (ApproveSaReturnRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/approve
FieldTypeDescription
returnHashrequiredstring

The hash from the return you reviewed: refused if the figures have moved since.

notestring

up to 2000 characters

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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 the client’s approval

POST/api/v1/self-assessment/returns/{id}/client-approval

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

HMRC requires the client to confirm in writing the copy they were sent. Applies only to these figures. Never available to 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.

Parameters

Parameters for POST /api/v1/self-assessment/returns/{id}/client-approval
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (RecordSaClientApprovalRequest).

HMRC requires the client to confirm in writing that the return they were sent is correct and complete, before an agent files it.

Request body for POST /api/v1/self-assessment/returns/{id}/client-approval
FieldTypeDescription
approvedOnrequiredstring (date)

example "2026-03-31"

notestring

How they confirmed, such as an email.

up to 2000 characters

returnHashrequiredstring

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

File with HMRC

POST/api/v1/self-assessment/returns/{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-Key to make retries safe.

A manager or partner, signed in with a second factor, once these figures are approved and the client has confirmed them. Answers 503 until filing is switched on, once HMRC has approved Tolvi. Never available to 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

Parameters for POST /api/v1/self-assessment/returns/{id}/submit
NameInTypeDescription
idrequiredpathstring (uuid)
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 (SubmitSaReturnRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/submit
FieldTypeDescription
returnHashrequiredstring
agentAccountIdrequiredstring (uuid)
declarationrequiredobject

{ accepted: true, version }: the agent’s declaration HMRC requires.

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Ask HMRC for its answer

POST/api/v1/self-assessment/returns/{id}/submissions/{submissionId}/poll

Scopes
self_assessment:read

While HMRC is checking a return. Tolvi also asks by itself. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/self-assessment/returns/{id}/submissions/{submissionId}/poll
NameInTypeDescription
idrequiredpathstring (uuid)
submissionIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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 AI Mode on a return

GET/api/v1/self-assessment/returns/{id}/ai

Scopes
self_assessment:read

The conversation, the documents, the plan, and about what the next turn would cost. Not available to connected assistants. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/ai
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaAiState).

AI Mode on a return: the conversation, the documents, and what it would cost to carry on.

200 OK response for GET /api/v1/self-assessment/returns/{id}/ai
FieldTypeDescription
availablerequiredboolean

Whether the firm has AI Mode on.

unavailableReasonrequiredstringnullable
messagesrequiredarray of SaAiMessage
messages[].​idrequiredstring (uuid)
messages[].​rolerequiredstring (SaAiMessageRole)

One of: person, assistant

messages[].​textrequiredstring
messages[].​outcomerequiredobjectnullable

On an assistant’s turn: { applied, cleared, refused, answers, stillNeeded, tokens }.

messages[].​createdAtrequiredstring (date-time)
documentsrequiredarray of SaDocument
documents[].​idrequiredstring (uuid)
documents[].​fileNamerequiredstring
documents[].​contentTyperequiredstring
documents[].​sizeBytesrequiredinteger
documents[].​statusrequiredstring (SaDocumentStatus)

One of: pending_upload, pending_scan, available, rejected

documents[].​rejectedReasonrequiredstringnullable
documents[].​readingStatusrequiredstring (SaDocumentReadingStatus)

One of: not_read, read, failed

documents[].​readingrequiredobjectnullable

{ documentType, taxYearShown, readings, warnings }.

documents[].​createdAtrequiredstring (date-time)
planrequiredobject (SaPlan)

Which pages and steps a return needs, from the answers so far. Nothing counts as a no until it’s answered.

plan.​questionnaireVersionrequiredstring
plan.​questionsrequiredarray of SaQuestion

The questions that apply, given the answers.

plan.​questions[].​idrequiredstring
plan.​questions[].​textrequiredstring
plan.​questions[].​helpstring
plan.​questions[].​kindrequiredstring (SaQuestionKind)

One of: yesno, count

plan.​questions[].​sectionstring

The SA100 section a yes opens.

plan.​questions[].​outOfScopeobject

{ form, title }: a page Tolvi can’t prepare yet, if the answer is yes.

plan.​answersrequiredobject

Answers so far.

plan.​unansweredrequiredarray of string
plan.​completerequiredboolean
plan.​pagesNeededrequiredobject

{ sa102: 2, sa103s: 0, ... }.

plan.​outOfScoperequiredarray of object

{ form, title }: pages the answers call for that can’t be filed from Tolvi.

plan.​stepsrequiredarray of SaPlanStep
plan.​steps[].​keyrequiredstring

example "sa102.0"

plan.​steps[].​titlerequiredstring
plan.​steps[].​pagerequiredstring

example "sa102"

plan.​steps[].​instancerequiredintegernullable
plan.​steps[].​boxesrequiredarray of stringnullable

The boxes on this step. Null means every box on the page.

plan.​extraPagesrequiredarray of object

{ page, instance }: pages with figures the answers no longer call for. A person decides.

plan.​prepModerequiredstring (SaPrepMode)nullable

How it’s being prepared, once someone has chosen.

One of: simple_step, ai, full

plan.​suggestedobject

{ questionId: { value, why } }: answers Tolvi can suggest from last year, the client’s record and what HMRC holds. None counts until a person accepts it.

phaserequiredstring (SaAiPhase)

What the next turn does: finds out what’s needed, fills the boxes, or acts on a request.

One of: questions, complete, change

estimaterequiredobject (SaAiEstimate)nullable
estimate.​tokensrequiredinteger

Tolvi AI tokens, about.

estimate.​affordablerequiredboolean
estimate.​reasonrequiredstringnullable

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

Tell or ask AI Mode

POST/api/v1/self-assessment/returns/{id}/ai/messages

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Preparers and above, on a draft. Spends the firm’s Tolvi AI tokens. Any figure it changes is read by Tolvi from the evidence it cites, and goes back to needing a person’s check. Refused figures are returned with the reason.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/ai/messages
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SendSaAiMessageRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/ai/messages
FieldTypeDescription
textrequiredstring

What you want to tell or ask. National Insurance numbers, UTRs and bank details are removed before it’s stored or sent.

1 to 4000 characters

Responses

200 OK, application/json

Body: object (SaAiTurn).

One turn of AI Mode. Every figure was read from the evidence it cites by Tolvi, not the model.

200 OK response for POST /api/v1/self-assessment/returns/{id}/ai/messages
FieldTypeDescription
availablerequiredboolean

Whether the firm has AI Mode on.

unavailableReasonrequiredstringnullable
messagesrequiredarray of SaAiMessage
messages[].​idrequiredstring (uuid)
messages[].​rolerequiredstring (SaAiMessageRole)

One of: person, assistant

messages[].​textrequiredstring
messages[].​outcomerequiredobjectnullable

On an assistant’s turn: { applied, cleared, refused, answers, stillNeeded, tokens }.

messages[].​createdAtrequiredstring (date-time)
documentsrequiredarray of SaDocument
documents[].​idrequiredstring (uuid)
documents[].​fileNamerequiredstring
documents[].​contentTyperequiredstring
documents[].​sizeBytesrequiredinteger
documents[].​statusrequiredstring (SaDocumentStatus)

One of: pending_upload, pending_scan, available, rejected

documents[].​rejectedReasonrequiredstringnullable
documents[].​readingStatusrequiredstring (SaDocumentReadingStatus)

One of: not_read, read, failed

documents[].​readingrequiredobjectnullable

{ documentType, taxYearShown, readings, warnings }.

documents[].​createdAtrequiredstring (date-time)
planrequiredobject (SaPlan)

Which pages and steps a return needs, from the answers so far. Nothing counts as a no until it’s answered.

plan.​questionnaireVersionrequiredstring
plan.​questionsrequiredarray of SaQuestion

The questions that apply, given the answers.

plan.​questions[].​idrequiredstring
plan.​questions[].​textrequiredstring
plan.​questions[].​helpstring
plan.​questions[].​kindrequiredstring (SaQuestionKind)

One of: yesno, count

plan.​questions[].​sectionstring

The SA100 section a yes opens.

plan.​questions[].​outOfScopeobject

{ form, title }: a page Tolvi can’t prepare yet, if the answer is yes.

plan.​answersrequiredobject

Answers so far.

plan.​unansweredrequiredarray of string
plan.​completerequiredboolean
plan.​pagesNeededrequiredobject

{ sa102: 2, sa103s: 0, ... }.

plan.​outOfScoperequiredarray of object

{ form, title }: pages the answers call for that can’t be filed from Tolvi.

plan.​stepsrequiredarray of SaPlanStep
plan.​steps[].​keyrequiredstring

example "sa102.0"

plan.​steps[].​titlerequiredstring
plan.​steps[].​pagerequiredstring

example "sa102"

plan.​steps[].​instancerequiredintegernullable
plan.​steps[].​boxesrequiredarray of stringnullable

The boxes on this step. Null means every box on the page.

plan.​extraPagesrequiredarray of object

{ page, instance }: pages with figures the answers no longer call for. A person decides.

plan.​prepModerequiredstring (SaPrepMode)nullable

How it’s being prepared, once someone has chosen.

One of: simple_step, ai, full

plan.​suggestedobject

{ questionId: { value, why } }: answers Tolvi can suggest from last year, the client’s record and what HMRC holds. None counts until a person accepts it.

phaserequiredstring (SaAiPhase)

What the next turn does: finds out what’s needed, fills the boxes, or acts on a request.

One of: questions, complete, change

estimaterequiredobject (SaAiEstimate)nullable
estimate.​tokensrequiredinteger

Tolvi AI tokens, about.

estimate.​affordablerequiredboolean
estimate.​reasonrequiredstringnullable
replyrequiredobject (SaAiMessage)
reply.​idrequiredstring (uuid)
reply.​rolerequiredstring (SaAiMessageRole)

One of: person, assistant

reply.​textrequiredstring
reply.​outcomerequiredobjectnullable

On an assistant’s turn: { applied, cleared, refused, answers, stillNeeded, tokens }.

reply.​createdAtrequiredstring (date-time)

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

Have AI Mode fill the boxes

POST/api/v1/self-assessment/returns/{id}/ai/complete

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Preparers and above, on a draft, once the questions are answered. Spends the firm’s Tolvi AI tokens. It fills only what the evidence supports. A person then checks each figure.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/ai/complete
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaAiTurn).

One turn of AI Mode. Every figure was read from the evidence it cites by Tolvi, not the model.

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 figures AI filled

POST/api/v1/self-assessment/returns/{id}/ai/confirm

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Preparers and above, signed in. Records who checked each figure. Doesn’t change the figures or approve anything. Never available to 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.

Parameters

Parameters for POST /api/v1/self-assessment/returns/{id}/ai/confirm
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (ConfirmSaAiFiguresRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/ai/confirm
FieldTypeDescription
boxKeysrequiredarray of string

Boxes you have checked, keyed sa102.0.EMP1.

Responses

200 OK, application/json

Body: object (SaReturn).

A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.

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

Add a document for AI Mode

POST/api/v1/self-assessment/returns/{id}/documents

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

A PDF or photo, such as a P60. Returns where to upload it. Nothing reads it until the malware scan is clean.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/documents
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (CreateSaDocumentRequest).

Request body for POST /api/v1/self-assessment/returns/{id}/documents
FieldTypeDescription
fileNamerequiredstring

1 to 200 characters; example "P60 2026.pdf"

contentTyperequiredstring

example "application/pdf"

sizeBytesrequiredinteger

Responses

201 Created, application/json

Body: object (SaDocumentUpload).

201 Created response for POST /api/v1/self-assessment/returns/{id}/documents
FieldTypeDescription
documentrequiredobject (SaDocument)
document.​idrequiredstring (uuid)
document.​fileNamerequiredstring
document.​contentTyperequiredstring
document.​sizeBytesrequiredinteger
document.​statusrequiredstring (SaDocumentStatus)

One of: pending_upload, pending_scan, available, rejected

document.​rejectedReasonrequiredstringnullable
document.​readingStatusrequiredstring (SaDocumentReadingStatus)

One of: not_read, read, failed

document.​readingrequiredobjectnullable

{ documentType, taxYearShown, readings, warnings }.

document.​createdAtrequiredstring (date-time)
uploadrequiredobject

{ url, headers, expiresAt }: PUT the file here.

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

Finish uploading a document

POST/api/v1/self-assessment/returns/{id}/documents/{documentId}/complete

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Checks the stored file and starts the malware scan.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/documents/{documentId}/complete
NameInTypeDescription
idrequiredpathstring (uuid)
documentIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaDocument).

200 OK response for POST /api/v1/self-assessment/returns/{id}/documents/{documentId}/complete
FieldTypeDescription
idrequiredstring (uuid)
fileNamerequiredstring
contentTyperequiredstring
sizeBytesrequiredinteger
statusrequiredstring (SaDocumentStatus)

One of: pending_upload, pending_scan, available, rejected

rejectedReasonrequiredstringnullable
readingStatusrequiredstring (SaDocumentReadingStatus)

One of: not_read, read, failed

readingrequiredobjectnullable

{ documentType, taxYearShown, readings, warnings }.

createdAtrequiredstring (date-time)

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

Have AI Mode read a document

POST/api/v1/self-assessment/returns/{id}/documents/{documentId}/read

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Spends the firm’s Tolvi AI tokens. Refused until the malware scan is clean.

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

Parameters for POST /api/v1/self-assessment/returns/{id}/documents/{documentId}/read
NameInTypeDescription
idrequiredpathstring (uuid)
documentIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaDocument).

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 a link to a document

GET/api/v1/self-assessment/returns/{id}/documents/{documentId}/download

Scopes
self_assessment:read

Refused until the malware scan is clean. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for GET /api/v1/self-assessment/returns/{id}/documents/{documentId}/download
NameInTypeDescription
idrequiredpathstring (uuid)
documentIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object.

200 OK response for GET /api/v1/self-assessment/returns/{id}/documents/{documentId}/download
FieldTypeDescription
urlrequiredstring
expiresAtrequiredstring

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

Remove a document

DELETE/api/v1/self-assessment/returns/{id}/documents/{documentId}

Scopes
self_assessment:write
Role
Preparer or above
Access
A signed-in Tolvi session only, never an API token.

Deletes the file. Figures already taken from it stay on the return with the record of where they came from.

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

Parameters for DELETE /api/v1/self-assessment/returns/{id}/documents/{documentId}
NameInTypeDescription
idrequiredpathstring (uuid)
documentIdrequiredpathstring (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 HMRC accounts

GET/api/v1/self-assessment/agent-accounts

Scopes
self_assessment:read

Names and status only: a saved sign-in is never returned. Part of the self_assessment product: the firm must have it and you must have access to it.

Responses

200 OK, application/json

Body: object (SaAgentAccountList).

200 OK response for GET /api/v1/self-assessment/agent-accounts
FieldTypeDescription
itemsrequiredarray of SaAgentAccount
items[].​idrequiredstring (uuid)
items[].​namerequiredstring
items[].​credentialStatusrequiredstring (SaCredentialStatus)

One of: not_saved, saved, needs_update

items[].​userIdHintrequiredstringnullable

The last characters of the user ID, to tell accounts apart.

items[].​lastUsedAtrequiredstring (date-time)nullable
items[].​connectionStatusrequiredstring (SaConnectionStatus)

One of: not_connected, connected, needs_reconnect

items[].​grantExpiresAtrequiredstring (date-time)nullable

HMRC’s authority ends 18 months after it was given.

items[].​reconnectSoonrequiredboolean
hmrcAvailablerequiredboolean

Whether Tolvi can reach HMRC on this deployment.

canStoreCredentialsrequiredboolean

Whether this deployment can store sign-ins (encryption is set up).

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

Add an HMRC account

POST/api/v1/self-assessment/agent-accounts

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Name it so people can tell them apart, such as Leeds office. Part of the self_assessment product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (CreateSaAgentAccountRequest).

Request body for POST /api/v1/self-assessment/agent-accounts
FieldTypeDescription
namerequiredstring

1 to 80 characters; example "Leeds office"

Responses

201 Created, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

201 Created response for POST /api/v1/self-assessment/agent-accounts
FieldTypeDescription
idrequiredstring (uuid)
namerequiredstring
credentialStatusrequiredstring (SaCredentialStatus)

One of: not_saved, saved, needs_update

userIdHintrequiredstringnullable

The last characters of the user ID, to tell accounts apart.

lastUsedAtrequiredstring (date-time)nullable
connectionStatusrequiredstring (SaConnectionStatus)

One of: not_connected, connected, needs_reconnect

grantExpiresAtrequiredstring (date-time)nullable

HMRC’s authority ends 18 months after it was given.

reconnectSoonrequiredboolean

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

Rename an HMRC account

PATCH/api/v1/self-assessment/agent-accounts/{id}

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for PATCH /api/v1/self-assessment/agent-accounts/{id}
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (CreateSaAgentAccountRequest).

Request body for PATCH /api/v1/self-assessment/agent-accounts/{id}
FieldTypeDescription
namerequiredstring

1 to 80 characters; example "Leeds office"

Responses

200 OK, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

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

Remove an HMRC account

DELETE/api/v1/self-assessment/agent-accounts/{id}

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Its sign-in and HMRC’s grant are deleted at once. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for DELETE /api/v1/self-assessment/agent-accounts/{id}
NameInTypeDescription
idrequiredpathstring (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).

Save the HMRC sign-in

PUT/api/v1/self-assessment/agent-accounts/{id}/credentials

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Encrypted, used only when someone allowed to file files a return, and never shown again. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for PUT /api/v1/self-assessment/agent-accounts/{id}/credentials
NameInTypeDescription
idrequiredpathstring (uuid)

Request body

Required. application/json: object (SaveSaCredentialsRequest).

Stored encrypted, used only when someone allowed to file files a return, and never returned by any route.

Request body for PUT /api/v1/self-assessment/agent-accounts/{id}/credentials
FieldTypeDescription
userIdrequiredstring

The HMRC online services user ID.

passwordrequiredstring (password)

Responses

200 OK, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

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

Delete the saved sign-in

DELETE/api/v1/self-assessment/agent-accounts/{id}/credentials

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for DELETE /api/v1/self-assessment/agent-accounts/{id}/credentials
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

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

Connect to HMRC

POST/api/v1/self-assessment/agent-accounts/{id}/authorize

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Gives the address where the account’s holder signs in at HMRC, to let Tolvi read its clients’ data for 18 months. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for POST /api/v1/self-assessment/agent-accounts/{id}/authorize
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaAuthorizeUrl).

200 OK response for POST /api/v1/self-assessment/agent-accounts/{id}/authorize
FieldTypeDescription
urlrequiredstring

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

Finish connecting to HMRC

POST/api/v1/self-assessment/agent-accounts/callback

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Posted by the page HMRC sends people back to, as the person who started. Part of the self_assessment product: the firm must have it and you must have access to it.

Request body

Required. application/json: object (SaHmrcCallbackRequest).

Request body for POST /api/v1/self-assessment/agent-accounts/callback
FieldTypeDescription
coderequiredstring
staterequiredstring

Responses

200 OK, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

The fields are as shown above.

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

Disconnect from HMRC

DELETE/api/v1/self-assessment/agent-accounts/{id}/connection

Scopes
settings:admin
Access
A signed-in Tolvi session only, never an API token.

Firm admins, signed in. Part of the self_assessment product: the firm must have it and you must have access to it.

Parameters

Parameters for DELETE /api/v1/self-assessment/agent-accounts/{id}/connection
NameInTypeDescription
idrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (SaAgentAccount).

A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.

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

Work out an informal estate computation

POST/api/v1/self-assessment/informal-estate

Scopes
self_assessment:write
Role
Preparer or above

The year-by-year breakdown HMRC asks for by letter, and HMRC’s three tests for whether the informal route fits. Gains and Capital Gains Tax are as entered. Keeps nothing. Body: deceasedName, dateOfDeath, administrationEnded, estateValuePence, years[].

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.

Responses

200 OK, application/json

Body: object.

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

Download an informal estate computation

POST/api/v1/self-assessment/informal-estate/pdf

Scopes
self_assessment:write
Role
Preparer or above

As a PDF, for a person to check and send with their letter. Same body.

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.

Responses

200 OK

A PDF.

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

Work out a trust accounts pack

POST/api/v1/self-assessment/trust-accounts

Scopes
self_assessment:write
Role
Preparer or above

Capital and income apart, a distribution statement and whether the assets agree. No statutory format was found for a non-charitable trust: this is a working layout. 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.

Request body

Required. application/json: object.

Responses

200 OK, application/json

Body: object.

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

Download a trust accounts pack

POST/api/v1/self-assessment/trust-accounts/pdf

Scopes
self_assessment:write
Role
Preparer or above

As a PDF. Same body.

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.

Responses

200 OK

A PDF.

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

Work out an R40 schedule

POST/api/v1/self-assessment/r40

Scopes
self_assessment:write
Role
Preparer or above

The figures for a repayment claim, and whether the R40 can be used. HMRC publishes no schema for it that could be found, so it can’t be sent from Tolvi and the repayment isn’t worked out. 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.

Request body

Required. application/json: object.

Responses

200 OK, application/json

Body: object.

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

Download an R40 schedule

POST/api/v1/self-assessment/r40/pdf

Scopes
self_assessment:write
Role
Preparer or above

A schedule to key from or post with evidence. It isn’t HMRC’s form. Same body.

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.

Responses

200 OK

A PDF.

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

A trust’s registration and what’s due

GET/api/v1/self-assessment/trust-registrations/{clientId}

Scopes
self_assessment:read
Role
Preparer or above

What the practice has recorded. HMRC’s Trust Registration Service has no API that could be found, so this doesn’t come from HMRC.

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

Parameters for GET /api/v1/self-assessment/trust-registrations/{clientId}
NameInTypeDescription
clientIdrequiredpathstring (uuid)

Responses

200 OK, application/json

Body: object (TrustRegistration).

200 OK response for GET /api/v1/self-assessment/trust-registrations/{clientId}
FieldTypeDescription
clientIdrequiredstring (uuid)
referencerequiredstringnullable

The UTR or Unique Reference Number HMRC gave.

registeredOnrequiredstring (date)nullable

example "2026-03-31"

taxablerequiredboolean
liableTaxYearEndsrequiredarray of number
declaredTaxYearEndsrequiredarray of number
changeAwareOnrequiredstring (date)nullable

example "2026-03-31"

duerequiredarray of TrustRegistrationDue
due[].​kindrequiredstring
due[].​duerequiredstring (date)

example "2026-03-31"

due[].​labelrequiredstring
due[].​taxYearEndinteger
remindersOnrequiredboolean

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

Record a trust’s registration

PUT/api/v1/self-assessment/trust-registrations/{clientId}

Scopes
self_assessment:write
Role
Preparer or above

The reference, whether it’s taxable, years of liability and what’s been confirmed. Reminders follow when they’re on.

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

Parameters for PUT /api/v1/self-assessment/trust-registrations/{clientId}
NameInTypeDescription
clientIdrequiredpathstring (uuid)

Request body

Required. application/json: object.

Responses

200 OK, application/json

Body: object (TrustRegistration).

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