Corporation Tax
30 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/corporation-tax/returns
- Scopes
corporation_tax:read
Every company’s returns, latest period first. Filter by client or status. Part of the corporation_tax product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
status | query | string | One of: |
clientId | query | string (uuid) |
Responses
200 OK, application/json
Body: object (CtReturnList).
| Field | Type | Description |
|---|---|---|
itemsrequired | array of CtReturnRow | |
items[].idrequired | string (uuid) | |
items[].clientIdrequired | string (uuid) | |
items[].clientNamerequired | string | |
items[].groupIdrequired | string (uuid) | Shared by the returns of one period of account. |
items[].periodOfAccountStartrequired | string (date) | example "2026-03-31" |
items[].periodOfAccountEndrequired | string (date) | example "2026-03-31" |
items[].periodStartrequired | string (date) | example "2026-03-31" |
items[].periodEndrequired | string (date) | example "2026-03-31" |
items[].periodIndexrequired | integer | This return’s place among the accounting periods, from 0. |
items[].periodCountrequired | integer | |
items[].statusrequired | string (CtReturnStatus) | One of: |
items[].sourcerequired | string (CtSource) | One of: |
items[].dueDaterequired | string (date) | When the return is due (FA 1998 Sch 18 para 14). example "2026-03-31" |
items[].openReviewPointsrequired | integer | |
items[].taxDuerequired | integernullable | Tax still to pay on this return, in integer pence, negative when overpaid. Null until it has figures the tax engine can work out. |
items[].clientConfirmationCurrentrequired | boolean | The client confirmed these figures, not earlier ones. |
items[].lastSubmissionStatusrequired | string (CtSubmissionStatus)nullable | How the latest attempt to send this return ended. Null if it has never been sent. One of: |
items[].filingEnabledrequired | boolean | Whether filing is switched on: off until HMRC’s test service passes. |
items[].returnTyperequired | string (CtReturnType) | What goes in the XML’s One of: |
items[].amendsReturnIdrequired | string (uuid)nullable | The return this amends. That one stays unchanged. |
items[].amendmentNumberrequired | integer | 1 for the first amendment. Nil on a new return. |
items[].filedElsewhereOnrequired | string (date)nullable | A person recorded it as filed outside Tolvi on this day. example "2026-03-31" |
items[].updatedAtrequired | string (date-time) |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Start a return
POST/api/v1/corporation-tax/returns
- Scopes
corporation_tax:write- Role
- Preparer or above
- Retries
- Send an
Idempotency-Keyto make retries safe.
Preparers and above, for limited companies. A period of account over 12 months makes one return per accounting period; this answers with the first, and relatedReturns names the rest. Accounting periods starting before 1 April 2023 are refused with 422. No Working Papers file or Accounts set is needed.
Needs the Preparer role or above. Part of the corporation_tax 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 (CreateCtReturnRequest).
A period of account over 12 months makes one return for each accounting period.
| Field | Type | Description |
|---|---|---|
clientIdrequired | string (uuid) | |
periodStartrequired | string (date) | Start of the period of account. Accounting periods starting before 1 April 2023 are refused. example "2026-03-31" |
periodEndrequired | string (date) | End of the period of account, at most 18 months on. example "2026-03-31" |
Responses
201 Created, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation and what stands in the way of filing.
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
clientIdrequired | string (uuid) | |
clientNamerequired | string | |
groupIdrequired | string (uuid) | Shared by the returns of one period of account. |
periodOfAccountStartrequired | string (date) | example "2026-03-31" |
periodOfAccountEndrequired | string (date) | example "2026-03-31" |
periodStartrequired | string (date) | example "2026-03-31" |
periodEndrequired | string (date) | example "2026-03-31" |
periodIndexrequired | integer | This return’s place among the accounting periods, from 0. |
periodCountrequired | integer | |
statusrequired | string (CtReturnStatus) | One of: |
sourcerequired | string (CtSource) | One of: |
dueDaterequired | string (date) | When the return is due (FA 1998 Sch 18 para 14). example "2026-03-31" |
openReviewPointsrequired | integer | |
taxDuerequired | integernullable | Tax still to pay on this return, in integer pence, negative when overpaid. Null until it has figures the tax engine can work out. |
clientConfirmationCurrentrequired | boolean | The client confirmed these figures, not earlier ones. |
lastSubmissionStatusrequired | string (CtSubmissionStatus)nullable | How the latest attempt to send this return ended. Null if it has never been sent. One of: |
filingEnabledrequired | boolean | Whether filing is switched on: off until HMRC’s test service passes. |
returnTyperequired | string (CtReturnType) | What goes in the XML’s One of: |
amendsReturnIdrequired | string (uuid)nullable | The return this amends. That one stays unchanged. |
amendmentNumberrequired | integer | 1 for the first amendment. Nil on a new return. |
filedElsewhereOnrequired | string (date)nullable | A person recorded it as filed outside Tolvi on this day. example "2026-03-31" |
updatedAtrequired | string (date-time) | |
recordFacts | object (CompanyFacts) | What the client’s record says now, to compare with what the return states. |
recordFacts.namerequired | stringnullable | The client’s name on the record. |
recordFacts.companyNumberrequired | stringnullable | Companies House number on the record. |
recordFacts.registeredOfficerequired | stringnullable | |
recordFacts.principalActivityrequired | stringnullable | |
recordFacts.signatoryNamerequired | stringnullable | The record’s, or the only serving director. |
recordFacts.directorsrequired | array of RecordDirector | Contacts whose role says director. |
recordFacts.directors[].namerequired | string | |
recordFacts.directors[].appointedOn | string (date) | example "2026-03-31" |
recordFacts.directors[].resignedOn | string (date) | example "2026-03-31" |
boxesrequired | objectnullable | { boxes, financialYears, loans }: CT600 and CT600A boxes by number. Money is integer pence, whole pounds where the form says so. Bank details are masked. Null without figures. |
problemsrequired | array of CtProblem | |
problems[].severityrequired | string (CtProblemSeverity) | block: stops filing, not approving or downloading. warn: a person should look. One of: |
problems[].coderequired | string | |
problems[].box | string | |
problems[].arearequired | string (CtProblemArea) | One of: |
problems[].messagerequired | string | |
computationrequired | objectnullable | The engine’s computation for this accounting period, with the period of account’s adjustments. Null without figures. |
inputrequired | objectnullable | The engine input now held, in integer pence. |
factsrequired | object | What a person has answered. |
masksrequired | object | Masked bank details. |
sourceStaterequired | object (CtSourceState) | |
sourceState.sourcerequired | string (CtSource) | One of: |
sourceState.engagementIdrequired | string (uuid)nullable | |
sourceState.accountsSetIdrequired | string (uuid)nullable | |
sourceState.sourceChangedrequired | boolean | A linked source differs from what this return holds. The figures here haven’t moved: refresh to bring the change in. |
sourceState.sourceApprovedrequired | booleannullable | Whether the linked file or set is approved. Null with nothing linked. |
sourceState.messagerequired | stringnullable | |
sourceChangedrequired | boolean | |
versionsrequired | array of CtInputVersion | |
versions[].idrequired | string (uuid) | |
versions[].versionrequired | integer | |
versions[].sourcerequired | string (CtSource) | One of: |
versions[].fingerprintrequired | string | |
versions[].sourceLabelrequired | stringnullable | |
versions[].createdByNamerequired | stringnullable | |
versions[].createdAtrequired | string (date-time) | |
relatedReturnsrequired | array of CtRelatedReturn | The other returns of a long period of account. |
relatedReturns[].idrequired | string (uuid) | |
relatedReturns[].periodStartrequired | string (date) | example "2026-03-31" |
relatedReturns[].periodEndrequired | string (date) | example "2026-03-31" |
relatedReturns[].statusrequired | string (CtReturnStatus) | One of: |
returnHashrequired | string | Send this back when approving: it fingerprints the return. |
utrrequired | stringnullable | |
registrationNumberrequired | stringnullable | |
approvedByNamerequired | stringnullable | |
approvedAtrequired | string (date-time)nullable | |
clientConfirmedOnrequired | string (date)nullable | example "2026-03-31" |
approverRolerequired | string (ApproverRole) | Who may approve in this firm: partners only, or managers and partners. One of: |
reviewerNamesrequired | array of string | Who sending for review goes to, by name: the client’s partner, or every partner where the record names none, and its manager. |
canApproverequired | boolean | |
cannotApproveReasonrequired | stringnullable | |
canFilerequired | boolean | No blocker stands in the way of filing this return, whether or not filing is switched on. |
canSubmitrequired | boolean | |
cannotSubmitReasonrequired | stringnullable | |
filingModerequired | string (CtFilingMode) | One of: |
declarationrequired | object | { version, text }: the declaration to accept before filing. |
rolledFromReturnIdrequired | string (uuid)nullable | |
canAmendrequired | boolean | |
cannotAmendReasonrequired | stringnullable | |
lastAmendmentDayrequired | string (date) | The last day this return can be amended: 12 months after its filing date (FA 1998 Sch 18 para 15(4)). example "2026-03-31" |
amendedByReturnIdrequired | string (uuid)nullable | The amendment of this return, once started. |
amendmentHistoryrequired | array of CtAmendmentHistoryItem | Every version of this return, oldest first. Each keeps its own review and approval. |
amendmentHistory[].idrequired | string (uuid) | |
amendmentHistory[].amendmentNumberrequired | integer | |
amendmentHistory[].statusrequired | string (CtReturnStatus) | One of: |
amendmentHistory[].filedElsewhereOnrequired | string (date)nullable | example "2026-03-31" |
amendmentHistory[].updatedAtrequired | string (date-time) | |
reviewPointsrequired | array of CtReviewPoint | |
reviewPoints[].idrequired | string (uuid) | |
reviewPoints[].boxrequired | stringnullable | |
reviewPoints[].textrequired | string | |
reviewPoints[].statusrequired | string (CtReviewPointStatus) | One of: |
reviewPoints[].raisedByNamerequired | stringnullable | |
reviewPoints[].createdAtrequired | string (date-time) | |
eventsrequired | array of CtEvent | |
events[].idrequired | string (uuid) | |
events[].kindrequired | string | |
events[].actorNamerequired | stringnullable | |
events[].noterequired | stringnullable | |
events[].createdAtrequired | string (date-time) | |
submissionsrequired | array of CtSubmission | |
submissions[].idrequired | string (uuid) | |
submissions[].moderequired | string (CtFilingMode) | One of: |
submissions[].statusrequired | string (CtSubmissionStatus) | How the latest attempt to send this return ended. Null if it has never been sent. One of: |
submissions[].correlationIdrequired | stringnullable | |
submissions[].irmarkrequired | string | |
submissions[].errorsrequired | array of objectnullable | HMRC’s errors: { number, text, location, meaning }. |
submissions[].messagerequired | stringnullable | What happened, in plain words. |
submissions[].receiptAtrequired | string (date-time)nullable | |
submissions[].submittedByNamerequired | stringnullable | |
submissions[].createdAtrequired | string (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/corporation-tax/returns/{id}
- Scopes
corporation_tax:read
The boxes, the computation, what would stop it being filed, where the figures came from, review points and history. canFile says whether anything blocks filing; filingEnabled whether filing is switched on. Bank details are only ever masked. Part of the corporation_tax 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 (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/returns/{id}
- Scopes
corporation_tax:write- Role
- Preparer or above
Preparers and above. Figures are a new immutable version, shared by every return of the period of account. Any change takes a reviewed or approved return back to draft. Figures from a linked source are refused with 409; refused once it’s with HMRC.
Needs the Preparer role or above. Part of the corporation_tax 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 (UpdateCtReturnRequest).
| Field | Type | Description |
|---|---|---|
input | object | Parts of the tax engine’s input to change, in integer pence. Applies to every return of the period of account. |
facts | object | Answers: declarationName, declarationStatus, exports, repaymentClaim, provisionalFigures, rnd (companySize, notificationSubmitted, additionalInformationSubmitted, payeReferences, connectedPayeReferences), amendment (accountsAlreadySubmitted, computationsAlreadySubmitted), outOfScope and so on. |
bank | objectnullable | Bank details for a repayment, or null to remove them. Encrypted, and only ever shown masked. |
note | string |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Group relief for a return
GET/api/v1/corporation-tax/returns/{id}/group-relief
- Scopes
corporation_tax:read
Notices of consent touching this company, the companies its client record connects it with, and an associated company count from those links. The links are suggestions: nothing is applied, and the group test is what a person says. Part of the corporation_tax 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 (CtGroupReliefState).
| Field | Type | Description |
|---|---|---|
noticesrequired | array of CtGroupNotice | |
notices[].idrequired | string (uuid) | |
notices[].kindrequired | string | One of: |
notices[].surrenderingClientIdrequired | string (uuid) | |
notices[].surrenderingNamerequired | string | |
notices[].surrenderingUtrrequired | stringnullable | |
notices[].claimantClientIdrequired | string (uuid) | |
notices[].claimantNamerequired | string | |
notices[].claimantUtrrequired | stringnullable | |
notices[].surrenderPeriodStartrequired | string (date) | |
notices[].surrenderPeriodEndrequired | string (date) | |
notices[].amountPencerequired | number | |
notices[].givenOnrequired | string (date) | |
notices[].statusrequired | string | One of: |
notices[].gapsrequired | array of string | What the notice lacks under FA 1998 Sch 18 para 71(1). A notice with gaps is ineffective. |
relatedCompaniesrequired | array of CtGroupCompanySuggestion | Companies the client record connects with this one. Suggestions: nothing is applied. |
relatedCompanies[].clientIdrequired | string (uuid) | |
relatedCompanies[].namerequired | string | |
relatedCompanies[].utrrequired | stringnullable | |
relatedCompanies[].whyrequired | string | How the client record connects the two. A pointer only. |
relatedCompanies[].looksLike75Percentrequired | boolean | The links would meet 75% ownership if they’re complete. Never decides the group test. |
associatedCompaniesSuggestedrequired | number | A count from the links for boxes 326 to 328, for a person to accept or ignore. Never applied by itself. |
associatedCompaniesNoterequired | string |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Record a notice of consent
POST/api/v1/corporation-tax/returns/{id}/group-relief/notices
- Scopes
corporation_tax:write- Role
- Preparer or above
- Retries
- Send an
Idempotency-Keyto make retries safe.
Preparers and above. Records a notice given to HMRC, between this company and another client of the firm (FA 1998 Sch 18 para 70). A notice can’t be changed: withdraw it and record another. Recording it doesn’t change either return.
Needs the Preparer role or above. Part of the corporation_tax 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 (CreateCtGroupNoticeRequest).
A notice of consent to surrender group relief, given to HMRC.
| Field | Type | Description |
|---|---|---|
kindrequired | string | One of: |
thisCompanyIsrequired | string | Which side this return’s company is on. One of: |
otherClientIdrequired | string (uuid) | The other company: a client of this firm. |
surrenderPeriod | object | The surrendering company’s accounting period. |
surrenderPeriod.startrequired | string (date) | |
surrenderPeriod.endrequired | string (date) | |
amountPencerequired | number | Whole pounds, in pence. |
givenOnrequired | string (date) | When notice was given to HMRC (FA 1998 Sch 18 para 70(3)). |
Responses
201 Created, application/json
Body: object (CtGroupNotice).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
kindrequired | string | One of: |
surrenderingClientIdrequired | string (uuid) | |
surrenderingNamerequired | string | |
surrenderingUtrrequired | stringnullable | |
claimantClientIdrequired | string (uuid) | |
claimantNamerequired | string | |
claimantUtrrequired | stringnullable | |
surrenderPeriodStartrequired | string (date) | |
surrenderPeriodEndrequired | string (date) | |
amountPencerequired | number | |
givenOnrequired | string (date) | |
statusrequired | string | One of: |
gapsrequired | array of string | What the notice lacks under FA 1998 Sch 18 para 71(1). A notice with gaps is ineffective. |
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).
Withdraw a notice of consent
POST/api/v1/corporation-tax/returns/{id}/group-relief/notices/{noticeId}/withdraw
- Scopes
corporation_tax:write- Role
- Preparer or above
- Retries
- Send an
Idempotency-Keyto make retries safe.
Preparers and above. A return that relies on it then can’t be filed until it’s replaced (FA 1998 Sch 18 para 71).
Needs the Preparer role or above. Part of the corporation_tax product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
noticeIdrequired | 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 |
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).
Link a source
POST/api/v1/corporation-tax/returns/{id}/sources/link
- Scopes
corporation_tax:write- Role
- Preparer or above
Preparers and above. Snapshots a Working Papers file’s tax computation, or takes profit and turnover from an approved Accounts set, or attaches only the accounts. The source of the same client and period is never written to, and later changes to it are only flagged until someone refreshes. Needs read access to the source’s product.
Needs the Preparer role or above. Part of the corporation_tax 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 (LinkCtSourceRequest).
| Field | Type | Description |
|---|---|---|
sourcerequired | string (CtLinkSource) | working_papers: a snapshot of the file’s tax computation. accounts: profit and turnover from an approved Accounts set, and its accounts. accounts_file: only the accounts that go with the return. typed: keep the figures and stop following a source. One of: |
engagementId | string (uuid) | |
accountsSetId | string (uuid) |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Refresh from the source
POST/api/v1/corporation-tax/returns/{id}/sources/refresh
- Scopes
corporation_tax:write- Role
- Preparer or above
Preparers and above. Brings in what a linked file or set now holds, as a new version. Nothing changes if they already match. A real change loses an approval.
Needs the Preparer role or above. Part of the corporation_tax 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 (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Start next period’s return
POST/api/v1/corporation-tax/returns/{id}/roll-forward
- Scopes
corporation_tax:write- Role
- Preparer or above
- Retries
- Send an
Idempotency-Keyto make retries safe.
Preparers and above. Carries trading losses, loans to participators, capital allowance pool balances and the answers from this return. This year’s figures start at nil.
Needs the Preparer role or above. Part of the corporation_tax 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 (RollForwardCtReturnRequest).
| Field | Type | Description |
|---|---|---|
periodEnd | string (date) | End of the next period of account. Defaults to 12 months on. example "2026-03-31" |
Responses
201 Created, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Send for review
POST/api/v1/corporation-tax/returns/{id}/send-for-review
- Scopes
corporation_tax:write- Role
- Preparer or above
Preparers and above, from draft.
Needs the Preparer role or above. Part of the corporation_tax 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 (CtNoteRequest).
| Field | Type | Description |
|---|---|---|
note | string | up to 2000 characters |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/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 corporation_tax 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 (RaiseCtReviewPointRequest).
| Field | Type | Description |
|---|---|---|
textrequired | string | 1 to 4000 characters |
box | string | The CT600 box it’s about. |
Responses
201 Created, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/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 corporation_tax product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
pointIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/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 a linked source changed, or if the figures moved since you reviewed them. What stops filing doesn’t stop approval. Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the corporation_tax 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 (ApproveCtReturnRequest).
| Field | Type | Description |
|---|---|---|
returnHashrequired | string | The |
note | string |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Reopen a return
POST/api/v1/corporation-tax/returns/{id}/reopen
- Scopes
review:write- Role
- Reviewer or above
- Access
- A signed-in Tolvi session only, never an API token.
Reviewers and above, signed in. Back to draft, and an approval is lost. Never available to API keys or connected assistants.
Needs the Reviewer role or above. Part of the corporation_tax 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 (CtNoteRequest).
| Field | Type | Description |
|---|---|---|
note | string | up to 2000 characters |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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).
Start an amended return
POST/api/v1/corporation-tax/returns/{id}/amend
- Scopes
corporation_tax:write- Role
- Preparer or above
- Access
- A signed-in Tolvi session only, never an API token.
Preparers and above, signed in. Only a filed return, within 12 months of its filing date (FA 1998 Sch 18 para 15(4)). A new draft with the filed figures: the original is never changed, and the amendment has its own review, approval and client's confirmation. Filing stays off. Never available to API keys or connected assistants.
Needs the Preparer role or above. Part of the corporation_tax 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 (CtNoteRequest).
| Field | Type | Description |
|---|---|---|
note | string | up to 2000 characters |
Responses
201 Created, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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 a return as filed outside Tolvi
POST/api/v1/corporation-tax/returns/{id}/filed-elsewhere
- Scopes
review:write- Role
- Partner
- Access
- A signed-in Tolvi session only, never an API token.
A partner, signed in, for an approved return that went to HMRC by other means. It's the partner's record, not HMRC's word, and nothing is sent. Never available to API keys or connected assistants.
Needs the Partner role or above. Part of the corporation_tax 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 (RecordCtFiledElsewhereRequest).
| Field | Type | Description |
|---|---|---|
filedOnrequired | string (date) | The day it went to HMRC by other means. This is a record a person makes, not HMRC’s word. example "2026-03-31" |
note | string | up to 2000 characters |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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 confirmation
POST/api/v1/corporation-tax/returns/{id}/client-confirmation
- Scopes
corporation_tax:write- Role
- Preparer or above
- Access
- A signed-in Tolvi session only, never an API token.
Preparers and above, signed in. The client confirmed the copy they were sent. It counts only for these figures. Never available to API keys or connected assistants.
Needs the Preparer role or above. Part of the corporation_tax 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 (RecordCtClientConfirmationRequest).
| Field | Type | Description |
|---|---|---|
confirmedOnrequired | string (date) | example "2026-03-31" |
note | string | |
returnHashrequired | string | The |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/returns/{id}/submit
- Scopes
corporation_tax:write- Role
- Manager or above
- Access
- A signed-in Tolvi session only, never an API token.
- Retries
- Send an
Idempotency-Keyto make retries safe.
A manager or partner, signed in with a second factor, once these figures are approved, the client has confirmed them and nothing blocks filing. Answers 503 until filing is switched on, once HMRC’s test service has passed. Never available to API keys or connected assistants.
Needs the Manager role or above. Part of the corporation_tax 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 (SubmitCtReturnRequest).
| Field | Type | Description |
|---|---|---|
returnHashrequired | string | |
agentAccountIdrequired | string (uuid) | |
declarationrequired | object | { accepted: true, version }: the declaration on the CT600. |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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/corporation-tax/returns/{id}/submissions/{submissionId}/poll
- Scopes
corporation_tax:read
While HMRC is checking a return. Tolvi also asks by itself. Part of the corporation_tax product: the firm must have it and you must have access to it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string (uuid) | |
submissionIdrequired | path | string (uuid) |
Responses
200 OK, application/json
Body: object (CtReturn).
A Company Tax Return for one accounting period, with its boxes, computation 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 the CT600
GET/api/v1/corporation-tax/returns/{id}/downloads/ct600.pdf
- Scopes
corporation_tax:read
The return in the style of HMRC’s form, with CT600A where it applies. Every page gives its status and says it wasn’t issued by HMRC. Bank details appear masked. Part of the corporation_tax 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 PDF.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Download the computation
GET/api/v1/corporation-tax/returns/{id}/downloads/computation.pdf
- Scopes
corporation_tax:read
The tax computation for this accounting period, for people to read. Part of the corporation_tax 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 PDF.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Download the iXBRL accounts
GET/api/v1/corporation-tax/returns/{id}/downloads/accounts.xhtml
- Scopes
corporation_tax:read
The tagged accounts from the linked Accounts set. 409 with no set linked. What stops the file being filed is in the return’s problems. Part of the corporation_tax 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
iXBRL.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Download the iXBRL computation
GET/api/v1/corporation-tax/returns/{id}/downloads/computation.xhtml
- Scopes
corporation_tax:read
The tagged computation for this accounting period. What stops the file being filed is in the return’s problems. Part of the corporation_tax 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
iXBRL.
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 404 Not found, 429 Too many requests, as problem details (application/problem+json).
Preview the CT600 XML
GET/api/v1/corporation-tax/returns/{id}/downloads/ct600.xml
- Scopes
corporation_tax:read
The return in the order of HMRC’s schema, as it would be sent, without any sign-in and with bank details masked. It isn’t filed by downloading it. Part of the corporation_tax 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
XML.
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/corporation-tax/agent-accounts
- Scopes
corporation_tax:read
Names and status only: a saved sign-in is never returned. Part of the corporation_tax product: the firm must have it and you must have access to it.
Responses
200 OK, application/json
Body: object (CtAgentAccountList).
| Field | Type | Description |
|---|---|---|
itemsrequired | array of CtAgentAccount | |
items[].idrequired | string (uuid) | |
items[].namerequired | string | |
items[].credentialStatusrequired | string (CtCredentialStatus) | One of: |
items[].userIdHintrequired | stringnullable | |
items[].lastUsedAtrequired | string (date-time)nullable | |
canStoreCredentialsrequired | boolean | Whether sign-ins can be stored on this Tolvi. |
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/corporation-tax/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 corporation_tax product: the firm must have it and you must have access to it.
Request body
Required. application/json: object (CreateCtAgentAccountRequest).
| Field | Type | Description |
|---|---|---|
namerequired | string | 1 to 80 characters; example "Leeds office" |
Responses
201 Created, application/json
Body: object (CtAgentAccount).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
namerequired | string | |
credentialStatusrequired | string (CtCredentialStatus) | One of: |
userIdHintrequired | stringnullable | |
lastUsedAtrequired | string (date-time)nullable |
Errors: 400 Bad request, 401 Unauthorised, 403 Forbidden, 429 Too many requests, as problem details (application/problem+json).
Remove an HMRC account
DELETE/api/v1/corporation-tax/agent-accounts/{id}
- Scopes
settings:admin- Access
- A signed-in Tolvi session only, never an API token.
Firm admins, signed in. Its sign-in is deleted at once. Part of the corporation_tax 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
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/corporation-tax/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 corporation_tax 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 (SaveCtCredentialsRequest).
| Field | Type | Description |
|---|---|---|
userIdrequired | string | 1 to 100 characters |
passwordrequired | string | 1 to 200 characters |
Responses
200 OK, application/json
Body: object (CtAgentAccount).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
namerequired | string | |
credentialStatusrequired | string (CtCredentialStatus) | One of: |
userIdHintrequired | stringnullable | |
lastUsedAtrequired | 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).
Delete the saved sign-in
DELETE/api/v1/corporation-tax/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 corporation_tax 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 (CtAgentAccount).
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
namerequired | string | |
credentialStatusrequired | string (CtCredentialStatus) | One of: |
userIdHintrequired | stringnullable | |
lastUsedAtrequired | 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).