Build MTD VAT Return JSON (HMRC API)
Skill: Convert VAT figures into the JSON payload for HMRC's MTD VAT API
Region: United Kingdom
Category: MTD — Making Tax Digital for VAT
Does: Takes the nine VAT-return box figures and produces the JSON body to submit a VAT return via HMRC's MTD VAT API (POST /organisations/vat/{vrn}/returns).
API: HMRC Making Tax Digital for VAT (v1.0)
Submission requires an OAuth 2.0 bearer token (user-restricted scope
write:vat), HMRC fraud-prevention headers (Gov-Client-*,Gov-Vendor-*), and a validperiodKeyobtained from the retrieve obligations endpoint. This skill builds the return body; it does not replace the auth/headers handshake. Submitting withfinalised: trueis the legal declaration — never send it speculatively.
Input data required
| Input | JSON field |
|---|---|
| VAT registration number | path param {vrn} |
| Obligation period key (from obligations endpoint) | periodKey |
| Box 1 — VAT due on sales | vatDueSales |
| Box 2 — VAT due on EC/NI acquisitions | vatDueAcquisitions |
| Box 4 — VAT reclaimed on purchases | vatReclaimedCurrPeriod |
| Box 6 — total value of sales ex-VAT | totalValueSalesExVAT |
| Box 7 — total value of purchases ex-VAT | totalValuePurchasesExVAT |
| Box 8 — total value of goods supplied ex-VAT | totalValueGoodsSuppliedExVAT |
| Box 9 — total acquisitions ex-VAT | totalAcquisitionsExVAT |
| Declaration confirmed by the user | finalised |
The nine VAT boxes → JSON fields
| Box | JSON field | Type / rule |
|---|---|---|
| 1 | vatDueSales |
decimal, 2 dp, −9999999999999.99 … 9999999999999.99 |
| 2 | vatDueAcquisitions |
decimal, 2 dp |
| 3 | totalVatDue |
= Box 1 + Box 2 (computed), 2 dp |
| 4 | vatReclaimedCurrPeriod |
decimal, 2 dp |
| 5 | netVatDue |
**= |
| 6 | totalValueSalesExVAT |
whole pounds (0 dp) |
| 7 | totalValuePurchasesExVAT |
whole pounds (0 dp) |
| 8 | totalValueGoodsSuppliedExVAT |
whole pounds (0 dp) |
| 9 | totalAcquisitionsExVAT |
whole pounds (0 dp) |
| — | periodKey |
4-character string from the obligations endpoint |
| — | finalised |
boolean — must be true to submit |
Calculation rules
totalVatDue(Box 3) =vatDueSales+vatDueAcquisitions.netVatDue(Box 5) = absolute difference of Box 3 and Box 4:abs(totalVatDue − vatReclaimedCurrPeriod). It is always non-negative.- Boxes 1–5 are monetary, exactly 2 decimal places.
- Boxes 6–9 are values in whole pounds, 0 decimal places (no pence).
periodKeymust exactly match an open obligation; it is case-sensitive (e.g.18A1,#001).finalisedmust betrue; it represents the user's legal declaration that the return is correct.
Worked example
A quarter with £20,000 of standard-rated sales (£4,000 output VAT) and £5,000 of purchases (£1,000 input VAT), no EC acquisitions:
{
"periodKey": "18A1",
"vatDueSales": 4000.00,
"vatDueAcquisitions": 0.00,
"totalVatDue": 4000.00,
"vatReclaimedCurrPeriod": 1000.00,
"netVatDue": 3000.00,
"totalValueSalesExVAT": 20000,
"totalValuePurchasesExVAT": 5000,
"totalValueGoodsSuppliedExVAT": 0,
"totalAcquisitionsExVAT": 0,
"finalised": true
}
Submit with:
POST /organisations/vat/{vrn}/returns
Authorization: Bearer {access_token}
Accept: application/vnd.hmrc.1.0+json
Content-Type: application/json
Gov-Client-Connection-Method: ... (plus the other required fraud-prevention headers)
A successful response returns a formBundleNumber, paymentIndicator, and processingDate — store the formBundleNumber as the receipt.
Validation checklist
-
periodKeymatches an open obligation fromGET /organisations/vat/{vrn}/obligations - Boxes 1–5 have exactly 2 decimal places; boxes 6–9 are whole numbers
-
totalVatDue= Box 1 + Box 2 -
netVatDue= abs(Box 3 − Box 4) and is non-negative -
finalisedistrueonly after the user confirms the declaration - OAuth bearer token has
write:vatscope; fraud-prevention headers populated -
formBundleNumberfrom the response stored as proof of submission
Last updated: 2026-05-26 — confirm field names, value ranges, the MTD VAT API version, and the current fraud-prevention header requirements against HMRC's MTD VAT API documentation before use.