Making Tax Digital
MTD ITSA compliance - quarterly submissions, HMRC API integration, and SA103 auto-fill.
What is MTD ITSA?
Making Tax Digital for Income Tax Self Assessment requires sole traders and landlords to keep digital records and submit quarterly updates using compatible software.
Rollout Timeline
| Date | Who |
|---|---|
| April 2026 | Income over £50,000 |
| April 2027 | Income over £30,000 |
| TBC | Income over £20,000 |
HMRC API Integration
| API | Purpose | Status |
|---|---|---|
| Self Assessment | SA returns | Live |
| Obligations | Deadlines | Live |
| Business Income | BISS data | Live |
| Individual Calculations | Tax calcs | Live |
| National Insurance | NI lookup | Live |
OAuth 2.0 Flow
sequenceDiagram
participant User
participant TaxMTD
participant HMRC
User->>TaxMTD: Click "Connect HMRC"
TaxMTD->>HMRC: Redirect to Gov Gateway
HMRC->>User: Login & Authorise
HMRC->>TaxMTD: Auth code callback
TaxMTD->>HMRC: Exchange for access token
TaxMTD->>TaxMTD: Store encrypted tokens
Quarterly Schedule
| Quarter | Period | Deadline |
|---|---|---|
| Q1 | 6 Apr - 5 Jul | 5 August |
| Q2 | 6 Jul - 5 Oct | 5 November |
| Q3 | 6 Oct - 5 Jan | 5 February |
| Q4 | 6 Jan - 5 Apr | 5 May |
| Final | Full year | 31 January |
Quarterly Update Payload
Each submission includes:
{
"totalIncome": 12500.00,
"totalExpenses": 3200.00,
"netProfit": 9300.00,
"taxableProfit": 9300.00,
"incomeTaxCharged": 1860.00,
"nic2": 44.85,
"nic4": 558.00,
"totalTaxDue": 2462.85
}
Setting Up HMRC
- Navigate to Settings → HMRC
- Enter your National Insurance Number (NINO)
- Click Authorise → redirect to Gov Gateway
- Log in with your Government Gateway credentials
- Grant TaxMTD permission
- View obligations under Making Tax Digital
All submissions require explicit user confirmation. TaxMTD never submits to HMRC automatically.
API
JavaScript
// Check HMRC connection
const status = await $fetch('https://www.taxmtd.uk/api/hmrc/status')
// Get obligations
const obligations = await $fetch('https://www.taxmtd.uk/api/hmrc/auth')
// Get SA103 data
const sa103 = await $fetch('https://www.taxmtd.uk/api/hmrc/sa103')
// Store NINO
await $fetch('https://www.taxmtd.uk/api/hmrc/nino', {
method: 'POST',
body: { nino: 'QQ123456C' }
})
Python
# Check HMRC connection
status = requests.get(
"https://www.taxmtd.uk/api/hmrc/status",
cookies=session_cookies,
).json()["data"]
# Get SA103 data
sa103 = requests.get(
"https://www.taxmtd.uk/api/hmrc/sa103",
cookies=session_cookies,
).json()["data"]
# Store NINO
requests.post(
"https://www.taxmtd.uk/api/hmrc/nino",
json={"nino": "QQ123456C"},
cookies=session_cookies,
)
PHP
$status = Http::get('https://www.taxmtd.uk/api/hmrc/status')->json();
$sa103 = Http::get('https://www.taxmtd.uk/api/hmrc/sa103')->json();
Http::post('https://www.taxmtd.uk/api/hmrc/nino', ['nino' => 'QQ123456C']);
Rust
// Check HMRC connection
let status = client
.get("https://www.taxmtd.uk/api/hmrc/status")
.send().await?
.json::<serde_json::Value>().await?;
// Get SA103 data
let sa103 = client
.get("https://www.taxmtd.uk/api/hmrc/sa103")
.send().await?
.json::<serde_json::Value>().await?;
// Store NINO
client.post("https://www.taxmtd.uk/api/hmrc/nino")
.json(&serde_json::json!({"nino": "QQ123456C"}))
.send().await?;
cURL
# Check HMRC status
curl https://www.taxmtd.uk/api/hmrc/status
# Get SA103 data
curl https://www.taxmtd.uk/api/hmrc/sa103
# Submit NINO
curl -X POST https://www.taxmtd.uk/api/hmrc/nino \
-H "Content-Type: application/json" \
-d '{"nino":"QQ123456C"}'