# UK Visa Sponsor Register Scraper: Home Office Sponsor Monitor (`seaf999ield/uk-visa-sponsor-register-monitor`) Actor

UK visa sponsor licence list from the Home Office Register of Licensed Sponsors: new, removed and A-to-B downgraded sponsors, Skilled Worker leads, by RawTrader | UK Industry & Bills: https://ukindustryandbills.substack.com · X: x.com/ImRawTrader

- **URL**: https://apify.com/seaf999ield/uk-visa-sponsor-register-monitor.md
- **Developed by:** [RustonRoad](https://apify.com/seaf999ield) (community)
- **Categories:** Jobs, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## UK Visa Sponsor Register Scraper: Home Office Sponsor Monitor

**Get alerted when UK employers gain, lose or change their Home Office visa sponsor licence.**

### Who it's for

- Immigration lawyers and advisers looking for employers that need help
- Recruiters finding employers able to sponsor Skilled Worker visas
- HR and compliance teams monitoring their own or partners' licence status

### Sample output

| changeType | organisationName | town | route | newRating |
|---|---|---|---|---|
| SPONSOR_DOWNGRADED | Example Employer Ltd | London | Skilled Worker | Worker (B rating) |

*Illustrative row showing the field layout (not a real employer).*

### Price per 1,000 results

Main event: **`change` at $0.01 each**, so **1,000 results = $10.00**. Other events: `snapshot-row` $0.001, `enriched-row` $0.004 each (only charged when that row type is output). See the Pricing tab for the current prices.

### Input example

```json
{
  "monitorName": "default"
}
```

**Get alerted when UK employers gain, lose or change their Home Office sponsor licence.** This actor checks the official **Register of Licensed Sponsors (Worker and Temporary Worker)**, published daily on GOV.UK, and returns **only what changed since your last run**:

| Change type | What it means |
|---|---|
| 🟢 **SPONSOR_ADDED** | A new licensed sponsor appeared, with town, county, route and rating |
| 🔴 **SPONSOR_REMOVED** | A sponsor dropped off the register (licence revoked, surrendered or expired) |
| ➕ **ROUTE_ADDED** / ➖ **ROUTE_REMOVED** | An existing sponsor gained or lost a route, e.g. Skilled Worker, Global Business Mobility, Scale-up, Creative Worker |
| ⚠️ **RATING_CHANGED** | e.g. A rating → B rating. Flagged with `isDowngrade: true` |

Every row carries a **`severity`** and a plain-English **`alertReason`**, so downgrades and removals stand out:

| Severity | When |
|---|---|
| 🔴 `high` | Sponsor removed from the register, or a rating **downgrade** (e.g. A → B) |
| 🟠 `medium` | A route removed (`isRemoval: true`), or another rating change |
| ⚪ `info` | New sponsors, routes added, upgrades, SNAPSHOT rows |

Set **Minimum severity** to `high` to receive only removals and downgrades.

There's no need to download a 140,000-row CSV every day and diff it yourself.

**Free weekly newsletter**, UK Industry & Bills: https://ukindustryandbills.substack.com

### What you get

- Only what changed on the Home Office **Register of Licensed Sponsors** since your last run: sponsors added, sponsors removed, routes added or removed, and A→B rating downgrades
- Organisation name, town, county, route, previous and new rating, severity and a plain-English alert reason on every row
- Optional full-register snapshot (the whole UK visa sponsor list) on a baseline run
- Optional Companies House enrichment: company number, status, SIC codes, incorporation date and insolvency flag
- Export to CSV, Excel or JSON, or send alerts to Slack, email, Make or Zapier

### Who uses it

- **Recruitment and talent agencies:** find newly licensed employers who can sponsor visas. They are hot leads for international hiring.
- **Job boards and sponsor-job sites:** keep "visa sponsor" badges accurate and remove revoked sponsors automatically.
- **HR, compliance and due-diligence teams:** watch your clients, suppliers or portfolio companies for downgrades and removals.
- **Researchers and journalists:** track licence revocations by sector, town or route over time.

### How it works

1. **Auto-discovery:** each run finds the latest official CSV through the GOV.UK Content API.
2. **Normalise:** it cleans the data (whitespace, duplicates) and groups rows by organisation and town.
3. **Compare:** it checks today's register against the snapshot saved from your previous run. Snapshots are kept per **Monitor name**, so you can run several monitors.
4. **Output:** only the changes are returned. The **first run is a baseline**: it saves state and outputs nothing, unless you turn on "Output full list on first run".

**Schedule it daily** (e.g. 10:00 UK time; GOV.UK usually updates the file in the morning) and connect a webhook, Slack, email, Make, Zapier or n8n.

### Input

| Field | Example | Notes |
|---|---|---|
| Monitor name | `london-tech-leads` | Separate saved state per name |
| Towns / cities | `["London", "Manchester"]` | Partial, case-insensitive |
| Visa routes | `["Skilled Worker", "Scale-up"]` | Partial match |
| Ratings | `["B rating"]` | Partial match on "Type & Rating" |
| Change types | `["SPONSOR_ADDED", "RATING_CHANGED"]` | Empty means all |
| Organisations only | `true` | Leaves out entries listed under a private individual's name |
| Output full list on first run | `false` | Turn on to get a full snapshot export |
| Max snapshot rows | `0` | Cap on SNAPSHOT rows (0 = no cap) |
| Minimum severity | `info` | `high` = only removals and downgrades |
| Enrich with Companies House | `false` | Optional, see below |
| Max organisations to enrich | `500` | Lookup cap per run |
| Your Companies House API key | *(empty)* | Optional, secret; for large runs |

### Optional: Companies House enrichment

Turn on **Enrich with Companies House** to match each output row's organisation to the official Companies House register (search by name, then the company profile). Matched rows gain:
`chCompanyNumber`, `chCompanyName`, `chCompanyStatus` (active, dissolved, liquidation…), `chCompanyType`, `chSicCodes`, `chIncorporationDate`, `chHasInsolvencyHistory`, **`chInsolvencyFlag`** (insolvency history, or status liquidation/administration/receivership/insolvency proceedings/voluntary arrangement), `chRegisteredAddress`, `chUrl`, plus `chMatchType` (`exact` or `name-variant`) and `chCandidateCount`.

- **Conservative matching:** only names identical after normalisation (case, punctuation, "&"/"and", Ltd/Limited, any "t/a" trading name) are matched; preference goes to UK-registered, active companies in the same town. No confident match = `ch*` fields are `null` and the row isn't billed for enrichment. Universities, NHS trusts, councils and sole traders often aren't companies, so they won't match.
- **Company-level data only.** No officers, PSCs or other personal data.
- **Speed:** about 2 API calls per organisation, rate-limited to the Companies House allowance (600 calls / 5 min). Use filters and **Max organisations to enrich** for big runs, or supply your own free API key.
- Use the **With Companies House** view in the Output tab.

When the option is off (the default), nothing changes: no Companies House calls and no extra cost.

**Example input: London Skilled Worker sponsors, additions and downgrades only**

```json
{"monitorName":"london-skilled-worker","towns":["London"],"routes":["Skilled Worker"],"changeTypes":["SPONSOR_ADDED","RATING_CHANGED"],"organisationsOnly":true,"outputSnapshotOnFirstRun":false}
```

#### Example output (real sample)

| changeType | organisationName | town | route | newRating | severity |
|---|---|---|---|---|---|
| RATING_CHANGED | Alium Consultancy Ltd | London | Skilled Worker | Worker (B rating) | high |
| RATING_CHANGED | HOUSE OF CARDS LTD | London | Skilled Worker | Worker (A rating) | info |
| RATING_CHANGED | ETERNIQUE LIMITED | LONDON | Skilled Worker | Worker (A rating) | info |

### Output example

One dataset item per change (Output tab → **Changes** view), plus a `RUN_SUMMARY` record in the key-value store with counts per change type and the register dates compared.

```json
{"changeType":"RATING_CHANGED","severity":"high","alertReason":"Rating downgraded: Worker (A rating) -> Worker (B rating)","organisationName":"Alium Consultancy Ltd","town":"London","county":"London, City of","route":"Skilled Worker","previousRating":"Worker (A rating)","newRating":"Worker (B rating)","isDowngrade":true,"isRemoval":false,"registerDate":"2026-10-20","previousRegisterDate":"2026-10-19","source":"Home Office Register of Licensed Sponsors (GOV.UK)","licence":"Open Government Licence v3.0"}
```

With Companies House enrichment on, the same row also includes e.g. `"chCompanyNumber":"01234567","chCompanyStatus":"active","chSicCodes":["87100"],"chIncorporationDate":"2011-03-02","chInsolvencyFlag":false,"chMatchType":"exact"`.

### Pricing

**In plain words:** **$10 per 1,000 change rows**, **$1 per 1,000 rows** for an optional full-register snapshot, and **$4 per 1,000** Companies House-enriched rows. A daily monitor typically costs cents.

**Pay per result:** you pay only for the change rows returned (one dataset item = one result). Optional full-list SNAPSHOT rows on a baseline run are billed at a much lower per-row price. A baseline run without snapshot output, or a day with no matching changes, costs almost nothing. Rows enriched with Companies House (optional, off by default) add a small per-row `enriched-row` charge, only when a match is found. Prices are shown on the Store page.

### Data, licence and privacy

- **Source:** Home Office [Register of licensed sponsors: workers](https://www.gov.uk/government/publications/register-of-licensed-sponsors-workers), published under the **Open Government Licence v3.0**. Attribution is included on every record.
- **Organisation data only:** organisation name, town, county, route and rating (plus, if enabled, company-level Companies House data, also OGL). No contacts, emails, officers or people.
- **Sole traders:** some register entries are sole traders listed under a personal name. With **Organisations only** on (the default), those entries are skipped. This uses a heuristic covering title prefixes (Mr/Mrs/Dr…), "Firstname SURNAME" patterns and common first names.
- **Not immigration advice.** This is a data feed. It does not tell you whether anyone qualifies for a visa.

### FAQ

- **Why is my first run empty?** It's the baseline. Changes appear from the second run onwards.
- **How often does the register change?** GOV.UK republishes it on working days. Daily changes vary, so check the run summary (`RUN_SUMMARY`) for counts.
- **Can I get sponsored job ads too?** Not yet. There's no free, keyless official jobs API (Find a job has no public API; Reed and Adzuna need keys). This may be added later.
- **Can I get the whole register?** Yes. Turn on "Output full list on first run", or use a new Monitor name.

*Keywords: UK visa sponsor list, register of licensed sponsors API, skilled worker sponsor list, sponsor licence revoked, UK visa sponsorship companies, Home Office sponsor register CSV, tier 2 sponsor list, sponsor licence monitoring.*

### Related UK data actors

- [UK Jobs Scraper: NHS Jobs, DWP Find a Job & Careers Pages](https://apify.com/seaf999ield/uk-jobs-feed)
- [UK Companies House Scraper: New Companies & Insolvency Alerts](https://apify.com/seaf999ield/uk-companies-house-feed)
- [UK Gazette Insolvency Scraper: Winding-Up & Liquidations](https://apify.com/seaf999ield/uk-gazette-insolvency-notices)

### About RawTrader | UK Industry & Bills

RawTrader | UK Industry & Bills is a UK newsletter and open data project tracking energy bills, fuel prices, public tenders, company closures and FCA short positions, using official data from Ofgem, DESNZ, ONS, Companies House, Find a Tender and the FCA.

- [RawTrader Data: every UK data tool in one place](https://imrawtrader.beehiiv.com/p/data)
- [UK Industry & Bills newsletter](https://imrawtrader.beehiiv.com)
- [Follow @ImRawTrader on X](https://x.com/ImRawTrader)

# Actor input Schema

## `monitorName` (type: `string`):

State is saved under this name (named key-value store uk-sponsor-monitor-<name>), so you can run separate monitors, e.g. one per client. Changes are computed against the previous run with the same name. A new name starts a new baseline.

## `towns` (type: `array`):

Only report changes for these towns (case-insensitive, partial match, e.g. 'London', 'Manchester'). Empty = all UK.

## `routes` (type: `array`):

Partial match on route, e.g. 'Skilled Worker', 'Global Business Mobility', 'Scale-up', 'Creative Worker'. Empty = all.

## `ratings` (type: `array`):

Partial match on type & rating, e.g. 'A rating', 'B rating', 'Temporary Worker'. Empty = all.

## `changeTypes` (type: `array`):

Which changes to output. Empty = all.

## `organisationsOnly` (type: `boolean`):

Skip register entries that look like a private individual's name (e.g. sole traders) rather than an organisation. Heuristic; recommended for GDPR data-minimisation.

## `outputSnapshotOnFirstRun` (type: `boolean`):

On the first (baseline) run for a monitor name, also output every matching sponsor route as a SNAPSHOT row (billed per row; use filters to keep it small — the full register is ~140k rows). Off = the baseline run outputs nothing and only saves state.

## `minSeverity` (type: `string`):

Only output rows at or above this severity. high = sponsor removed or rating downgraded (A → B); medium = a route removed or other rating change; info = additions, upgrades, snapshot rows. Default 'info' outputs everything.

## `maxSnapshotRows` (type: `integer`):

Cap on SNAPSHOT rows output on a baseline run with 'Output full list on first run' on. 0 = no cap.

## `enrichWithCompaniesHouse` (type: `boolean`):

Optional, off by default. Match each output row's organisation name to Companies House (official search API) and add company number, status, type, SIC codes, incorporation date and an insolvency flag. Company-level data only: no officers or personal data. Rows with a confident match are billed an extra 'enriched-row' event ($0.004); unmatched rows are not billed for enrichment.

## `maxEnrichments` (type: `integer`):

Upper limit on Companies House lookups (distinct organisations) per run; rows beyond it are output without enrichment. Each lookup takes ~2 API calls and the API allows 600 calls per 5 minutes, so large numbers slow the run.

## `companiesHouseApiKey` (type: `string`):

Optional. Leave empty to use the actor's built-in key. Supply your own free key (developer.company-information.service.gov.uk) for large runs to get your own rate limit.

## `csvUrl` (type: `string`):

Advanced/testing: a direct URL to a register CSV. Leave empty to auto-discover the latest official file from GOV.UK.

## Actor input object example

```json
{
  "monitorName": "default",
  "towns": [],
  "routes": [],
  "ratings": [],
  "changeTypes": [],
  "organisationsOnly": true,
  "outputSnapshotOnFirstRun": false,
  "minSeverity": "info",
  "maxSnapshotRows": 0,
  "enrichWithCompaniesHouse": false,
  "maxEnrichments": 500,
  "csvUrl": ""
}
```

# Actor output Schema

## `results` (type: `string`):

Sponsor register changes since the previous run with the same monitor name.

## `runSummary` (type: `string`):

JSON with baseline flag, counts per change type and previous/current register metadata.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "monitorName": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("seaf999ield/uk-visa-sponsor-register-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "monitorName": "default" }

# Run the Actor and wait for it to finish
run = client.actor("seaf999ield/uk-visa-sponsor-register-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "monitorName": "default"
}' |
apify call seaf999ield/uk-visa-sponsor-register-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,seaf999ield/uk-visa-sponsor-register-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rtYrAhPH0hO62zrfQ/builds/UiwhEb8YCVD9e60MT/openapi.json
