# Companies House Scraper & API — UK Companies, Officers, Filings (`s-r/companies-house-uk`) Actor

Look up UK companies by name, company number or filters and get company profiles, directors and other officers, persons with significant control and filing history as flat rows, ready for KYB checks, B2B lead lists and credit research.

- **URL**: https://apify.com/s-r/companies-house-uk.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Business, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 company 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

## Companies House API & Scraper for UK Company Data

Use this Companies House API alternative to collect public UK company profiles, directors and other officers, persons with significant control (PSCs) and filing history, without registering for an API key. Search by company name, provide company numbers, or use registration filters to build a structured dataset for KYB checks, B2B lead lists, credit research and company enrichment.

Each company, appointment and filing is a separate record. The `registry_id` field is the Companies House company number shared by all records for that company. This makes the output suitable for spreadsheets, CRM imports and database joins without unpacking nested lists of people or documents.

### What the Companies House scraper collects

Company records include the registered name, company number, current register status, legal form, incorporation date, registered office address and UK SIC codes. Where available, they also include previous names, dissolution dates, accounts dates and confirmation statement dates. Status is provided as a consistent value such as `active`, `dissolved` or `in_liquidation`, with the original register text when disclosed. Royal Charter companies, charitable incorporated organisations and ICVCs may omit the status: these profiles remain available with `status: unknown` and no `status_raw`. Administration and receiver action normalize to `inactive`; open establishments, registered overseas entities and active companies with a strike-off proposal normalize to `active`.

Officer records include the name, role, appointment date, resignation date and company context. Nationality, month and year of birth, correspondence address, residence and identity verification information are included when the register discloses them. An appointment recorded as “Appointed before” retains that distinction in `appointed_before`.

Filing records include the filing type code, date and description. Where a document is available, `document_url` points to its public Companies House download route. Accounts filings can also include the period end date. The actor returns document links and metadata; it does not download or interpret the contents of financial statements.

### How to get Companies House data in three steps

1. Enter one or more company numbers, company names, or advanced search filters such as SIC codes and incorporation dates.
2. Choose the sections you need: officers (directors and secretaries), PSCs, filing history and the GLEIF LEI match.
3. Start the run and export the dataset as JSON, CSV or Excel, or read it from the Apify API in your own pipeline.

### Input

Provide at least one company number, a name search, or an advanced search filter. You can combine company numbers and searches in the same run. Duplicate company numbers and companies appearing in more than one search are collected once.

| Field | Default | What it does |
|---|---|---|
| `company_numbers` | – | Companies House numbers to look up directly |
| `search_queries` | – | Company names to search for |
| `sic_codes` | – | Advanced search: UK SIC codes |
| `location` | – | Advanced search: registered office address text |
| `company_status` | – | Advanced search: register status, for example `active`, `dissolved` or `liquidation` |
| `incorporated_from` / `incorporated_to` | – | Advanced search: incorporation date range (`YYYY-MM-DD`) |
| `max_results` | 20 | Matches per name query or advanced filter set, up to 1,000 |
| `include_officers` | false | Add officer rows (directors, secretaries and other appointments) |
| `officers_status` | all | `all`, or `active` for current appointments only |
| `max_officers_per_company` | 35 | Officer rows per company |
| `include_filings` | false | Add filing history rows |
| `max_filings_per_company` | 25 | Filing rows per company |
| `include_psc` | false | Add persons with significant control |
| `include_lei` | true | Match each company to its GLEIF LEI |

For a direct lookup, the following input retrieves Tesco PLC with officers, filings and any available PSC information:

```json
{
  "company_numbers": ["00445790"],
  "include_officers": true,
  "include_filings": true,
  "include_psc": true
}
```

For a company name search, use:

```json
{
  "search_queries": ["tesco"],
  "max_results": 40,
  "include_lei": false
}
```

Numeric company numbers are padded to eight digits, so `445790` becomes `00445790`. Letter prefixes are preserved: Scottish company numbers and LLP numbers remain valid Companies House identifiers. All records use `GB` as their register jurisdiction.

`max_results` defaults to 20 and applies separately to each name query or advanced filter set. It does not truncate an explicit list of company numbers. You can request up to 1,000 matches per query. Searches follow the public register’s result order and can match previous company names as well as current names.

Advanced filters include `sic_codes`, `location`, `company_status`, `incorporated_from` and `incorporated_to`. Dates must use `YYYY-MM-DD` and refer to valid calendar dates. The location filter searches registered office address text. Multiple advanced filters form one additional search; they do not change the meaning of separate name queries.

Officers, filings and PSCs are optional and disabled by default. `max_officers_per_company` defaults to 35, and `max_filings_per_company` defaults to 25. Set `officers_status` to `active` when you only want current appointments. The officer limit counts the delivered appointments after that filter. Larger limits follow the available history up to the requested cap.

### Output

The dataset contains a flat list distinguished by `record_type`: `company`, `officer` or `filing`. Every row includes its company number, register jurisdiction, source identifier, retrieval timestamp and source URL. For each company, its profile comes first, followed by appointments, PSC records and filings.

PSCs use the `officer` record type and the role `person with significant control`. They can include a notification date and the disclosed nature of control. A company exempt from PSC disclosure produces a warning and no PSC rows. This is a valid register outcome.

Optional values that the register does not disclose are omitted. Active companies have a null `dissolution_date`, and active appointments have a null `resigned_on`. Company data does not imply that VAT numbers, websites, employee counts or officer occupations are available; those fields are outside this actor’s public register output.

The run summary reports delivered rows, units, charges, warnings and whether collection was incomplete. Units count every delivered company, officer and filing row. Large collections continue automatically across result pages. If an upstream section cannot be retrieved, the actor preserves available records and reports the missing section. A permanently unavailable or unrecognised company profile is skipped with a warning so the remaining companies can still be collected; the collection stays incomplete. Review warnings before treating a collection as complete.

#### Example output

These three rows come from a real run for Tesco PLC (`00445790`) on 4 October 2026, one of each record type. The company row is shortened to its main fields.

```json
{
  "record_type": "company",
  "registry_id": "00445790",
  "jurisdiction": "GB",
  "url": "https://find-and-update.company-information.service.gov.uk/company/00445790",
  "name": "TESCO PLC",
  "status": "active",
  "status_raw": "Active",
  "dissolution_date": null,
  "legal_form": "Public limited Company",
  "incorporation_date": "1947-11-27",
  "address_raw": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
  "address": {
    "street": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom",
    "postal_code": "AL7 1GA",
    "country": "GB"
  },
  "industry_codes": [
    {
      "scheme": "sic",
      "code": "47110",
      "description": "Retail sale in non-specialised stores with food, beverages or tobacco predominating"
    }
  ],
  "accounts": {
    "next_made_up_to": "2027-02-26",
    "next_due_by": "2027-08-26",
    "last_made_up_to": "2026-02-28"
  },
  "officers_count": 74,
  "resignations_count": 63,
  "lei": "2138002P5RNKC5W2JZ46"
}
```

```json
{
  "record_type": "officer",
  "registry_id": "00445790",
  "company_name": "TESCO PLC",
  "name": "BETHELL, Melissa",
  "role": "Director",
  "officer_status": "Active",
  "appointed_on": "2018-09-24",
  "resigned_on": null,
  "appointed_before": false,
  "nationality": "British",
  "country_of_residence": "United Kingdom",
  "birth_year": 1974,
  "birth_month": 9,
  "identity_verified": true,
  "officer_id": "aqrS_F-2zIvSaMNtl1opqDV4-w0"
}
```

```json
{
  "record_type": "filing",
  "registry_id": "00445790",
  "company_name": "TESCO PLC",
  "date": "2026-09-16",
  "filing_type": "SH03",
  "description": "Purchase of own shares. ANNOTATION Clarification hmrc confirmation received that appropriate duty has been paid on this repurchase",
  "document_url": "https://find-and-update.company-information.service.gov.uk/company/00445790/filing-history/MzU0MzY3ODg5MGFkaXF6a2N4/document?format=pdf&download=0",
  "filing_id": "MzU0MzY3ODg5MGFkaXF6a2N4",
  "pages": 4
}
```

### Use cases

- **KYB and onboarding checks.** Confirm that a UK supplier or customer exists, is active, and is run by the directors and PSCs it claims. The LEI match links the company to its global legal entity identifier.
- **B2B lead generation.** Combine SIC codes, a location and an incorporation date range to list newly formed companies in a sector, then add directors as named contacts for your CRM.
- **Credit and risk monitoring.** Track accounts and confirmation statement due dates, status changes such as liquidation, and recent filings for a portfolio of company numbers.
- **Director search and due diligence.** Collect every appointment on a company, including resigned officers, to see who has run it and since when.
- **Data enrichment.** Add register status, SIC codes and registered address to an existing list of company numbers in one run.

### Companies House API compared with this actor

The official Companies House API is free, but you register an application, manage an API key, call a separate endpoint for the profile, officers, PSCs and filing history of each company, and work within its request limits. That is a good fit if you are building and maintaining your own integration.

This actor returns the same public register information as one flat dataset per run: no key, no pagination code and no joining of separate responses. You pay per delivered row instead of building and hosting the integration yourself.

Companies House bulk data products are monthly snapshots of basic company data. They suit full-register analysis, but do not include filing history per company and need your own loading and matching. Use this actor when you need current records for a specific set of companies or a filtered search.

Other Companies House scrapers in the Apify Store often return one nested object per company. Here every officer and filing is its own row with the company number as the join key, and each record type has its own price, so you only pay for the sections you switch on.

### Pricing

Billing uses separate events for delivered company, officer and filing rows. PSC rows count as officer rows. The current event prices appear in the Apify pricing panel. A company profile is counted once even when collection needs several continuation pages. Document links are part of filing records; they do not trigger a separate document event.

There is no custom start event. An empty search or an unknown company number produces no register rows and no result charges. When some supplied numbers are invalid or missing, valid company records can still be delivered, with warnings identifying the skipped inputs.

Users without a paid Apify plan receive at most ten dataset rows per run, across all record types. Section options can therefore use part of this allowance. Only delivered rows are counted by the company, officer and filing events. Paid users can collect the requested volumes subject to the source and the actor’s run limits.

### Joining company identities

LEI lookup is enabled by default. The actor matches the Companies House number against GLEIF’s `registeredAs` field and checks for a GB legal address. Tesco PLC’s company number `00445790`, for example, matches LEI `2138002P5RNKC5W2JZ46` in the captured register response.

A missing LEI does not mean that the company is invalid. Many registered companies do not have one. If GLEIF has no matching record, `lei` is omitted. If the lookup fails, the Companies House profile is still delivered and the run includes a warning. Set `include_lei` to false if your workflow only needs register data.

### FAQ

#### Do I need a Companies House API key?

No. The actor collects the public register pages for you. You only need an Apify account; the dataset can be read from the Apify API with your Apify token.

#### Is this the official Companies House API?

No. It is an independent tool that returns publicly available Companies House information. Use the official service if you need its guarantees or want to file documents.

#### Can I search dissolved companies?

Yes. Direct company number lookups can retrieve dissolved profiles, and advanced search supports a dissolved status filter. A disclosed dissolution date is included alongside the normalized status. Available historical officers and filings can be requested for the same company.

#### Are officers and PSCs the same kind of record?

Both are separate `officer` rows for convenient identity joins, but their roles distinguish them. A director appointment has the role shown by the register. A PSC has the role `person with significant control`, with its notification date and disclosed control information when available.

#### Does the actor return full dates of birth?

No. The public register generally discloses a month and year for individual officers. The actor preserves that level of detail through `birth_month` and `birth_year`. It does not infer a day or manufacture values for corporate officers.

#### Can I download the filing PDFs later?

Yes, when a document link is disclosed. Use `document_url`, which is the Companies House document route. Downloading may redirect to a temporary document location, so retain the register URL in your dataset rather than a destination obtained during a previous download.

#### How current is the output?

Records are fetched from the public sources during the run and include `fetched_at`. The output reflects what those sources disclose at retrieval time. A company’s current profile and its historical appointments or filings describe different dates; use the individual record dates when building timelines.

# Actor input Schema

## `company_numbers` (type: `array`):

Companies House numbers. Numeric numbers are padded to eight digits; duplicates are fetched once.

## `search_queries` (type: `array`):

Company name searches, including previous names. max_results applies to each query.

## `sic_codes` (type: `array`):

Five-digit UK SIC codes for advanced search.

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

Registered office address text for advanced search.

## `company_status` (type: `string`):

Company status filter for advanced search.

## `incorporated_from` (type: `string`):

Earliest incorporation date, inclusive, in YYYY-MM-DD format.

## `incorporated_to` (type: `string`):

Latest incorporation date, inclusive, in YYYY-MM-DD format.

## `max_results` (type: `integer`):

Maximum company matches per name search or advanced filter set. Does not limit company_numbers or section rows.

## `include_officers` (type: `boolean`):

Emit separate officer rows with role, dates, nationality and birth year when disclosed.

## `officers_status` (type: `string`):

all includes historical officers; active filters the source records locally.

## `max_officers_per_company` (type: `integer`):

Maximum delivered appointment rows per company. Active filtering may require more source pages.

## `include_filings` (type: `boolean`):

Emit filing history records with stable public document links.

## `max_filings_per_company` (type: `integer`):

Maximum filing records per company, newest first.

## `include_psc` (type: `boolean`):

Emit persons with significant control as officer rows. Exempt companies produce a warning.

## `include_lei` (type: `boolean`):

Look up the LEI using the company number and GB legal address in GLEIF. No match omits lei.

## Actor input object example

```json
{
  "company_numbers": [
    "00445790"
  ],
  "max_results": 20,
  "include_officers": false,
  "officers_status": "all",
  "max_officers_per_company": 35,
  "include_filings": false,
  "max_filings_per_company": 25,
  "include_psc": false,
  "include_lei": true
}
```

# Actor output Schema

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

Company, officer and filing rows joined on registry_id.

## `output` (type: `string`):

Counts, charges and warnings for this run.

# 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 = {
    "company_numbers": [
        "00445790"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/companies-house-uk").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 = { "company_numbers": ["00445790"] }

# Run the Actor and wait for it to finish
run = client.actor("s-r/companies-house-uk").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 '{
  "company_numbers": [
    "00445790"
  ]
}' |
apify call s-r/companies-house-uk --silent --output-dataset

```

## MCP server setup

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

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/pgeH4A0rGcz3aUOSd/builds/villJgkdegDZyfahN/openapi.json
