Tax API Reference
Income tax, National Insurance, tax years, take-home pay, employer cost, and VAT calculations.
Base URL: https://api.govdata.dev/v1
Tax Years
/v1/tax/years
No parameters required.
Waiting for request...
List all available tax years.
curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.govdata.dev/v1/tax/years
uri = URI("https://api.govdata.dev/v1/tax/years") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer YOUR_API_KEY" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.get( "https://api.govdata.dev/v1/tax/years", headers={"Authorization": "Bearer YOUR_API_KEY"} )
const response = await fetch("https://api.govdata.dev/v1/tax/years", { headers: { "Authorization": "Bearer YOUR_API_KEY" } });
Response
{ "data": [ { "identifier": "2025-26", "start_date": "2025-04-06", "end_date": "2026-04-05", "active": true, "key_dates": { "self_assessment_deadline": "2027-01-31", "payment_on_account_first": "2026-01-31", "payment_on_account_second": "2026-07-31", "p60_deadline": "2026-05-31", "p11d_deadline": "2026-07-06" } } ], "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0" }, "pagination": { "total": 6, "page": 1, "per_page": 25, "total_pages": 1 } }
/v1/tax/years/current
No parameters required.
Waiting for request...
Returns the current active tax year.
/v1/tax/years/:identifier
Waiting for request...
Returns a specific tax year by identifier.
| Parameter | Type | Description |
|---|---|---|
identifier |
string | Tax year in YYYY-YY format (e.g., 2025-26) |
Income Tax
/v1/tax/income/bands
No parameters required.
Waiting for request...
Returns income tax bands for the current tax year. Append /:tax_year for a specific year.
curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.govdata.dev/v1/tax/income/bands
uri = URI("https://api.govdata.dev/v1/tax/income/bands") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer YOUR_API_KEY" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.get( "https://api.govdata.dev/v1/tax/income/bands", headers={"Authorization": "Bearer YOUR_API_KEY"} )
const response = await fetch("https://api.govdata.dev/v1/tax/income/bands", { headers: { "Authorization": "Bearer YOUR_API_KEY" } });
Response
{ "data": { "tax_year": "2025-26", "personal_allowance": 12570, "personal_allowance_taper_threshold": 100000, "regions": { "england_wales_ni": { "bands": [ { "name": "basic_rate", "label": "Basic Rate", "rate": 0.20, "from": 12570, "to": 50270 }, { "name": "higher_rate", "label": "Higher Rate", "rate": 0.40, "from": 50270, "to": 125140 }, { "name": "additional_rate", "label": "Additional Rate", "rate": 0.45, "from": 125140, "to": null } ] }, "scotland": { "bands": [ { "name": "starter_rate", "rate": 0.19, "from": 12570, "to": 15325 }, { "name": "basic_rate", "rate": 0.20, "from": 15325, "to": 43662 }, { "name": "intermediate_rate", "rate": 0.21, "from": 43662, "to": 50270 }, { "name": "higher_rate", "rate": 0.41, "from": 50270, "to": 125140 }, { "name": "top_rate", "rate": 0.46, "from": 125140, "to": null } ] } } }, "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0", "source": "HMRC", "source_url": "https://www.gov.uk/income-tax-rates" } }
/v1/tax/income/calculate
Waiting for request...
Calculate income tax for a given gross income.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
gross_income |
integer | Yes | Annual gross income in pounds (e.g., 55000) |
region |
string | No | Default: england_wales_ni. Also: scotland |
tax_year |
string | No | Default: current year. Format: YYYY-YY |
curl -X POST https://api.govdata.dev/v1/tax/income/calculate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"gross_income": 55000, "region": "england_wales_ni"}'
uri = URI("https://api.govdata.dev/v1/tax/income/calculate") req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json") req["Authorization"] = "Bearer YOUR_API_KEY" req.body = { gross_income: 55000, region: "england_wales_ni" }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.post( "https://api.govdata.dev/v1/tax/income/calculate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={"gross_income": 55000, "region": "england_wales_ni"} )
const response = await fetch("https://api.govdata.dev/v1/tax/income/calculate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ gross_income: 55000, region: "england_wales_ni" }) });
Response
{ "data": { "gross_income": 55000, "personal_allowance": 12570, "taxable_income": 42430, "tax_year": "2025-26", "region": "england_wales_ni", "breakdown": [ { "band": "basic_rate", "rate": 0.20, "taxable_amount": 37700, "tax": 7540.00 }, { "band": "higher_rate", "rate": 0.40, "taxable_amount": 4730, "tax": 1892.00 } ], "total_income_tax": 9432.00, "effective_rate": 0.1715 }, "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0", "source": "HMRC" } }
National Insurance
/v1/tax/national-insurance/thresholds
No parameters required.
Waiting for request...
Returns National Insurance thresholds for the current tax year. Append /:tax_year for a specific year.
Response
{ "data": { "tax_year": "2025-26", "employee": { "primary_threshold": { "annual": 12570, "weekly": 241.73 }, "upper_earnings_limit": { "annual": 50270, "weekly": 967.12 } }, "employer": { "secondary_threshold": { "annual": 5000 } }, "self_employed": { "class_2_small_profits_threshold": { "annual": 6725 }, "class_4_lower_profit_limit": { "annual": 12570 }, "class_4_upper_profit_limit": { "annual": 50270 } } }, "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0", "source": "HMRC", "source_url": "https://www.gov.uk/national-insurance-rates-letters" } }
/v1/tax/national-insurance/calculate
Waiting for request...
Calculate National Insurance contributions for employed or self-employed income.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
annual_salary |
integer | Yes* | Annual salary in pounds (for employed type) |
annual_profit |
integer | Yes* | Annual profit in pounds (for self_employed type) |
type |
string | No | Default: employed. Also: self_employed |
tax_year |
string | No | Default: current year. Format: YYYY-YY |
* Use annual_salary for employed, annual_profit for self-employed.
curl -X POST https://api.govdata.dev/v1/tax/national-insurance/calculate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"annual_salary": 55000, "type": "employed"}'
uri = URI("https://api.govdata.dev/v1/tax/national-insurance/calculate") req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json") req["Authorization"] = "Bearer YOUR_API_KEY" req.body = { annual_salary: 55000, type: "employed" }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.post( "https://api.govdata.dev/v1/tax/national-insurance/calculate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={"annual_salary": 55000, "type": "employed"} )
const response = await fetch("https://api.govdata.dev/v1/tax/national-insurance/calculate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ annual_salary: 55000, type: "employed" }) });
Take-Home Calculator
/v1/tax/take-home/calculate
Waiting for request...
Combined income tax and National Insurance calculation. Returns net pay breakdown with annual, monthly, and weekly figures.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
gross_income |
integer | Yes | Annual gross income in pounds |
region |
string | No | Default: england_wales_ni |
tax_year |
string | No | Default: current year |
curl -X POST https://api.govdata.dev/v1/tax/take-home/calculate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"gross_income": 55000, "region": "england_wales_ni"}'
uri = URI("https://api.govdata.dev/v1/tax/take-home/calculate") req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json") req["Authorization"] = "Bearer YOUR_API_KEY" req.body = { gross_income: 55000, region: "england_wales_ni" }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.post( "https://api.govdata.dev/v1/tax/take-home/calculate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={"gross_income": 55000, "region": "england_wales_ni"} )
const response = await fetch("https://api.govdata.dev/v1/tax/take-home/calculate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ gross_income: 55000, region: "england_wales_ni" }) });
Response
{ "data": { "gross_income": 55000, "region": "england_wales_ni", "tax_year": "2025-26", "deductions": { "income_tax": { "amount": 9432.00, "personal_allowance": 12570, "effective_rate": 0.1715, "breakdown": [ { "band": "basic_rate", "rate": 0.20, "taxable_amount": 37700, "tax": 7540.00 }, { "band": "higher_rate", "rate": 0.40, "taxable_amount": 4730, "tax": 1892.00 } ] }, "national_insurance": { "employee": 3110.60, "breakdown": [ { "from": 12570, "to": 50270, "rate": 0.08, "amount": 3016.00 }, { "from": 50270, "to": 55000, "rate": 0.02, "amount": 94.60 } ] } }, "net_annual": 42457.40, "net_monthly": 3538.12, "net_weekly": 816.49, "total_deductions": 12542.60, "marginal_rate": 0.42, "employer_costs": { "employer_ni": 7500.00, "total_cost_to_employer": 62500.00 } }, "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0", "source": "HMRC" } }
VAT Return Calculation
/v1/tax/vat/return/calculate
Waiting for request...
Calculate a complete 9-box VAT return from a set of transactions. Supports standard accounting, flat rate scheme, partial exemption, domestic reverse charge, EC supplies/acquisitions, postponed VAT accounting, bad debt relief, and fuel scale charges.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| breakdown_detail | string | No | full, summary (default), or none. Controls transaction detail in the breakdown. |
Request Body
| Field | Type | Description |
|---|---|---|
| company | object | VAT registration, schemes, partial exemption config, fuel scale charges. |
| period | object | Return period start_date and end_date (ISO 8601). Max 12 months. |
| transactions | array | Up to 10,000 transactions with id, date, type, amounts, VAT rate, and supply type. |
curl -X POST https://api.govdata.dev/v1/tax/vat/return/calculate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "company": { "vat_registration_number": "123456789", "vat_schemes": [{"scheme": "standard", "effective_from": "2024-01-01", "effective_to": null}], "partially_exempt": false }, "period": {"start_date": "2024-01-01", "end_date": "2024-03-31"}, "transactions": [ {"id": "S001", "date": "2024-01-15", "type": "sale", "net_amount": 10000, "vat_amount": 2000, "gross_amount": 12000, "vat_rate": "standard", "vat_rate_percentage": 20, "supply_type": "domestic", "is_capital_asset": false}, {"id": "P001", "date": "2024-02-01", "type": "purchase", "net_amount": 3000, "vat_amount": 600, "gross_amount": 3600, "vat_rate": "standard", "vat_rate_percentage": 20, "supply_type": "domestic", "is_capital_asset": false} ] }'
uri = URI("https://api.govdata.dev/v1/tax/vat/return/calculate") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer YOUR_API_KEY" req["Content-Type"] = "application/json" req.body = { company: { vat_registration_number: "123456789", vat_schemes: [{ scheme: "standard", effective_from: "2024-01-01", effective_to: nil }], partially_exempt: false }, period: { start_date: "2024-01-01", end_date: "2024-03-31" }, transactions: [ { id: "S001", date: "2024-01-15", type: "sale", net_amount: 10000, vat_amount: 2000, gross_amount: 12000, vat_rate: "standard", vat_rate_percentage: 20, supply_type: "domestic", is_capital_asset: false } ] }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.post( "https://api.govdata.dev/v1/tax/vat/return/calculate", headers={"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}, json={ "company": { "vat_registration_number": "123456789", "vat_schemes": [{"scheme": "standard", "effective_from": "2024-01-01", "effective_to": None}], "partially_exempt": False }, "period": {"start_date": "2024-01-01", "end_date": "2024-03-31"}, "transactions": [ {"id": "S001", "date": "2024-01-15", "type": "sale", "net_amount": 10000, "vat_amount": 2000, "gross_amount": 12000, "vat_rate": "standard", "vat_rate_percentage": 20, "supply_type": "domestic", "is_capital_asset": False} ] } )
const response = await fetch("https://api.govdata.dev/v1/tax/vat/return/calculate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ company: { vat_registration_number: "123456789", vat_schemes: [{ scheme: "standard", effective_from: "2024-01-01", effective_to: null }], partially_exempt: false }, period: { start_date: "2024-01-01", end_date: "2024-03-31" }, transactions: [ { id: "S001", date: "2024-01-15", type: "sale", net_amount: 10000, vat_amount: 2000, gross_amount: 12000, vat_rate: "standard", vat_rate_percentage: 20, supply_type: "domestic", is_capital_asset: false } ] }) });
Response (200 OK)
{ "data": { "return_period": { "start_date": "2024-01-01", "end_date": "2024-03-31" }, "boxes": { "box_1": { "value": 2000.00, "exact_value": 2000.00 }, "box_2": { "value": 0.00, "exact_value": 0.00 }, "box_3": { "value": 2000.00, "exact_value": 2000.00 }, "box_4": { "value": 600.00, "exact_value": 600.00 }, "box_5": { "value": 1400.00, "exact_value": 1400.00 }, "box_6": { "value": 10000, "exact_value": 10000.00 }, "box_7": { "value": 3000, "exact_value": 3000.00 }, "box_8": { "value": 0, "exact_value": 0.00 }, "box_9": { "value": 0, "exact_value": 0.00 } }, "warnings": [], "scheme_summary": [ { "scheme": "standard", "effective_from": "2024-01-01", "effective_to": "2024-03-31", "transaction_count": 2 } ], "rounding_summary": { "box_1_rounding": 0.0, "box_2_rounding": 0.0, "box_3_rounding": 0.0, "box_4_rounding": 0.0, "box_5_rounding": 0.0, "box_6_rounding": 0.0, "box_7_rounding": 0.0, "box_8_rounding": 0.0, "box_9_rounding": 0.0 } }, "meta": { "source": "HMRC", "source_url": "https://www.gov.uk/vat-returns" } }
Box Descriptions
| Box | Description |
|---|---|
| box_1 | VAT due on sales and other outputs |
| box_2 | VAT due on acquisitions from other EC member states |
| box_3 | Total VAT due (Box 1 + Box 2) |
| box_4 | VAT reclaimed on purchases and other inputs |
| box_5 | Net VAT due or reclaimable (Box 3 - Box 4) |
| box_6 | Total value of sales excluding VAT |
| box_7 | Total value of purchases excluding VAT |
| box_8 | Total value of EC supplies of goods |
| box_9 | Total value of EC acquisitions of goods |
Transaction Types
sale
purchase
credit_note_issued
credit_note_received
debit_note_issued
debit_note_received
bad_debt_relief
journal
Supply Types
domestic
domestic_reverse_charge
ec_supply_goods
ec_supply_services
ec_acquisition_goods
ec_acquisition_services
export_outside_ec
import_outside_ec
import_postponed_vat
outside_scope
VAT Schemes
standard
flat_rate
cash_accounting
annual_accounting
Validation Errors (400)
{ "error": { "code": "VALIDATION_ERROR", "message": "Request contains invalid data.", "documentation_url": "https://docs.govdata.dev/errors/VALIDATION_ERROR", "details": [ { "field": "transactions[0]", "code": "AMOUNT_MISMATCH", "message": "Transaction S001: net_amount (100.0) + vat_amount (20.0) = 120.0, but gross_amount is 999.0." } ] } }
Error codes: AMOUNT_MISMATCH, EXEMPT_WITH_VAT, DUPLICATE_TRANSACTION_ID, TRANSACTION_OUTSIDE_PERIOD, SCHEME_GAP, SCHEME_OVERLAP, FRS_MISSING_PERCENTAGE, BAD_DEBT_RELIEF_TOO_EARLY, BAD_DEBT_RELIEF_POSITIVE_VAT, BAD_DEBT_RELIEF_MISSING_ORIGINAL, DOMESTIC_REVERSE_CHARGE_SALE_WITH_VAT, CAPITAL_GOODS_MISSING_VALUE, PERIOD_TOO_LONG, INVALID_RATE_SUPPLY_COMBINATION, ANNUAL_ADJUSTMENT_WITHOUT_PARTIAL_EXEMPTION, PARTIAL_EXEMPTION_ATTRIBUTION_ON_OUTPUT, INVALID_SCHEME_OVERRIDE, RATE_PERCENTAGE_MISMATCH, SCHEME_OVERRIDE_DATE_MISMATCH, CREDIT_NOTE_POSITIVE_AMOUNTS, NEGATIVE_AMOUNT_ON_POSITIVE_TYPE, SUPPLY_TYPE_DIRECTION_MISMATCH, TRANSACTION_LIMIT_EXCEEDED, INVALID_CO2_BAND, TRANSACTION_NO_MATCHING_SCHEME.
Employer Cost Calculator
Calculate the total cost to an employer of hiring staff. Includes gross salary, employer National Insurance contributions, and workplace pension. Supports multiple employees at the same salary.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
annual_salary |
number | Yes | Gross annual salary in GBP |
tax_year |
string | No | Tax year (e.g. "2025-26"). Defaults to current year. |
pension_rate |
number | No | Employer pension rate as decimal (e.g. 0.03 for 3%). Default: 0.03 |
num_employees |
integer | No | Number of employees at this salary. Default: 1 |
curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"annual_salary": 45000, "pension_rate": 0.05, "num_employees": 3}' \ "https://api.govdata.dev/v1/tax/employer-cost/calculate"
uri = URI("https://api.govdata.dev/v1/tax/employer-cost/calculate") req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json") req["Authorization"] = "Bearer YOUR_API_KEY" req.body = { annual_salary: 45000, pension_rate: 0.05, num_employees: 3 }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
response = requests.post( "https://api.govdata.dev/v1/tax/employer-cost/calculate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={"annual_salary": 45000, "pension_rate": 0.05, "num_employees": 3} )
const response = await fetch( "https://api.govdata.dev/v1/tax/employer-cost/calculate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ annual_salary: 45000, pension_rate: 0.05, num_employees: 3 }) } );
Example response
{ "data": { "tax_year": "2025-26", "per_employee": { "annual_salary": 45000.0, "employer_ni": 5064.78, "employer_ni_breakdown": [{ "band": "Above secondary threshold", "rate": 0.138, "amount": 5064.78 }], "employer_pension": 2250.0, "pension_rate": 0.05, "total_cost": 52314.78 }, "num_employees": 3, "total_annual_cost": 156944.34, "monthly_cost": 13078.70 }, "meta": { "api_version": "v1", "licence": "Open Government Licence v3.0" } }
Data Coverage
| Source | HMRC / GOV.UK |
| Date range | 2020-21 to 2025-26 tax years |
| Records | 6 tax years across all tax types |
| Updated | Annually (after Budget) |
| Limitations | Historical rates before 2020-21 not yet available |