Why firm-level VAT?¶
Household-side VAT in PolicyEngine answers the question “what does this household pay in VAT on the goods and services it buys?” but it can’t answer policy questions framed at the business side:
How does changing the VAT registration threshold (£90,000 of taxable turnover since 1 April 2024) affect the number of firms in scope, and through them the consumer prices that households face?
What’s the revenue effect of moving a supply between standard, reduced and zero rates seen from the supplier side (input/output netting)?
How does the flat-rate scheme distort the modelled compliance picture?
Closing those questions needs a separate entity that carries turnover, sector, and registration status, and variables for input/output VAT and net liability.
Scope¶
Phase 1: minimum viable product¶
Firmentity with the bare attributes needed for the threshold and rate questions:firm_turnover,firm_industry_sector,firm_vat_registered. Firms are linked to households for sole traders and partnerships (unincorporated business income flows already exist in the FRS) and stand alone for incorporated entities.Registration threshold logic: a firm must register if its taxable turnover is more than a new
gov.hmrc.vat.firm.registration_thresholdparameter, or it can register voluntarily. The threshold has been £90,000 since 1 April 2024.Standard / reduced / zero-rated supply split at the firm level, driven by sector-specific share parameters.
firm_vat_on_sales(output VAT) andfirm_vat_on_purchases(input VAT), each computed from share-based decompositions of turnover and intermediate consumption.firm_net_vat_liability= output VAT − input VAT.
Phase 2: distributional refinements¶
Flat-rate scheme for small businesses (a new
gov.hmrc.vat.firm.flat_rate_schemeparameter tree).VAT groups and partial exemption (de minimis rules for exempt-versus-taxable splits).
Cross-border VAT after Brexit (Northern Ireland under the Windsor Framework, postponed VAT accounting on imports).
Phase 3: incidence¶
Pass-through of VAT rate changes to consumer prices, joining up the household-side
vatvariable and the firm-sidefirm_net_vat_liabilitythrough an explicit incidence assumption (already modelled in spirit viavat_changeon the household side; Phase 3 promotes it to a first-class link).
Implementation plan¶
Entity¶
A new Firm entity in policyengine_uk/entities.py next to the
existing Household, BenUnit, Person:
Firm = build_entity(
key="firm",
plural="firms",
label="Firm",
doc="A business entity that may register for VAT.",
roles=[
{
"key": "owner",
"plural": "owners",
"label": "Owner",
"doc": "Person who owns the firm.",
}
],
containing_entities=[],
)The containing_entities set deliberately does not include
household because incorporated firms have no household; the link for
sole traders is via an explicit firm_owning_household_id input
variable rather than entity nesting. (The existing Household and
BenUnit entities list a "state" containing entity, but PolicyEngine UK
has no state entity, so the firm should not copy it.) In policyengine-core
only people can be members of a group entity, so the owner role holds people.
Core also places each person in exactly one instance of every group entity,
so a person cannot own two firms and everyone belongs to some firm: a
situation that lists firms gives anyone it leaves out a one-person firm, one
that lists households but no firms puts all its people in a single firm, and
a dataset build must assign every person a firm. The design therefore needs
a way to represent people who own no firm and incorporated firms with no
owner in the data.
Variables¶
Under a new variables/gov/hmrc/vat/firm/ tree:
firm_turnover(input)firm_industry_sector(input, enum)firm_vat_registered(derived from turnover and the threshold; can also be set as input for voluntary registration)firm_standard_rated_share,firm_reduced_rated_share,firm_zero_rated_share,firm_exempt_share(derived from sector or input override)firm_vat_on_sales(output VAT)firm_vat_on_purchases(input VAT)firm_net_vat_liability(output − input)
The household-side vat variable stays untouched; the two sides only
meet in Phase 3.
Parameters¶
A new tree under parameters/gov/hmrc/vat/firm/:
registration_threshold.yaml: £90,000 from 1 April 2024.deregistration_threshold.yaml: £88,000 from 1 April 2024.Rates: reference the existing
gov/hmrc/vat/standard_rate.yamlandreduced_rate.yamlrather than duplicating them. Zero-rated supplies need no rate parameter.sector_supply_split/: share parameters by industry sector for the standard/reduced/zero/exempt split (Phase 1.5 refinement; MVP can use a single national split per sector).flat_rate_scheme/: Phase 2.
Tests¶
Unit tests around the threshold (firm just below, just above, just above the deregistration threshold).
Tests of rate-split arithmetic for each sector.
Integration test asserting that summing
firm_net_vat_liabilityacross a representative firm panel reproduces published HMRC VAT receipts to within calibration tolerance.
Data needs¶
This is the harder half of the project. Summary of where each Phase 1 component sits against our current data:
| Component | Public source | FRS coverage | Datalab source |
|---|---|---|---|
| Firm turnover distribution | ONS UK business: activity, size and location | sole-trader / partnership profit (not turnover) via FRS self-employment income | HMRC Datalab: anonymised VAT returns |
| Industry sector | SIC codes from ONS Inter-Departmental Business Register (IDBR) | main- or last-job SIC 2007 division only (sic_industry_division); no firm-level sector | HMRC Datalab |
| VAT registration share | HMRC VAT statistics (annual) | not in FRS | HMRC Datalab |
| Input VAT shares | ONS Supply and Use tables | not applicable | HMRC Datalab |
Proposed imputation approach¶
Build a synthetic firm panel weighted to ONS UK business: activity, size and location counts by SIC sector and turnover band.
Attach to each firm a registration status, supply split, and intermediate-consumption ratio drawn from HMRC VAT statistics and ONS Supply and Use tables.
Calibrate the panel so that summed
firm_net_vat_liabilitymatches the HMRC VAT receipts outturn for the year.For sole traders and partnerships, link the synthetic firm row back to the FRS household that owns it via self-employment income.
The companion repo policyengine/uk-vatlab hosts the firm-level
VAT analysis files linked from #1333.
Effort estimate¶
Adding the
Firmentity,firm_turnoverinput, threshold logic, and a single-rate liability variable: ~1–2 days.Phase 1 MVP (full Firm entity, sector-driven supply split, calibrated synthetic firm panel, threshold/rate tests, integration test against HMRC outturn): ~3–4 weeks, with most time on the data side.
Phase 2 (flat-rate scheme, VAT groups, partial exemption): another 2–3 weeks once the panel is stable.
Phase 3 (cross-side incidence): tied to the
consumer_incident_tax_revenue_changeinfrastructure already in the repo; the link itself is small but the elasticity assumptions need agreement.
Open questions¶
Should the synthetic firm panel live in the data pipeline or in this repo? Recommendation: in the data pipeline (Microcosm UK), with the rules variables here.
Do we need to model Making Tax Digital filing-frequency mechanics, or is annualised liability sufficient for nowcasting purposes?
HMRC Datalab access for anonymised VAT returns: pursue, or stick to ONS / public-aggregate calibration?
References¶
HMRC, VAT rates and VAT thresholds.
Value Added Tax Act 1994: primary statute.
HMRC, VAT statistics: annual outturn used for calibration.
ONS, UK business: activity, size and location: counts of VAT- and/or PAYE-based enterprises by industry (SIC) and turnover band from the Inter-Departmental Business Register (IDBR).
ONS, Supply and Use tables: intermediate consumption shares.
Companion analysis repo:
policyengine/uk-vatlab(#1333).