Table Of Contents
If you've ever tried to build accounting software for the UK market, you've hit the same wall I did: there's no clean, machine-readable UK Chart of Accounts available on PyPI.
US-centric ones exist. Plenty of them. But UK accounting has different categories, VAT treatments, and HMRC-specific codes that don't map neatly onto American standards.
So rejoice UK accountants, I built one.
What it does
uk-chart-of-accounts is a Python library with 166 standard UK nominal codes - the numbered category system every UK business uses to classify transactions. Each code includes:
- Account type with double-entry rules (does a debit increase or decrease this account?)
- VAT treatment (standard 20%, reduced 5%, zero-rated, exempt, or outside scope)
- HMRC box mappings (CT600, VAT Return, FPS/RTI, EPS, CIS)
- Tags for searchable grouping (motor, payroll, premises, etc.)
- Descriptions on complex codes explaining the nuances
Zero dependencies. Pure Python. Works with Python 3.10+.
Quick example
from uk_coa import ChartOfAccounts, VatRate
coa = ChartOfAccounts()
# Look up any nominal code
account = coa.get(7602)
account.name # "Accountancy Fees"
account.vat # VatRate.STANDARD
account.vat_rate_pct # 0.20
account.debit_increase # True
# Search
coa.search("insurance") # All accounts with "insurance" in the name
coa.by_vat(VatRate.EXEMPT) # All VAT-exempt accounts
coa.by_tag("motor") # All motor-related accounts
# Export for LLM prompts
context = coa.to_prompt_context()
Why VAT treatments matter
Different expenses have different treatments:
| Treatment | Rate | Examples |
|---|---|---|
| Standard | 20% | Most business expenses |
| Reduced | 5% | Domestic energy |
| Zero-rated | 0% | Books, children's clothes |
| Exempt | - | Insurance, bank charges, Royal Mail postage |
| Outside scope | - | Wages, taxes, depreciation |
This is the part most non-UK developers get wrong. UK VAT isn't just "add 20%".
The LLM use case
If you're building AI-powered bookkeeping tools, the to_prompt_context() method formats the entire chart as structured text you can inject into an LLM prompt:
# Feed the chart to an LLM for transaction categorisation
context = coa.to_prompt_context(types=[AccountType.OVERHEAD])
prompt = f"""Given this chart of accounts:
{context}
Categorise this transaction: "TESCO 15.40 GBP"
"""
This gives the model the full code structure, names, and VAT treatments without you having to maintain prompt templates.
HMRC box mappings
Each code references the HMRC form and box it feeds into:
corp_tax = coa.get(2110)
corp_tax.hmrc_box # "CT600 Box 86"
entertainment = coa.get(7403)
entertainment.hmrc_box # "CT600 Box 46"
entertainment.description
# "VAT on business entertainment is blocked from input tax
# recovery (HMRC VAT Notice 700/65). Disallowable for
# corporation tax - must be added back on CT600."
Mappings cover CT600, VAT Return (Boxes 1-9), FPS/RTI, EPS, and CIS returns.
Install
pip install uk-chart-of-accounts
Background
I'm a finance professional who builds AI tools for UK accounting. This library came from extracting the reference data layer of a larger bookkeeping automation project. The codes, VAT treatments, and HMRC mappings are standard public knowledge - I've just packaged them in a way that's actually usable in code.
billkhiz-bit
/
uk-chart-of-accounts
Machine-readable UK Chart of Accounts for Python. 166 nominal codes with VAT treatments and HMRC mappings.
uk-chart-of-accounts
Machine-readable UK Chart of Accounts for Python. 166 standard nominal codes with account types, VAT treatments, and HMRC box mappings.
Install
pip install uk-chart-of-accounts
Quick start
from uk_coa import ChartOfAccounts, AccountType, VatRate
coa = ChartOfAccounts()
# Look up by code
account = coa.get(7602)
account.name # "Accountancy Fees"
account.type # AccountType.OVERHEAD
account.vat # VatRate.STANDARD
account.vat_rate_pct # 0.20
account.debit_increase # True (expenses increase on debit side)
# Search
coa.search("insurance") # All accounts with "insurance" in the name
coa.by_type(AccountType.INCOME) # All income accounts
coa.by_vat(VatRate.EXEMPT) # All VAT-exempt accounts
coa.by_tag("motor") # All motor-related accounts
coa.code_range(7000, 7012) # Payroll overheads
# Convenience
coa.expenses() …
Top comments (0)