# Companies House UK Scraper & Monitor (`tiger19935/companies-house-scraper`) Actor

Companies House scraper using the official API: search UK companies, officers, PSC, charges and filings. Get daily new-incorporation lead lists by SIC code and postcode, monitor watchlist changes, export JSON, CSV or Excel. Pay per result, from $2 per 1,000 companies.

- **URL**: https://apify.com/tiger19935/companies-house-scraper.md
- **Developed by:** [Andrew Boiko](https://apify.com/tiger19935) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 companies

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Companies House UK Scraper & Monitor

Companies House scraper that reads UK company data straight from the official Companies House REST API: no HTML scraping, nothing that breaks when the website changes. Look up companies by number or name, pull officers, persons with significant control (PSC), filing history and charges, build a daily list of newly incorporated UK companies by SIC code, location or postcode, and monitor a watchlist for changes. Export to JSON, CSV or Excel, call it from the API, or plug it into n8n, Make, Zapier and MCP agents.

### What does Companies House UK Scraper & Monitor do?

This Actor wraps the free official Companies House API (`api.company-information.service.gov.uk`) in eight modes:

| Mode | What you get | Billed as |
|---|---|---|
| `lookup` | Company profile by number or name: status, type, incorporation date, SIC codes, registered office, accounts and confirmation-statement dates, charges and insolvency flags | `company` |
| `search` | Companies matching a name search phrase | `company` |
| `officers` | Directors, secretaries and other officers of a company (active only, or including resigned) | `officer-psc` |
| `psc` | Persons with significant control: natures of control, notified and ceased dates | `officer-psc` |
| `filings` | Filing history with category, type, date and description, optional category filter | `officer-psc` |
| `charges` | Registered charges (mortgages): status, dates, persons entitled | `officer-psc` |
| `new-incorporations` | Newly registered companies for a date range, filtered by SIC code, location text and postcode prefix, optionally with officers | `new-incorporation` (+ `officer-psc`) |
| `monitor` | Change events on a watchlist since the previous run: status, name, address, accounts, filings, officers, PSC, charges | `change-event` |

Every row carries a `recordType` field (`company`, `officer`, `psc`, `filing`, `charge`, `incorporation`, `change`) and a link to the public Companies House page, so mixed results stay easy to filter in a spreadsheet.

### Why use Companies House UK Scraper & Monitor?

- **Official API, not HTML scraping.** The most used Companies House scrapers in the Store parse web pages, which is slow and breaks when the site changes. This Actor calls the documented REST API, so the field names and values are the ones the registry publishes.
- **Lead feed and monitor in one tool.** Most alternatives only look up companies one by one. Here the same Actor also produces a new-incorporations lead list (by SIC code, location and postcode prefix, with officer names on request) and a change monitor for companies you care about.
- **Cheap and predictable.** Company rows cost $2 per 1,000 on the free plan (down to $1.40 per 1,000 on the Gold plan), new incorporations $0.50 per 1,000. You can cap spend with Apify's maximum total charge setting and the Max results field.
- **Rate limits handled for you.** Companies House allows 600 requests per 5 minutes per key. The Actor paces requests with a token bucket, backs off on HTTP 429 and rotates through a key pool when one is configured, so a long run finishes instead of failing.
- **Built for agents.** Array-based input and flat, typed rows work well through the Apify MCP server for KYB and due-diligence assistants.

### How much does it cost to scrape Companies House?

You pay per result (pay per event). There is no monthly rental and no charge for empty or failed lookups, duplicates or companies that are not found. Your Apify plan sets the unit price:

| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| `company` (profile or search row) | $0.0020 | $0.0018 | $0.0016 | $0.0014 |
| `officer-psc` (officer, PSC, filing or charge row) | $0.0010 | $0.0009 | $0.0008 | $0.0007 |
| `new-incorporation` | $0.0005 | $0.00045 | $0.0004 | $0.00035 |
| `change-event` | $0.0050 | $0.0045 | $0.0040 | $0.0035 |

Examples on the Free tier prices: 1,000 company profiles = $2.00. 1,000 officer rows = $1.00. A feed of 1,000 new incorporations = $0.50. 100 change events = $0.50. Apify platform usage (compute) is billed separately by Apify and is small for this HTTP-only Actor because the API is fast; the main cost driver is the API rate limit, roughly 1.8 requests per second per key.

Users on the free Apify plan get up to 25 results per run. The run then stops with the message "Free tier limit reached (25 results). Upgrade to a paid Apify plan for unlimited results." and finishes normally. Set Apify's `maxTotalChargeUsd` on any run to hard-limit your spend; the Actor stops cleanly when the limit is reached.

### Input

The most important fields:

| Field | Type | Description |
|---|---|---|
| `mode` | select | `lookup`, `search`, `officers`, `psc`, `filings`, `charges`, `new-incorporations` or `monitor`. Default `lookup`. |
| `queries` | array | Company numbers (for example `00445790`, `SC123456`) or company names. Numbers are looked up directly, other text is treated as a name. In `search` mode each entry is a search phrase. |
| `include` | array | Lookup mode: also fetch `officers`, `psc`, `filings`, `charges` rows for each company. |
| `maxResults` | integer | Maximum billable rows for the whole run. Default 25. |
| `apiKey` | secret | Your own free Companies House REST API key. Optional if the shared pool is available. |
| `includeResigned` | boolean | Officers mode: include resigned officers. |
| `filingCategories` | array | Filings mode: keep only categories such as `accounts`, `confirmation-statement`, `officers`, `mortgage`, `insolvency`. |
| `incorporatedFrom`, `incorporatedTo`, `daysBack` | text / integer | New-incorporations date range. If `incorporatedFrom` is empty the range is the last `daysBack` days. |
| `sicCodes` | array | New-incorporations: SIC codes such as `62020`. |
| `location` | text | New-incorporations: location text passed to the API, such as `London`. |
| `postcodePrefixes` | array | New-incorporations: keep only companies whose postcode starts with one of these prefixes, such as `EC1`, `M1`. |
| `includeOfficers` | boolean | New-incorporations: add `officerNames` to each row and return officer rows too (one extra API request per company). |
| `watchlist`, `watch`, `stateStoreName`, `resetBaseline` | mixed | Monitor mode: company numbers to watch, what to compare (`profile`, `filings`, `charges`, `officers`, `psc`), the named key-value store that keeps the previous snapshot, and a switch to start over. |

Example 1: look up companies and their active officers.

```json
{
  "mode": "lookup",
  "queries": ["00445790", "Marks and Spencer Group"],
  "include": ["officers"],
  "maxResults": 100
}
```

Example 2: UK new companies list for yesterday and today, IT consultancies in London postcodes.

```json
{
  "mode": "new-incorporations",
  "daysBack": 1,
  "sicCodes": ["62020", "62012"],
  "postcodePrefixes": ["EC", "WC", "E1"],
  "includeOfficers": true,
  "maxResults": 500
}
```

Example 3: monitor a watchlist (first run stores a baseline, later runs report changes).

```json
{
  "mode": "monitor",
  "watchlist": ["00445790", "00214436"],
  "watch": ["profile", "filings"],
  "stateStoreName": "my-watchlist"
}
```

### Output example

Illustrative example of a `lookup` row (values are examples, not a live run):

```json
{
  "recordType": "company",
  "companyNumber": "00445790",
  "companyName": "EXAMPLE TRADING PLC",
  "status": "active",
  "type": "plc",
  "dateOfCreation": "1947-11-27",
  "sicCodes": ["47110"],
  "registeredAddress": "Example House, 1 High Street, London, EC1A 1BB",
  "postalCode": "EC1A 1BB",
  "accountsLastMadeUpTo": "2026-02-28",
  "accountsNextDue": "2027-11-30",
  "accountsOverdue": false,
  "confirmationStatementNextDue": "2027-06-20",
  "hasCharges": true,
  "hasInsolvencyHistory": false,
  "url": "https://find-and-update.company-information.service.gov.uk/company/00445790",
  "source": "Companies House (Open Government Licence v3.0)"
}
```

Illustrative `change` row from the monitor:

```json
{
  "recordType": "change",
  "companyNumber": "00445790",
  "companyName": "EXAMPLE TRADING PLC",
  "changeType": "officer-resigned",
  "summary": "officer SMITH, Jane is resigned",
  "previous": "active",
  "current": "resigned",
  "detectedAt": "2026-10-19T06:00:00.000Z"
}
```

Officer and PSC rows contain only month and year of birth, as published by the register. A run summary (counts, charged events, estimated maximum cost, warnings) is saved to the `OUTPUT` record of the default key-value store.

### How to use Companies House UK Scraper & Monitor (tutorial)

1. **Get a free API key (recommended).** Register at the Companies House developer hub, create an application and add a REST API key. Paste it into the `apiKey` field. Your key is stored as a secret and never printed to the log. If the shared key pool is available you can skip this for small runs.
2. **Choose a mode.** For a company check pick `lookup`; for a lead list pick `new-incorporations`; for alerts pick `monitor`.
3. **Fill the list.** Add company numbers or names to `queries`, or set the date range, SIC codes and postcode prefixes for the feed.
4. **Set Max results and run.** Start with the default 25 to check the output, then raise `maxResults`. Open the Overview table in the Output tab.
5. **Export or schedule.** Download JSON, CSV or Excel, or add an Apify schedule: a daily `new-incorporations` run with `daysBack` 1 gives you a fresh UK new companies list every morning, and a daily `monitor` run reports watchlist changes.

How the monitor works: the first run stores a snapshot of every company in a named key-value store and reports nothing. Each later run compares against that snapshot, reports differences as `change` rows (one `change-event` charge each) and updates the snapshot. Use a different `stateStoreName` for each watchlist. Each watched item costs one API request per company per run, so the default (`profile` and `filings`) is the cheapest useful setting. When the same real-world change shows up twice (for example a new accounts filing and the accounts date in the profile), it is reported and billed once.

### Run via API

Synchronous run that returns the dataset items:

```bash
curl -X POST "https://api.apify.com/v2/acts/tiger19935~companies-house-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"lookup","queries":["00445790"],"apiKey":"YOUR_COMPANIES_HOUSE_KEY","maxResults":10}'
```

Node.js:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('tiger19935/companies-house-scraper').call({
  mode: 'new-incorporations',
  daysBack: 1,
  sicCodes: ['62020'],
  maxResults: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'new companies');
```

MCP: add this Actor to the Apify MCP server (`https://mcp.apify.com`) and an AI agent can call it with the same JSON input, for example for KYB checks ("who are the active directors and PSCs of company 00445790?").

### Integrations

- **n8n and Make**: use the Apify node or module, run the Actor on a schedule and route `recordType: "change"` rows to Slack, email or a CRM.
- **Zapier**: trigger a Zap when a run finishes and send new incorporations to your sales tools.
- **Google Sheets**: use the Apify integration or the dataset CSV URL for a self-updating new companies sheet.
- **Webhooks**: Apify webhooks call your URL when a run succeeds, so a monitor run can notify your system.
- **MCP**: expose the Actor to AI agents through the Apify MCP server.

### Legal / ethical use

Companies House data is a public register published under the Open Government Licence v3.0 and the Companies House API terms. This Actor reads only public API data with your key (or the shared key pool) and uses no logins or cookies. Officer and PSC records contain personal data of individuals, so GDPR and UK GDPR apply to how you store and use them. If you use names for marketing, PECR and the Data Protection Act also apply: document your lawful basis (for example legitimate interest), honour objections and opt-outs, and do not use the data for unlawful purposes. You are responsible for your own compliance and for following the Companies House API terms of use. This Actor is not affiliated with or endorsed by Companies House.

### FAQ and support

**Do I need a Companies House API key?**
Using your own free REST API key is recommended: it gives you your own 600 requests per 5 minutes. If the Actor owner has configured a shared key pool, small runs work without a key; otherwise the Actor stops with a message asking you to paste your own key.

**How do I get a list of newly incorporated UK companies?**
Use the `new-incorporations` mode, set `daysBack` or a date range, add SIC codes, a location and optional postcode prefixes. Each row includes the registered address; switch on `includeOfficers` to add officer names. Schedule it daily for a fresh UK new companies list.

**Is the data legal to use?**
The register is public and published under the Open Government Licence. Using officer data for marketing is subject to GDPR and PECR: document your lawful basis. See the legal section above.

**How fresh is the data?**
The API serves the live register, so data is as current as Companies House makes it.

**How do I export Companies House data to CSV or Excel?**
Open the dataset after the run and choose CSV, Excel or JSON, or use the dataset API URL with `format=csv`.

**Why did my run stop at 25 results?**
You are on the free Apify plan, which is capped at 25 results per run. Upgrade to a paid plan for unlimited results. A run can also stop at your `maxResults` value or at your maximum total charge.

**Does the monitor report anything on the first run?**
No. The first run stores a baseline snapshot. Changes are reported from the second run onwards.

**Does it cover Northern Ireland, Scotland and overseas companies?**
It covers whatever the Companies House API returns, which includes England and Wales, Scotland and Northern Ireland registered companies (numbers such as SC123456 or NI123456). Coverage of other registers is not offered.

**Something is wrong or a field is missing. Where do I report it?**
Open an issue in the Issues tab of this Actor with the run link. Replies come within 12 hours.

### More tools by the same author

- [Prozorro & TED Tenders Scraper](https://apify.com/tiger19935/prozorro-ted-tenders-scraper) - public tenders from Ukraine and the EU
- [Billing & Payment Stack Detector](https://apify.com/tiger19935/billing-stack-detector) - which payment gateway a website uses
- [Website Technology Detector](https://apify.com/tiger19935/website-technology-detector) - tech stack of any site
- [Decision-Maker Contacts](https://apify.com/tiger19935/decision-maker-contacts) - people and roles at a company

### Related searches

companies house scraper, companies house api, uk company search, uk new companies list, companies house officers, psc register, companies house monitor, uk company data, kyb uk, new incorporations uk, companies house to csv, uk company lead list.

# Changelog

This Actor's version history is a separate document: https://apify.com/tiger19935/companies-house-scraper/changelog.md

# Actor input Schema

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

What to do. lookup = company profile by number or name; search = name search; officers / psc / filings / charges = detail rows for each company; new-incorporations = feed of newly registered companies; monitor = detect changes on a watchlist since the last run.

## `queries` (type: `array`):

Used by lookup, search, officers, psc, filings and charges. Company numbers (for example 00445790 or SC123456) are looked up directly; anything else is treated as a company name. In search mode every entry is a search phrase.

## `include` (type: `array`):

Lookup mode only: extra detail rows to fetch for every company. Each row is billed as an officer-psc event.

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

Maximum number of billable result rows for the whole run. The run stops when this is reached. Free Apify plan users are capped at 25.

## `apiKey` (type: `string`):

Your free API key from developer.company-information.service.gov.uk (REST key). Leave empty to use the shared key pool if the Actor owner configured one. Your own key gives you your own 600 requests per 5 minutes.

## `includeResigned` (type: `boolean`):

Officers mode only: also return officers who have resigned. Off = active officers only.

## `filingCategories` (type: `array`):

Filings mode only: keep only these categories, for example accounts, confirmation-statement, officers, mortgage, insolvency, address, incorporation. Empty = all.

## `incorporatedFrom` (type: `string`):

New-incorporations mode: earliest incorporation date. Leave empty to use Days back instead.

## `incorporatedTo` (type: `string`):

New-incorporations mode: latest incorporation date. Empty = today.

## `daysBack` (type: `integer`):

New-incorporations mode: used when Incorporated from is empty. 1 = yesterday and today.

## `sicCodes` (type: `array`):

New-incorporations mode: only companies with at least one of these SIC codes, for example 62020 (IT consultancy) or 56101 (restaurants). Empty = any.

## `location` (type: `string`):

New-incorporations mode: free-text registered-office location filter passed to the API, for example London or Manchester.

## `postcodePrefixes` (type: `array`):

New-incorporations mode: keep only companies whose registered postcode starts with one of these prefixes (for example EC1, M1, SW). Applied after the API search.

## `includeOfficers` (type: `boolean`):

New-incorporations mode: fetch officers for every new company, add officerNames to the row and return one officer row each (billed as officer-psc). Slower: one extra API request per company.

## `watchlist` (type: `array`):

Monitor mode: companies to watch. The first run stores a baseline and reports nothing; later runs report changes.

## `watch` (type: `array`):

Monitor mode: which data to compare. profile = status, name, address, accounts and confirmation-statement dates; filings = new filings; charges; officers; psc. Every watched item costs one API request per company per run.

## `stateStoreName` (type: `string`):

Monitor mode: named key-value store that keeps the previous snapshot between runs. Use a different name per watchlist.

## `resetBaseline` (type: `boolean`):

Monitor mode: discard the stored snapshot and start again (no change events are reported on that run).

## Actor input object example

```json
{
  "mode": "lookup",
  "queries": [
    "00445790",
    "00214436"
  ],
  "include": [],
  "maxResults": 25,
  "includeResigned": false,
  "filingCategories": [],
  "daysBack": 1,
  "sicCodes": [],
  "postcodePrefixes": [],
  "includeOfficers": false,
  "watchlist": [],
  "watch": [
    "profile",
    "filings"
  ],
  "stateStoreName": "companies-house-watchlist",
  "resetBaseline": false
}
```

# Actor output Schema

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

All result rows (companies, officers, PSC, filings, charges, new incorporations, change events).

## `overview` (type: `string`):

Overview view of the results in the Apify Console.

## `summary` (type: `string`):

Counts, charged events, estimated cost and warnings.

# 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 = {
    "mode": "lookup",
    "queries": [
        "00445790",
        "00214436"
    ],
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("tiger19935/companies-house-scraper").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 = {
    "mode": "lookup",
    "queries": [
        "00445790",
        "00214436",
    ],
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("tiger19935/companies-house-scraper").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 '{
  "mode": "lookup",
  "queries": [
    "00445790",
    "00214436"
  ],
  "maxResults": 25
}' |
apify call tiger19935/companies-house-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tiger19935/companies-house-scraper"
        }
    }
}
```

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/c6gIuTciMbJbf6cQz/builds/GFpPjQxtCzg0dqbQB/openapi.json
