Replacing getAddress.io? Free drop-in replacement →
← Back to Blog
Guides Oct 13, 2025 · 7 min read

Council Tax Bands API: VOA Data, Band Lookup, and Use Cases

How council tax bands are assigned, where the VOA data comes from, and how to look up bands programmatically for estate agents, proptech, and conveyancing tools.

What is council tax and how are bands set?

Council tax is a local government charge levied on all residential properties in England, Scotland, and Wales. Every property is assigned a band — A through H — which determines how much council tax the occupier pays each year.

The bands were set by the Valuation Office Agency (VOA) in 1991, based on the estimated open market value of each property at that time. They haven't been revalued since — which means a property's band reflects its relative value in 1991, not today. Two identical houses on the same street can be in different bands if one was built after 1991 (new properties are assessed against 1991 equivalent values).

The eight bands in England are:

Band 1991 value range Relative rate Typical annual bill (2024)
AUp to £40,0006/9 of Band D~£1,000–£1,400
B£40,001–£52,0007/9 of Band D~£1,200–£1,600
C£52,001–£68,0008/9 of Band D~£1,400–£1,800
D£68,001–£88,0001× Band D (baseline)~£1,600–£2,100
E£88,001–£120,00011/9 of Band D~£2,000–£2,600
F£120,001–£160,00013/9 of Band D~£2,300–£3,000
G£160,001–£320,00015/9 of Band D~£2,700–£3,500
HOver £320,00018/9 of Band D~£3,200–£4,200+

The exact charge depends on where the property is — each local authority sets its own Band D rate, and all other bands are calculated as a ratio of that. A Band A property always pays two-thirds of what a Band D property pays in the same council area.

Where the data comes from

The authoritative source is the Valuation Office Agency — a government body that maintains the council tax list for England and Wales. Their public-facing lookup tool at tax.service.gov.uk lets you check a band manually, but it's a web scraper's challenge: there's no official API, pagination is clunky, and rate limiting kicks in fast.

The Homedata Council Tax API solves this with a two-layer approach:

  1. Cached database — batch-scraped from the VOA across all ~1.8 million UK postcodes. UPRN lookups check this cache first — when the band is stored, response is milliseconds.
  2. Live VOA fallback — if a property isn't in the cache (new builds, recent changes), the API scrapes the VOA in real time and caches the result.

The one thing that trips everyone up

The Council Tax API is the only endpoint in the Homedata API that does not take a UPRN as its primary parameter. Every other endpoint uses ?uprn=. This one uses ?postcode= and ?building_number= (or ?building_name=).

That said, if you have a UPRN, you can pass it directly — the API will resolve the address internally and do a cached lookup:

# UPRN path (fastest when band is cached — falls back to live VOA if not)
GET /api/council_tax_band/?uprn=100023336956

# Postcode + building path (fallback to live VOA if not cached)
GET /api/council_tax_band/?postcode=SW1A+2AA&building_number=10

The UPRN path is usually faster — it checks the cached database first and only falls back to a live VOA scrape if the band isn't stored yet. If you only have an address string, use the Address Lookup API first to resolve address → UPRN, then pass the UPRN here.

Making your first request

cURL:

# By UPRN (fastest)
curl "https://api.homedata.co.uk/api/council_tax_band/?uprn=100023336956" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# By postcode + building number
curl -G "https://api.homedata.co.uk/api/council_tax_band/" \
  --data-urlencode "postcode=SW1A 2AA" \
  --data-urlencode "building_number=10" \
  -H "Authorization: Api-Key YOUR_API_KEY"

Python:

import requests

API_KEY = "your_api_key"

# By UPRN
resp = requests.get(
    "https://api.homedata.co.uk/api/council_tax_band/",
    params={"uprn": 100023336956},
    headers={"Authorization": f"Api-Key {API_KEY}"},
)
print(resp.json())

# By postcode + building number
resp = requests.get(
    "https://api.homedata.co.uk/api/council_tax_band/",
    params={"postcode": "SW1A 2AA", "building_number": "10"},
    headers={"Authorization": f"Api-Key {API_KEY}"},
)
print(resp.json())

JavaScript:

// By UPRN
const resp = await fetch(
  "https://api.homedata.co.uk/api/council_tax_band/?uprn=100023336956",
  { headers: { Authorization: "Api-Key YOUR_API_KEY" } }
);
const data = await resp.json();
console.log(data.council_tax_band); // "D"

Example response

{
  "uprn": 100023336956,
  "address": "10 DOWNING STREET, LONDON, SW1A 2AA",
  "postcode": "SW1A 2AA",
  "council_tax_band": "H",
  "source": "cached",
  "updated_at": "2026-03-14T04:36:00Z"
}

The source field tells you whether the result came from the cached database ("cached") or a live VOA scrape ("live"). Cached results are fastest; live lookups add ~2-4 seconds while the VOA is queried.

Use cases

Estate agent and portal listings

Council tax band is one of the most-requested fields on property listings. Buyers want to know before they enquire, not after they've spent time on a viewing. With the API, you can enrich your listing data at index time and show the band automatically — no manual entry, no stale data.

async function enrichListing(listing) {
  const resp = await fetch(
    `https://api.homedata.co.uk/api/council_tax_band/?uprn=${listing.uprn}`,
    { headers: { Authorization: "Api-Key YOUR_API_KEY" } }
  );
  if (!resp.ok) return listing;
  const { council_tax_band } = await resp.json();
  return { ...listing, council_tax_band };
}

Proptech form auto-fill

Mortgage applications, lettings forms, and insurance quotes all ask for council tax band. Pair the Address Lookup API (to resolve address → UPRN) with the Council Tax API to auto-fill the field the moment a user selects their address — reducing friction and data entry errors.

// After user selects address from autocomplete:
async function autofillFromAddress(selectedAddress) {
  // Step 1: Resolve address to UPRN
  const addressResp = await fetch(
    `https://api.homedata.co.uk/api/address/retrieve/${selectedAddress.uprn}/`,
    { headers: { Authorization: "Api-Key YOUR_API_KEY" } }
  );
  const { uprn } = await addressResp.json();

  // Step 2: Get council tax band
  const ctResp = await fetch(
    `https://api.homedata.co.uk/api/council_tax_band/?uprn=${uprn}`,
    { headers: { Authorization: "Api-Key YOUR_API_KEY" } }
  );
  const { council_tax_band } = await ctResp.json();

  // Step 3: Fill the form
  document.getElementById("council-tax-band").value = council_tax_band;
}

Conveyancing and property searches

Conveyancers are required to report council tax band to buyers as part of the property information form. Automating the lookup — rather than asking clients to find it themselves — reduces back-and-forth and speeds up the transaction.

Portfolio analysis and investment tools

If you're building a buy-to-let analyser or investment calculator, council tax band directly affects yield calculations. Different bands in the same postcode can mean a £600+ annual difference in running costs for a landlord. Surfacing this at the property level makes your analysis more accurate.

import requests

API_KEY = "your_api_key"

# Council tax costs by band in a typical local authority (2024 example)
BAND_RATES = {
    "A": 1200, "B": 1400, "C": 1600, "D": 1800,
    "E": 2200, "F": 2600, "G": 3000, "H": 3600,
}

def annual_council_tax(uprn: int) -> int | None:
    resp = requests.get(
        "https://api.homedata.co.uk/api/council_tax_band/",
        params={"uprn": uprn},
        headers={"Authorization": f"Api-Key {API_KEY}"},
    )
    if not resp.ok:
        return None
    band = resp.json().get("council_tax_band")
    return BAND_RATES.get(band)

Handling edge cases

  • Property not found (404) — UPRN not in the database. This can happen with very new builds or commercial/mixed-use properties that don't appear in the residential council tax list. Check the address first via the Address Lookup API.
  • No matching address found (404 with "error": "No matching address found") — Postcode + building lookup couldn't match on the VOA website. Try with building name instead of number, or use the UPRN path if available.
  • Service temporarily unavailable (503) — Live VOA scrape timed out. Retry after 60 seconds. The response includes a retry_after hint. For production use, the UPRN path avoids this — it hits the cached database and doesn't call the VOA at all if the band is already stored.
  • Scotland and Wales — Scotland uses Bands A-H with different 1991 value ranges. Wales revalued in 2003 and uses Bands A-I. Both are covered, though council area rates vary — the API returns band only, not the annual charge (which requires knowing the local authority rate).

Getting started

  1. Create a free Homedata account
  2. Get your API key from the developer dashboard
  3. Try it: GET /api/council_tax_band/?uprn={uprn}

See the full Council Tax API reference for all parameters and error codes, or explore the interactive API playground to test with your own postcodes.

Look up council tax bands programmatically

Free API key — 100 calls/month, no credit card required.