Build MTD ITSA Final Declaration (JSON)
Skill: Assemble year-end figures into the End of Period Statement and Final Declaration
Region: United Kingdom Category: Tax — Income/MTD Does: Takes a taxpayer's finalised year-end business figures, adjustments and other income, and assembles the End of Period Statement (EOPS) crystallisation / Final Declaration submission for HMRC's MTD for Income Tax REST API, confirming the tax year is complete and correct. Spec: HMRC MTD for Income Tax REST API — Self Assessment / crystallisation (JSON over OAuth 2.0 with fraud-prevention headers)
Confirms a tax year for a sole trader or landlord after the four cumulative quarterly updates. The Final Declaration replaces the old SA100 self-assessment return; element names below follow the form/API, not a verbatim schema.
When this applies
- After the fourth quarterly update for each business source and any accounting adjustments (capital allowances, disallowable expenses, private-use adjustments, basis-period transition).
- Once all income sources for the tax year are known (employment, savings, dividends, gains, reliefs).
- Due by the Self Assessment deadline of 31 January following the tax year (e.g. 2026/27 due 31 Jan 2028).
Structure (year-end → Final Declaration)
1. Per business source: finalise via EOPS-style annual submission
- adjustments { ... }, allowances { capitalAllowanceMainPool, ... },
nonFinancials { class4NicsExemptionReason, ... }
2. Retrieve calculation: trigger /calculation (intent = "finalDeclaration")
-> returns calculationId + tax liability
3. Crystallise: POST .../income-tax/calculations/{taxYear}/{calculationId}/final-declaration
(empty body; declares figures true and complete)
Data rules
- Sequence — all quarterly updates and annual adjustments must be submitted before triggering the final calculation; crystallisation fails if the period data is incomplete.
- calculationId — the Final Declaration references the latest
finalDeclaration-intent calculation for thattaxYear; a stale id is rejected. - GBP rounding — income rounded down to whole pounds, tax/allowances per HMRC convention; reliefs and allowances at 2 dp where the API requires.
- Reconciliation — the declared liability must match the HMRC calculation; recompute after any late adjustment.
- Identifiers — taxpayer NINO and UTR,
taxYearinYYYY-YYform, plus OAuth user session and fraud-prevention headers.
Worked example (outline)
Sole trader 2026-27, NINO QQ123456C, UTR 1234567890
Quarterly updates Q1-Q4 submitted (cumulative)
Annual adjustments: capital allowances main pool £3,200; disallowable £450
Trigger calculation (finalDeclaration) -> calculationId c0ffee...; liability £4,812.40
POST final-declaration {calculationId} -> 204 No Content
Submitted to the MTD ITSA crystallisation endpoint for the tax year, due 31 January after year end.
Validation checklist
- All four quarterly updates and annual adjustments submitted first
- Calculation triggered with finalDeclaration intent; current
calculationIdused - All other income (employment, savings, dividends, gains) included
- NINO + UTR and
taxYear(YYYY-YY) correct - Declared liability reconciles to the HMRC calculation
- OAuth session + fraud-prevention headers present
- Submitted by 31 January following the tax year
Last updated: 2026-06-04 — confirm the current schema/version, identifiers, rounding, and deadline against current authority (gov.uk/hmrc) guidance before use.