# UK New Companies & Officers Feed (unofficial Companies House) (`plusonets/uk-companies-house-feed`) Actor

Daily feed of newly incorporated UK companies from the official Companies House API, with SIC, type and postcode filters and optional officers. Unofficial; not affiliated with Companies House.

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

## Pricing

from $3.00 / 1,000 company results

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 New Companies & Officers Feed (unofficial Companies House)

Daily list of companies newly incorporated at Companies House, with optional officers. This Actor calls the official Companies House REST API. It can also read the free monthly basic-data snapshot when you need a historical month without spending API calls.

This Actor is unofficial. It is not affiliated with, endorsed by, or connected to Companies House or the UK government.

### Set a key before the first run

Companies House requires a free API key on every REST call. The default input does **not** contain a key, so the Apify daily test and any run that leaves `apiKey` blank depend on an environment variable:

1. Create a key at <https://developer.company-information.service.gov.uk/>. It is free and limited to 600 requests in each 5 minute period.
2. As the Actor owner, open the Actor in Apify Console → **Settings** → **Environment variables**.
3. Add `COMPANIES_HOUSE_API_KEY` with that key and mark the variable secret.

A user can still pass their own key in the `apiKey` input. That value overrides the environment variable for that run. If neither is set, the run stops with an error that names `COMPANIES_HOUSE_API_KEY`. It does not guess, scrape the website, or call the API anonymously.

The default input is yesterday in the Europe/London calendar, at most 20 companies, officers off, and "only new since last run" off. That is one search request and returns a non-empty dataset whenever yesterday (or the previous week, if yesterday is empty) has incorporations.

### What it returns

Each dataset row is one company:

- company number, name, status, type, incorporation date, SIC codes
- registered office postcode, locality, region, country, and the address object
- a link to the public register page
- officers, only when you turn them on

Officers stay on the company row. The **Officers** view unwinds them. Date of birth is month and year only, which is all the public register publishes.

### Input

| Field | Default | What it does |
| --- | --- | --- |
| `apiKey` | empty | Secret. Your Companies House key. Blank uses `COMPANIES_HOUSE_API_KEY`. |
| `incorporatedFrom` / `incorporatedTo` | yesterday | `YYYY-MM-DD`, or a relative date such as `1 day` or `2 weeks`. |
| `fallbackLookbackDays` | 7 | If both dates are empty and yesterday has no companies, search this many days ending yesterday. |
| `maxCompanies` | 20 | Stop after this many matching companies. |
| `sicCodes` | empty | Any of these SIC 2007 codes, for example `62012`. |
| `companyTypes` | empty | API codes such as `ltd`, `plc`, `llp`. |
| `companyStatus` | empty | For example `active`. Empty means every status. |
| `postcode` | empty | Registered-office prefix, such as `SW1A` or `EH`. |
| `region` | empty | Matches locality, county, country, or address lines. Example: `Manchester`. |
| `includeOfficers` | false | One extra API call per company. |
| `activeOfficersOnly` | true | Drop officers who have a resignation date. |
| `onlyNewSinceLastRun` | false | Skip company numbers already stored for `stateKey`. |
| `stateKey` | `default` | Separate seen-lists for separate schedules. |
| `source` | `api` | `bulk` reads the free monthly snapshot instead. |
| `bulkSnapshotDate` | latest | File date such as `2026-10-01`. |

Leave **Only new since last run** off for the daily test. The seen-list lives in the default key-value store and would make a second run the same day empty.

### Output example

Illustration of the shape, not a live register extract:

```json
{
  "companyNumber": "12345678",
  "companyName": "NORTH WHARF DIGITAL LTD",
  "companyStatus": "active",
  "companyType": "ltd",
  "dateOfCreation": "2026-10-22",
  "sicCodes": ["62012"],
  "postalCode": "SW1A 1AA",
  "locality": "London",
  "region": "Greater London",
  "country": "United Kingdom",
  "registeredOfficeAddress": {
    "addressLine1": "1 Wharf Lane",
    "locality": "London",
    "postalCode": "SW1A 1AA",
    "country": "United Kingdom"
  },
  "companyProfileUrl": "https://find-and-update.company-information.service.gov.uk/company/12345678",
  "source": "api",
  "retrievedAt": "2026-10-23T06:15:00+00:00",
  "officerCount": 1,
  "officers": [
    {
      "name": "DOE, Jane",
      "officerRole": "director",
      "appointedOn": "2026-10-22",
      "nationality": "British",
      "occupation": "Director",
      "countryOfResidence": "England",
      "dateOfBirth": "1985-04",
      "officerLocality": "London",
      "officerPostalCode": "E1 6AN"
    }
  ]
}
```

`officerCount` and `officers` are omitted when officers are not requested.

### Pricing

Pay per event. There is a $0.005 start event and no dataset-item event. When you publish the Actor, add only these events and do not put a price on dataset items, or a company would be billed twice.

| Event | Suggested price | Charged when |
| --- | --- | --- |
| `apify-actor-start` | $0.005 | Once per run, by the platform (once per GB of memory, so once at the 512 MB default). The Actor does not call `Actor.charge` for it. |
| `company-result` | $0.003 | A company is written to the dataset |
| `officer-result` | $0.0015 | An officer is included on a saved company |

A default run of 20 companies and no officers is about $0.065 ($0.005 start + 20 × $0.003). Twenty companies with two officers each is about $0.125. The run stops when `Actor.charge` reports that the user's max charge is used up, and it does not fetch further companies after that. Set the minimum run budget to at least $0.01 so one company can be returned.

Platform compute is not billed to you; the events above are the whole price.

### Only new since last run

Turn this on for a daily schedule. The Actor stores company numbers in its default key-value store under a key derived from `stateKey`. The next run of the same window skips them. Use a different `stateKey` for each saved search so a London filter and a Scotland filter do not hide each other's companies.

The record keeps the newest 30,000 numbers once it passes 40,000. That is about two weeks of every UK incorporation, and much longer when you filter. The Actor uses only its own default dataset and key-value store, which is within Apify limited permissions. Leave the Actor on **Limited permissions** so it stays visible to MCP clients.

### Rate limit and the 10,000-row cap

Companies House allows 600 requests in any 5 minute period per key, and says applications that try to get around that can be blocked. This Actor stays at or under 540 requests per 300 seconds, with at least 0.55 seconds between calls. HTTP 429 and 5xx responses are retried with backoff. The key is sent as HTTP Basic username with an empty password, which is the documented method, and it is never written into the dataset.

Advanced search will not return more than 10,000 rows for one date range (`start_index` + `size` must stay at or under 10,000). If you ask for more than 10,000 companies and the range is longer than a day, the Actor splits the range by date and continues. A single day with more than 10,000 hits is truncated and the run says so. A normal day is a few thousand incorporations, so a one-day window fits.

Schedule a daily run after 07:00 Europe/London. The search index can lag the moment of incorporation.

### Free bulk snapshot

`source: "bulk"` streams `BasicCompanyDataAsOneFile-YYYY-MM-DD.zip` from <https://download.companieshouse.gov.uk/en_output.html>. Companies House compiles that file to the end of the previous month and publishes it within a few working days. The file dated 1 October 2026 holds incorporations through 30 September 2026. It is about 500 MB. It is the wrong tool for yesterday's companies; use the API for that. The Actor refuses a bulk run whose whole date window is after the snapshot's coverage.

Officers are not in the snapshot. Asking for them on a bulk run still calls the REST API and still needs a key.

Give a bulk run 1024 MB of memory and a long timeout. The reader scans the CSV until it has enough matches, which can mean reading most of the file when the date you want is uncommon.

### Attribution and licence

Company and officer data is Crown copyright, published by Companies House. Reuse is allowed with attribution. See [Companies House public task, copyright and Crown copyright](https://www.gov.uk/government/publications/companies-house-accreditation-to-information-fair-traders-scheme/public-task-copyright-and-crown-copyright).

Contains public sector information licensed under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).

API behaviour and the rate limit are described in the [Companies House developer guidelines](https://developer.company-information.service.gov.uk/developer-guidelines/) and the [rate limiting guide](https://developer-specs.company-information.service.gov.uk/guides/rateLimiting).

### Limits

- No key is shipped with this Actor. The owner must set `COMPANIES_HOUSE_API_KEY`, or every default run fails.
- The 600 / 5 minute cap is per key. A key shared with another application exhausts the budget sooner. A 429 pauses and retries.
- Results are public register data, not a certificate of incorporation.
- Officer records can include a correspondence address and a month and year of birth. Those fields are already public. This Actor does not add anything Companies House does not return.
- Postcode and region filters are applied again locally because the API `location` parameter is a free-text address search.
- Bulk categories are mapped onto API company-type codes where the names match. Unusual categories keep a slug of the original text.

### Run locally

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
export COMPANIES_HOUSE_API_KEY=your-key
python3 -m uk_companies_house_feed
```

On your own machine the SDK reads `INPUT.json` from the working directory when the key-value store has no input. An empty object uses the defaults above.

```bash
pytest
```

Tests mock Companies House HTTP. They do not need a key. A live call of the default input needs `COMPANIES_HOUSE_API_KEY`.

# Actor input Schema

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

Your free Companies House REST API key (https://developer.company-information.service.gov.uk/). Leave this empty to use the COMPANIES_HOUSE_API_KEY environment variable. The Actor owner sets that variable under Actor → Settings → Environment variables and should mark it secret. The default input does not contain a key.

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

First incorporation date to include. Use YYYY-MM-DD or a relative date such as 1 day or 2 weeks, in the Europe/London calendar. Leave empty to use yesterday.

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

Last incorporation date to include. Same formats as Incorporated from. Leave empty to use yesterday.

## `fallbackLookbackDays` (type: `integer`):

Used only when both dates are empty and yesterday has no incorporations. The run then searches this many days ending yesterday, so a quiet day still returns recent companies. Set 0 or 1 to disable. Ignored when you set a date.

## `maxCompanies` (type: `integer`):

Stop after this many matching companies. The default is 20 so the daily test finishes in one API call. Raise it for a full day (a typical day is a few thousand incorporations).

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

UK SIC 2007 codes. A company matches if it has any of these codes. Example: 62012 for business and domestic software development. Leave empty for every SIC code.

## `companyTypes` (type: `array`):

Companies House company_type codes. Common values: ltd, plc, llp, private-limited-guarant-nsc, charitable-incorporated-organisation, registered-overseas-entity, uk-establishment, limited-partnership. Leave empty for every type.

## `companyStatus` (type: `array`):

Optional status filter. Values include active, open, dissolved, liquidation, administration, receivership, voluntary-arrangement, insolvency-proceedings. Leave empty for every status. New incorporations are usually active.

## `postcode` (type: `string`):

Registered-office postcode prefix, such as SW1A, EH, or M1 1AE. Spaces and case are ignored. Applied on top of the Companies House location search.

## `region` (type: `string`):

Case-insensitive match against the registered office locality, county/region, country, or address lines. Examples: Manchester, Greater London, Scotland, Wales.

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

Optional text passed straight to the Companies House location filter. When this is empty, the postcode is sent, or the region if there is no postcode. Local postcode and region checks still apply.

## `nameIncludes` (type: `string`):

Only companies whose name contains this text. Sent to the API as company_name_includes.

## `nameExcludes` (type: `string`):

Drop companies whose name contains this text. Sent to the API as company_name_excludes.

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

Also read /company/{number}/officers for each saved company. Each officer is its own paid event. Leave this off for the fast default run. One request per company, paced under the 600 requests / 5 minutes cap.

## `activeOfficersOnly` (type: `boolean`):

When officers are included, drop anyone with a resignation date.

## `maxOfficersPerCompany` (type: `integer`):

Cap officer rows stored on each company. New companies usually have one to three.

## `onlyNewSinceLastRun` (type: `boolean`):

Skip company numbers already saved for this state key. The list is kept in the default key-value store (limited permissions). Leave this off for the daily test, or the second test run of the same day can be empty. Turn it on for a scheduled monitor, and use a different state key per saved search.

## `stateKey` (type: `string`):

Name of the seen-company list used by Only new since last run. Example: software-london. The stored record keeps the newest 30,000 company numbers after it passes 40,000.

## `source` (type: `string`):

api calls the live REST search (needs a key). bulk streams the free monthly Basic Company Data snapshot from download.companieshouse.gov.uk. That file is compiled to the end of the previous month and is about 500 MB, so it cannot serve yesterday's incorporations. Officers always come from the API.

## `bulkSnapshotDate` (type: `string`):

YYYY-MM-DD from the snapshot file name, for example 2026-10-01. Leave empty to use the latest file linked from the Companies House download page. The file dated the 1st of a month holds incorporations through the end of the previous month.

## Actor input object example

```json
{
  "fallbackLookbackDays": 7,
  "maxCompanies": 20,
  "includeOfficers": false,
  "activeOfficersOnly": true,
  "maxOfficersPerCompany": 50,
  "onlyNewSinceLastRun": false,
  "stateKey": "default",
  "source": "api"
}
```

# Actor output Schema

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

One row per newly incorporated UK company, with officers when requested.

# 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 = {
    "fallbackLookbackDays": 7,
    "maxCompanies": 20,
    "includeOfficers": false,
    "activeOfficersOnly": true,
    "maxOfficersPerCompany": 50,
    "onlyNewSinceLastRun": false,
    "stateKey": "default",
    "source": "api"
};

// Run the Actor and wait for it to finish
const run = await client.actor("plusonets/uk-companies-house-feed").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 = {
    "fallbackLookbackDays": 7,
    "maxCompanies": 20,
    "includeOfficers": False,
    "activeOfficersOnly": True,
    "maxOfficersPerCompany": 50,
    "onlyNewSinceLastRun": False,
    "stateKey": "default",
    "source": "api",
}

# Run the Actor and wait for it to finish
run = client.actor("plusonets/uk-companies-house-feed").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 '{
  "fallbackLookbackDays": 7,
  "maxCompanies": 20,
  "includeOfficers": false,
  "activeOfficersOnly": true,
  "maxOfficersPerCompany": 50,
  "onlyNewSinceLastRun": false,
  "stateKey": "default",
  "source": "api"
}' |
apify call plusonets/uk-companies-house-feed --silent --output-dataset

```

## MCP server setup

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

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/tZ9bgd4RMhafeVGui/builds/PgPgufiRT4ifDF7Ve/openapi.json
