How to Programmatically Verify UK Employer Sponsor Licence Status
If you're building HR compliance tooling, an ATS integration, or simply need to automate UK right-to-work checks, understanding the structure of the Home Office's sponsor licence register is essential. This post covers what the register contains, how to consume it, and what a compliant verification workflow looks like.
Background: The UK Sponsor Licence Register
The UK Home Office maintains a Register of Licensed Sponsors — a public dataset of all organisations currently authorised to issue Certificates of Sponsorship (CoS) for UK work visas. Under the UK points-based immigration system (post-Brexit), any employer hiring from outside the UK on most work routes must appear on this register.
The register is updated weekly (Thursdays) and published as a downloadable CSV on GOV.UK. As of mid-2026, it contains approximately 125,000+ entries.
Data Structure
The CSV schema is straightforward:
| Field | Description |
|---|---|
Organisation Name |
Legal trading name of the sponsor |
Town/City |
Registered location |
County |
UK county |
Type & Rating |
e.g. "Worker" (A), "Temporary Worker" (A), "Worker" (B) |
Route |
The visa categories they're licensed for |
There's no unique identifier column (no Companies House number, no HMRC reference), which creates challenges for exact matching — more on that below.
Licence ratings:
- A-rated: Fully compliant, can issue CoS without restrictions
- B-rated: Under a Home Office action plan; still licensed but with reduced privileges and likely under audit
Consuming the Register: Practical Notes
Download + Parse
The file is a zipped CSV, usually around 3-4MB unzipped. Standard approach:
import requests
import pandas as pd
import zipfile
import io
# The URL changes periodically — check GOV.UK for the latest
REGISTER_URL = "https://assets.publishing.service.gov.uk/media/[current-hash]/2024-02-29_Tier_2_5_Register_of_Licensed_Sponsors.xlsx"
# Alternatively, scrape the GOV.UK page to get the current download link
response = requests.get(REGISTER_URL)
df = pd.read_excel(io.BytesIO(response.content))
print(df.columns.tolist())
# ['Organisation Name', 'Town/City', 'County', 'Type & Rating', 'Route']
Note: The actual download URL is embedded in the GOV.UK page HTML. You'll need to scrape the page or hardcode a weekly refresh job to keep it current.
Fuzzy Matching Challenge
The biggest operational headache is name normalisation. Companies register under their legal entity name, which may differ from:
- Their trading name ("doing business as")
- How they appear in job ads
- How employees refer to them internally
A basic matching strategy:
from rapidfuzz import fuzz, process
def find_sponsor(query: str, register_df: pd.DataFrame, threshold: int = 85):
names = register_df['Organisation Name'].tolist()
result = process.extractOne(
query.upper(),
[n.upper() for n in names],
scorer=fuzz.token_sort_ratio,
score_cutoff=threshold
)
if result:
idx = result[2]
return register_df.iloc[idx]
return None
For production use, you'll want to normalise common suffixes (Ltd, Limited, PLC, LLP) and strip punctuation before matching.
Weekly Sync Architecture
A minimal production setup:
[Cron: Thursday 09:00 UTC]
→ Fetch GOV.UK page
→ Extract current download URL
→ Download and unzip CSV
→ Diff against previous week's dataset
→ Upsert into your database
→ Flag any sponsors in your system that dropped off or changed rating
Consider storing both the current register and a changelog — you'll want to alert if a sponsor your users depend on moves from A to B rating, or disappears entirely.
Verification Workflow for HR Compliance
For HR platforms, the verification flow should include:
- Search by name + location: Match the employer against the register with fuzzy tolerance
- Check the route: A "Temporary Worker" licence cannot support a Skilled Worker visa — route matters
- Confirm A-rating: B-rated sponsors can still technically issue CoS but should trigger a manual review flag
- Cross-check revoked sponsors: The Home Office also publishes a separate revoked sponsors list. Check both, not just the active register
-
Request licence number confirmation: The register has no unique ID, but the employer's actual licence number (format:
XXX-XXX-XXXXXX) can serve as a secondary verification step
What a CoS Verification Response Should Include
If you're exposing this as an API or internal tool, a verification response object might look like:
{
"query": "Acme Technologies Ltd",
"matched_name": "ACME TECHNOLOGIES LIMITED",
"match_confidence": 94,
"status": "active",
"rating": "A",
"routes": ["Worker"],
"location": "Manchester",
"last_checked": "2026-06-26T08:00:00Z",
"register_last_updated": "2026-06-19",
"warnings": []
}
Warnings should surface: B-rating, route mismatch, near-match uncertainty, or presence on the revoked list.
Tools and Resources
If you don't want to build this from scratch, ImmigrationGPT provides a real-time searchable interface over the full UK sponsor register, including revoked sponsor data, with an API-friendly design built specifically for HR and compliance use cases.
For teams who need programmatic access or bulk verification, building your own pipeline against the GOV.UK source is straightforward — the main investment is in the fuzzy matching layer and the weekly refresh job.
Summary
- The register is public, weekly-updated CSV data — consumable with any standard data stack
- Name matching is the hardest part; invest in normalisation and fuzzy matching
- Route and rating are as important as presence — "on the register" is not the same as "can sponsor your specific visa category"
- Build weekly diff alerting so you know when sponsor status changes for employers in your system
This is technical guidance for developers and HR compliance teams. For immigration advice specific to an individual's circumstances, consult a qualified UK immigration solicitor. Rules referenced are current as of June 2026.
Top comments (0)