# UK Business Data Scraper: 1.4M Organisations, Renewal Dates (`uksignals/ico-signals`) Actor

Extract UK business data from the official ICO register: 1.4M organisations with annual renewal dates, verified size tiers, postcodes and trading names. Includes limited companies, sole traders and charities. Filter by expiry, tier, postcode area or name. Updated daily, no API key.

- **URL**: https://apify.com/uksignals/ico-signals.md
- **Developed by:** [UK Signals](https://apify.com/uksignals) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 organisation 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## UK Business Data Scraper: 1.4M Organisations With Renewal Dates and Size Tiers

Extract **UK business data** from the official ICO register of data protection
fee payers: **1,432,322 organisations** as of the 2026-08-25 register, each with
an annual renewal date and a verified size tier.

Covers **limited companies, LLPs, sole traders, charities and public
authorities**, not just registered companies. Filter by renewal window,
organisation size, postcode area or name, and export as JSON, CSV or Excel.

Useful for UK B2B lead generation, company enrichment, supplier due diligence
and market sizing.

> **Unofficial.** This Actor is not affiliated with, endorsed by, or operated by
> the Information Commissioner's Office. It reads the ICO's own published open
> data file. See [Data source, licence and limits](#data-source-licence-and-limits).

***

### Why this source beats a company registry

Paying the data protection fee is a **legal requirement**, not a voluntary
scheme, for almost any UK organisation processing personal data. That makes the
register unusually complete and unusually honest compared with the directory
data most B2B tools are built on, and it reaches far beyond incorporated
companies.

Two things fall out of it that you cannot get from Companies House or any
standard business directory:

**1. Renewal dates.** Registration lasts 12 months and must be renewed. Every
row carries its exact end date, so you can pull a dated renewal pipeline:

| Window | Organisations |
| --- | --- |
| Expiring within 30 days | 100,413 |
| 31 to 60 days | 133,849 |
| 61 to 90 days | 126,895 |

**2. Verified size banding.** Payment tier is set by the organisation's own
declared size, and it is a far cleaner size signal than employee-count guesses:

| Tier | Meaning | Count |
| --- | --- | --- |
| Tier 1 | Micro and small | 1,303,139 |
| Tier 2 | 10+ staff or ~£632k+ turnover | 121,823 |
| Tier 3 | 250+ staff or ~£36m+ turnover | 7,360 |

51,611 entries are public authorities, and can be included or excluded.

***

### Example: mid-size and large law firms in the City, renewing within 60 days

```json
{
  "expiringWithinDays": 60,
  "tiers": ["Tier 2", "Tier 3"],
  "postcodeAreas": ["EC", "E", "WC"],
  "nameIncludesAny": ["solicitors", "law", "legal", "llp"],
  "maxResults": 500
}
```

Returns rows like:

```json
{
  "reg_no": "Z5563277",
  "name": "Kingsley Napley LLP",
  "postcode": "EC2A 4DN",
  "tier": "Tier 3",
  "public_authority": false,
  "start_date": "2001-08-31",
  "end_date": "2026-08-30",
  "days_to_expiry": 5,
  "entry_url": "https://ico.org.uk/ESDWebPages/Entry/Z5563277",
  "register_date": "2026-08-25"
}
```

***

### Input

| Field | Description |
| --- | --- |
| `expiringWithinDays` | Only organisations whose registration ends within N days |
| `tiers` | `Tier 1`, `Tier 2`, `Tier 3` |
| `postcodeAreas` | Letters-only areas, e.g. `E`, `EC`, `RM`, `M`, `B` |
| `nameIncludesAny` | Substrings matched against name **and registered trading names** |
| `nameExcludes` | Substrings to filter out |
| `publicAuthority` | `any`, `only`, or `exclude` |
| `maxResults` | Stop after N matches |

**Postcode areas match exactly.** `E` returns E1 and E14 but never EC1, EH3 or
EN5. Most tools get this wrong by treating the area as a string prefix.

### Output

`reg_no`, `name`, `trading_names`, `address_line_1`, `postcode`, `tier`,
`public_authority`, `start_date`, `end_date`, `days_to_expiry`, `entry_url`,
`register_date`.

Export as JSON, CSV, Excel, or pull via the Apify API, MCP, Make, n8n or
Zapier.

***

### Data source, licence and limits

Data comes from the ICO's own daily published register, and the actor always
resolves the current day's file rather than a stale copy.

**No personal data is returned.** The source file contains DPO contact columns
(name, email, phone, address). These are never read or emitted, because the
Open Government Licence does not extend to personal data in the dataset.

**Known limits, stated plainly:**

- The register lists organisations that are *currently* registered. Entries are
  removed once a registration lapses, so a search cannot tell you who has
  stopped being registered.
- Registered address is the address given to the ICO, which is often a
  registered office rather than a trading address.
- Sector is not a field in the source. Name matching is the available proxy.

### Attribution

Contains public sector information from the Information Commissioner's Office
(register of fee payers), licensed under the
[Open Government Licence v3.0](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).

This is an **unofficial** Actor. It is not affiliated with, endorsed by, or
operated by the Information Commissioner's Office.

**This Actor is stateless.** It reads the ICO's published file, returns the rows
matching your filters to your own dataset, and retains nothing between runs. No
copy of the output is kept, aggregated, or resold.

**On lawful use:** the OGL permits commercial reuse, but UK GDPR and PECR apply
to what you do with the output independently of the licence. Direct marketing to
sole traders and partnerships in particular is treated differently from
marketing to corporate bodies. Use accordingly.

# Actor input Schema

## `expiringWithinDays` (type: `integer`):

Only return organisations whose ICO registration ends within this many days. Registration is annual and mandatory, so this is a renewal window. Leave empty for no date filter.

## `tiers` (type: `array`):

Tier 1 = micro/small. Tier 2 = more than 10 staff or ~£632k turnover. Tier 3 = more than 250 staff or ~£36m turnover. Tier is a reliable size proxy.

## `postcodeAreas` (type: `array`):

UK postcode areas, letters only, e.g. E, EC, RM, IG, M, B. Matching is exact: 'E' returns E1 and E14 but never EC1, EH3 or EN5.

## `nameIncludesAny` (type: `array`):

Case-insensitive substrings. Matches the registered organisation name or any of its registered trading names. Example: solicitors, law, legal, llp

## `nameExcludes` (type: `array`):

Case-insensitive substrings to filter out.

## `publicAuthority` (type: `string`):

Restrict to public authorities, or exclude them. 51,611 of the 1.4M entries are public authorities.

## `maxResults` (type: `integer`):

Stop after this many matches.

## Actor input object example

```json
{
  "expiringWithinDays": 60,
  "tiers": [],
  "postcodeAreas": [],
  "nameIncludesAny": [],
  "nameExcludes": [],
  "publicAuthority": "any",
  "maxResults": 1000
}
```

# Actor output Schema

## `organisations` (type: `string`):

One row per organisation, with registration number, name, trading names, postcode, payment tier, registration start and end dates, days to expiry and a link to its ICO register entry.

# 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 = {
    "expiringWithinDays": 60,
    "maxResults": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("uksignals/ico-signals").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 = {
    "expiringWithinDays": 60,
    "maxResults": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("uksignals/ico-signals").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 '{
  "expiringWithinDays": 60,
  "maxResults": 1000
}' |
apify call uksignals/ico-signals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,uksignals/ico-signals"
        }
    }
}

```

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/Aq8sFXhrWLI6mLfeC/builds/clNvkGJGNW5nCDQuj/openapi.json
