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

DateWho
April 2026Income over £50,000
April 2027Income over £30,000
TBCIncome over £20,000

HMRC API Integration

APIPurposeStatus
Self AssessmentSA returns Live
ObligationsDeadlines Live
Business IncomeBISS data Live
Individual CalculationsTax calcs Live
National InsuranceNI 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

QuarterPeriodDeadline
Q16 Apr - 5 Jul5 August
Q26 Jul - 5 Oct5 November
Q36 Oct - 5 Jan5 February
Q46 Jan - 5 Apr5 May
FinalFull year31 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

  1. Navigate to Settings → HMRC
  2. Enter your National Insurance Number (NINO)
  3. Click Authorise → redirect to Gov Gateway
  4. Log in with your Government Gateway credentials
  5. Grant TaxMTD permission
  6. 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://dev.taxmtd.uk/api/hmrc/status')

// Get obligations
const obligations = await $fetch('https://dev.taxmtd.uk/api/hmrc/auth')

// Get SA103 data
const sa103 = await $fetch('https://dev.taxmtd.uk/api/hmrc/sa103')

// Store NINO
await $fetch('https://dev.taxmtd.uk/api/hmrc/nino', {
  method: 'POST',
  body: { nino: 'QQ123456C' }
})
Python
# Check HMRC connection
status = requests.get(
    "https://dev.taxmtd.uk/api/hmrc/status",
    cookies=session_cookies,
).json()["data"]

# Get SA103 data
sa103 = requests.get(
    "https://dev.taxmtd.uk/api/hmrc/sa103",
    cookies=session_cookies,
).json()["data"]

# Store NINO
requests.post(
    "https://dev.taxmtd.uk/api/hmrc/nino",
    json={"nino": "QQ123456C"},
    cookies=session_cookies,
)
PHP
$status = Http::get('https://dev.taxmtd.uk/api/hmrc/status')->json();
$sa103 = Http::get('https://dev.taxmtd.uk/api/hmrc/sa103')->json();

Http::post('https://dev.taxmtd.uk/api/hmrc/nino', ['nino' => 'QQ123456C']);
Rust
// Check HMRC connection
let status = client
    .get("https://dev.taxmtd.uk/api/hmrc/status")
    .send().await?
    .json::<serde_json::Value>().await?;

// Get SA103 data
let sa103 = client
    .get("https://dev.taxmtd.uk/api/hmrc/sa103")
    .send().await?
    .json::<serde_json::Value>().await?;

// Store NINO
client.post("https://dev.taxmtd.uk/api/hmrc/nino")
    .json(&serde_json::json!({"nino": "QQ123456C"}))
    .send().await?;
cURL
# Check HMRC status
curl https://dev.taxmtd.uk/api/hmrc/status

# Get SA103 data
curl https://dev.taxmtd.uk/api/hmrc/sa103

# Submit NINO
curl -X POST https://dev.taxmtd.uk/api/hmrc/nino \
  -H "Content-Type: application/json" \
  -d '{"nino":"QQ123456C"}'