If you are an international developer looking for work in the UK, there is one question worth answering before you write a single cover letter: is this employer licensed to sponsor visas at all?

The Home Office publishes the answer as open data. It is a CSV file, it updates regularly, and it is a surprisingly good exercise in handling messy real-world data. Here is how to query it from your terminal.

Where the data lives

GOV.UK publishes the Register of licensed sponsors: workers. The version I used was updated on 6 November 2026. It is a single CSV of about 10 MB with five columns:

Organisation Name,Town/City,County,Type & Rating,Route 

That file has 143,053 data rows but only about 127,000 distinct organisation names, because many organisations appear once per immigration route (for example "Skilled Worker" and "Global Business Mobility: Senior or Specialist Worker") and sometimes once per location.

Three gotchas in the raw file

Before writing any code, open the CSV and look. You will find:

  1. Stray whitespace. Values like " Asian African Foods Ltd " and " London " have leading and trailing spaces.
  2. Commas inside names. Some organisation names are quoted because they contain commas, so splitting each line on , will silently shift columns. Use a real CSV parser.
  3. Legal names, not brands. The register uses the legal entity. Searching for "Deliveroo" only works because the entry reads Roofoods Ltd t/a Deliveroo. Many companies do not include a trading name at all, so you may need the legal name from Companies House.

The script

Install one dependency:

npm init -y npm install csv-parse 

Download the latest CSV from the GOV.UK page above, save it as register.csv, then create check-sponsor.mjs:

// check-sponsor.mjs // Usage: node check-sponsor.mjs register.csv "company name" import { readFile } from "node:fs/promises"; import { parse } from "csv-parse/sync"; const [, , file, query] = process.argv; if (!file || !query) { console.error('Usage: node check-sponsor.mjs register.csv "company name"'); process.exit(1); } // Normalise names so "ACME Ltd " and "Acme Limited" compare equally const normalise = (s) => s .toLowerCase() .replace(/&/g, " and ") .replace(/\b(limited|ltd|plc|llp)\b\.?/g, " ") .replace(/[^a-z0-9 ]/g, " ") .replace(/\s+/g, " ") .trim(); const rows = parse(await readFile(file, "utf8"), { columns: true, // first line holds the headers bom: true, trim: true, // the register has stray spaces around values skip_empty_lines: true, }); const target = normalise(query); const matches = rows.filter((r) => normalise(r["Organisation Name"]).includes(target) ); if (matches.length === 0) { console.log(`No licensed sponsor found for "${query}". Check the legal name on Companies House.`); } else { for (const r of matches.slice(0, 20)) { console.log(`${r["Organisation Name"]} | ${r["Town/City"]} | ${r["Type & Rating"]} | ${r["Route"]}`); } if (matches.length > 20) console.log(`...and ${matches.length - 20} more`); } 

Run it:

node check-sponsor.mjs register.csv "Deliveroo" 

Against the 6 November 2026 file, that prints:

Roofoods Ltd t/a Deliveroo | London | Worker (A rating) | Skilled Worker Roofoods Ltd t/a Deliveroo | London | Worker (A rating) | Global Business Mobility: Senior or Specialist Worker 

And a name that is not on the register returns the "No licensed sponsor found" message instead of an empty screen, which is friendlier when you are checking a list of companies.

Reading the result

  • Route tells you what the licence covers. For most developer roles you care about Skilled Worker.
  • Type & Rating shows values such as Worker (A rating) or Worker (B rating). A B rating usually means the Home Office has asked the sponsor to make improvements, so it is worth a closer look.
  • A licence is necessary, not sufficient. The specific job still has to meet the rules for that route, including the occupation and salary requirements. Check the current guidance on GOV.UK or ask the employer directly. This script is a first filter, not legal advice.

Ideas to extend it

  • Batch mode: read a list of company names from a text file and print a yes or no for each, so you can screen a job board export in seconds.
  • Freshness check: the register changes as licences are granted, suspended and revoked, so fetch the latest file before relying on an old copy.
  • Tighter matching: substring search is greedy. Searching "Revolut" correctly returns Revolut Ltd, but also Revolution Oil Limited and a dozen other "Revolution" companies. Matching on whole words (for example a regular expression with \b boundaries) cuts that noise, and a library such as fuse.js helps with genuine typos.
  • Legal name lookup: the Companies House API can map a brand to its registered company name before you search.

Checking the register first saves hours of tailoring applications for employers who could never have hired you. If you try this, tell me in the comments what edge cases you hit in the data.

Disclosure: this article was generated by an AI agent at the request of the author. The code was run against the 6 November 2026 register before publishing, and the outputs shown are real.