# UK Visa Sponsor Register: Skilled Worker Sponsors + Changes (`wrtcom/uk-visa-sponsors`) Actor

Home Office register of licensed sponsors (Skilled Worker and all worker routes) as JSON: organisation, town, A/B rating, routes. Daily feed of added, removed and downgraded sponsors. $2 per 1,000. No personal data.

- **URL**: https://apify.com/wrtcom/uk-visa-sponsors.md
- **Developed by:** [WRTLabs](https://apify.com/wrtcom) (community)
- **Categories:** Jobs, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 sponsor records

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: Skilled Worker Sponsors + Changes

Every organisation licensed by the UK Home Office to sponsor workers (Skilled Worker, Global Business
Mobility, Creative, Charity, Religious and other routes) from the **official GOV.UK register**, in
**one clean JSON format**: one row per organisation and town, with its A/B rating and all its routes.
Or run it daily in **changes** mode and get only the sponsors that were **added, removed or changed**
(for example downgraded from A to B).

Data comes from the official register CSV that the Home Office publishes on GOV.UK every working day.
We don't use logins, and the output contains **no personal data**: sponsors that may be individuals
(sole traders) are left out (see "How it behaves").

### What you get

Snapshot mode, one row per sponsor (example from the 2026-11-06 register):

```json
{
  "id": "f2fe8b5b3e0ede5f",
  "record_type": "sponsor",
  "organisation_name": "(IECC Care) Independent Excel Care Consortium Limited",
  "town": "Colchester",
  "county": null,
  "worker_rating": "A",
  "temporary_worker_rating": null,
  "routes": ["Skilled Worker"],
  "register_date": "2026-11-06",
  "register_url": "https://www.gov.uk/government/publications/register-of-licensed-sponsors-workers",
  "licence": "OGL-UK-3.0",
  "attribution": "Contains public sector information licensed under the Open Government Licence v3.0. Source: Home Office, ..."
}
```

| Field | Meaning |
|---|---|
| `id` | stable id of the sponsor (organisation + town + county) |
| `record_type` | `sponsor` (snapshot) or `change` (changes mode) |
| `organisation_name`, `town`, `county` | as in the register (most rows have no county) |
| `worker_rating` | Worker licence rating: `A`, `B` (downgraded), `A (Premium)`, `A (SME+)`, `UK Expansion Worker: Provisional` |
| `temporary_worker_rating` | Temporary Worker licence rating, same values |
| `routes` | all visa routes the sponsor is licensed for, e.g. `Skilled Worker`, `Creative Worker` |
| `register_date` | date of the register file the row comes from |
| `change_type` | changes mode: `added`, `removed` or `changed` |
| `changed_fields`, `old`, `new` | changes mode: what changed (rating / routes) with the old and new values |
| `previous_register_date` | changes mode: the register date your previous run compared against |
| `licence`, `licence_url`, `attribution` | source licence, kept on every row |

Each run also saves two reports (linked on the Output tab): `RUN_REPORT` (records delivered, invalid
records dropped, whether the run collected everything) and `SPONSORS_REPORT` (register date and file,
rows read, sponsors delivered, names left out as possible individuals, baseline / change counts).

**Coverage note:** the register lists about 143,000 rows (one per sponsor, town and route); grouped,
that is about 128,000 organisations, of which about 105,000 are delivered (2026-11-06). About 18% of
names are left out because they may be a sole trader or another individual. The Home Office updates
the register on working days; there is no history in the file, so changes start from your first
changes-mode run.

### Input

| Option | Default | |
|---|---|---|
| Mode | snapshot | `snapshot` = every sponsor; `changes` = added / removed / changed since your previous changes run |
| Organisation name keywords | (all) | any word in the name, e.g. `care`, `software` |
| Towns / cities | (all) | exact town, e.g. `London`, `Manchester` |
| Counties | (all) | exact county (most rows have none) |
| Visa routes | (all) | words in the route name, e.g. `Skilled Worker`, `Creative` |
| Ratings | (all) | `A`, `B`, `A (Premium)`, ... |
| Change types | (all) | changes mode: `added`, `removed`, `changed` |
| Max results | 1000 (form starts at 50 for a quick test) | hard stop, so you control cost |
| Only new since last run | off | snapshot mode: only sponsors you have not received before |

**Changes mode, first run:** it saves today's register as your baseline and returns no records.
Schedule it daily; from the next register on you get the changes. A run that stops early (max
results or max cost reached) does not move the baseline, so the next run returns the same changes
again (turn on "Only new" to skip those you already have).

### Typical uses

- Job seekers and recruiters: which employers in a town or sector can sponsor a Skilled Worker visa.
- Compliance and HR teams: get told when a sponsor is removed or downgraded to B.
- Immigration advisers and market researchers: new sponsor licences every day, by route.

### Pricing

Pay per result: `sponsor` record $0.002, `change` record $0.003, see the Pricing tab. You pay only for
records delivered to your dataset. The Actor stops when it reaches the max cost per run you set.

### How it behaves

- Polite by design: obeys robots.txt, one request at a time, identifies itself; one small JSON request
  plus one download of the register file (~11 MB) per run.
- **No personal data.** A name is delivered only when it is clearly an organisation: it ends in a legal
  form (Ltd, Limited, PLC, LLP, CIC, CIO, ...), it is an institution (University, College, Council, NHS
  Trust, Trust, Foundation, Charity, Society, Association, Institute, Hospice, Church, Mosque, Temple,
  ...), or it is such a company trading under another name ("Example Ltd T/A Cafe Example"). Names
  with personal titles or post-nominals (Mr, Mrs, Dr, Pastor, MBE ...), trading phrases after a
  person ("John Smith T/A ...", "doing business as", "known as"), private trusts (family, will,
  pension trusts) and a bare "<one word> Church / Temple" are left out and only counted in
  `SPONSORS_REPORT`. So some real organisations without a legal form in the name (for example
  "Example Corner Shop") are not in the output. The check is a rule set, not a guarantee: a
  company may trade under its founder's name ("Example Ltd T/A Jane Doe Associates").
- Every record is checked against the output schema before delivery. Broken records are dropped
  (you are not charged for them) and counted in the run report. If more than 5% of the records
  fail the check, the run is marked **Failed**, so a change on the source side never goes unnoticed.

### Data licence and attribution

Re-use of the output must keep the attribution in each row:

- Home Office, Register of licensed sponsors: workers: *"Contains public sector information licensed
  under the Open Government Licence v3.0."*
  [OGL v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/),
  [source page](https://www.gov.uk/government/publications/register-of-licensed-sponsors-workers).

This Actor is not affiliated with or endorsed by the Home Office, UK Visas and Immigration or GOV.UK.

# Actor input Schema

## `mode` (type: `string`):

'snapshot' = one record per licensed sponsor (organisation + town). 'changes' = sponsors added, removed or changed (A/B rating, routes) since your previous 'changes' run. The FIRST 'changes' run only saves today's register as the baseline and returns no records; schedule it daily (the register is updated on working days).

## `keywords` (type: `array`):

Keep only sponsors whose name contains any of these words (case-insensitive), e.g. 'care', 'NHS', 'software'. Empty = all.

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

Exact town or city as written in the register, case-insensitive, e.g. 'London', 'Manchester'. Empty = all.

## `counties` (type: `array`):

Exact county as written in the register, case-insensitive, e.g. 'Greater London', 'West Yorkshire'. Most rows have no county. Empty = all.

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

Keep sponsors licensed for a route containing any of these words, e.g. 'Skilled Worker', 'Creative', 'Global Business Mobility', 'Charity'. Empty = all.

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

Keep sponsors with any of these ratings: 'A', 'B' (downgraded), 'A (Premium)', 'A (SME+)', 'UK Expansion Worker: Provisional'. Empty = all.

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

Changes mode only: which changes to return. Empty = all.

## `maxItems` (type: `integer`):

Stop after this many results (you pay per result). The form starts at 50 for a quick test; default without a value is 1000. The full register is about 105,000 sponsors.

## `onlyNew` (type: `boolean`):

Skip records already returned by earlier runs on your account (snapshot mode: = sponsors you have not received yet).

## Actor input object example

```json
{
  "mode": "snapshot",
  "maxItems": 50,
  "onlyNew": false
}
```

# Actor output Schema

## `records` (type: `string`):

Organisation, town, county, Worker / Temporary Worker rating, visa routes; in changes mode also the change type and old / new values.

## `allFields` (type: `string`):

Same records with every field.

## `runReport` (type: `string`):

JSON report per source: pages fetched, records scanned and delivered, success/block rate, whether the run collected everything.

## `sponsorsReport` (type: `string`):

Register date and file, rows read, sponsors kept, names withheld as possible individuals, baseline / change counts.

# 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 = {
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("wrtcom/uk-visa-sponsors").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 = { "maxItems": 50 }

# Run the Actor and wait for it to finish
run = client.actor("wrtcom/uk-visa-sponsors").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 '{
  "maxItems": 50
}' |
apify call wrtcom/uk-visa-sponsors --silent --output-dataset

```

## MCP server setup

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

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/P6g1KBVWnRR6zNgQr/builds/s2bnHsHX19wM9IUny/openapi.json
