# UK Companies House Monitor - Filings, Officers & Charges (`datadeltas/uk-companies-house-monitor`) Actor

Change feed on UK companies from the official Companies House register: new filings, director appointments and resignations, status changes, registered charges, and new incorporations by SIC code. Watch a list of company numbers, or find newly incorporated leads. Bring your own free API key.

- **URL**: https://apify.com/datadeltas/uk-companies-house-monitor.md
- **Developed by:** [Daniel Matthee](https://apify.com/datadeltas) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 change detecteds

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 Companies House Monitor — Filings, Directors, Charges & New Incorporations

A **change feed** on UK companies, straight from the official Companies House
register. Give it a list of company numbers, schedule it, and every run emits
**only what moved since the last one**: new filings, directors appointed and
resigned, status changes, registered charges. Or run it in lead-gen mode and
get every **newly incorporated** UK company matching your SIC codes.

Most Companies House actors on the store are one-shot scrapers: they hand you a
snapshot and leave the diffing to you. This one **keeps the baseline and does
the diffing**, so a scheduled run gives you events, not a re-download.

Built for:

- **KYC, onboarding & compliance** — get told the day a customer enters
  liquidation, changes control, or appoints a director you need to re-screen.
  Watch your whole book; a quiet run costs pennies.
- **Credit & risk teams** — a new registered charge means someone else has
  taken security over the assets. A satisfied charge means they let it go.
  Both land here the day they hit the register.
- **Sales & GTM intelligence** — lead-gen mode lists companies incorporated in
  the last N days filtered by SIC code. A brand-new company in your sector,
  with its registered office and postcode, before anyone has sold to it.
- **Supplier & counterparty monitoring** — strike-off notices (GAZ1), overdue
  accounts and status changes across every supplier you depend on.
- **Journalists & researchers** — watch a set of companies and get a clean,
  timestamped event log instead of refreshing the register by hand.

### You bring your own API key (free, about 5 minutes)

Companies House publishes this data through a free official API, and this actor
runs on **your own key** — so the quota and the 600-requests-per-5-minutes rate
limit are yours alone, not shared with every other buyer.

1. Go to **developer.company-information.service.gov.uk** and sign in (creating
   an account is free).
2. Click **Create an application** — choose the **Live** environment.
3. In the application, click **Create new key** and choose key type **REST**
   (*not* "Streaming").
4. Leave the IP restriction **empty** — the actor runs on Apify's servers, so a
   restricted key will be rejected.
5. Paste the key into the actor's **API key** input. It is stored encrypted
   (`isSecret`), and never appears in your dataset or logs.

That is the whole setup. There is no charge from Companies House.

### How the diffing works

- **Run 1 seeds a baseline** for each company and emits **nothing**. That is
  correct and deliberate: without it, adding Tesco to your watch list would
  dump 8,371 historical filings into your dataset.
- **Every later run emits only the differences.** A filing is identified by the
  register's own permanent transaction id, an officer by their appointment
  link, a charge by its charge link — so nothing is ever reported twice.
- **A company added later seeds on its own first run**, and one removed from
  the list is forgotten (re-adding it re-seeds rather than replaying history).
- **`maxItems` is shared fairly** across every watched company, so one busy plc
  cannot crowd out the other 699. Anything over the cap is *not* marked as seen
  and arrives on the next run — you are never billed twice, and never lose a
  change.

### Example output

```json
{
  "companyNumber": "00102498",
  "companyName": "BP P.L.C.",
  "eventType": "filing",
  "summary": "Secretary resignation filed",
  "filingType": "TM02",
  "effectiveDate": "2026-08-18",
  "officersAffected": [],
  "status": "active",
  "url": "https://find-and-update.company-information.service.gov.uk/company/00102498",
  "detectedAt": "2026-09-01T01:51:29Z",
  "details": {
    "transactionId": "MzUzOTMzMzcwNmFkaXF6a2N4",
    "category": "officers",
    "description": "termination-secretary-company-with-name-termination-date",
    "filedOn": "2026-08-18"
  }
}
```

And a lead-gen row:

```json
{
  "companyNumber": "SC900284",
  "companyName": "CONTENT CREATOR COACH AI LTD",
  "eventType": "incorporation",
  "summary": "New company incorporated in Glasgow (SIC 62012)",
  "filingType": null,
  "effectiveDate": "2026-08-25",
  "officersAffected": [],
  "status": "active",
  "url": "https://find-and-update.company-information.service.gov.uk/company/SC900284",
  "detectedAt": "2026-09-01T01:51:45Z",
  "details": {
    "companyType": "ltd",
    "sicCodes": ["62012"],
    "postcode": "G2 1BP",
    "locality": "Glasgow"
  }
}
```

#### Event types

| `eventType` | Fires when |
|---|---|
| `filing` | Any new document on the filing history — accounts, confirmation statements, capital changes, strike-off notices. `filingType` carries the form code. |
| `officer-appointed` | A director or secretary is newly appointed. |
| `officer-resigned` | An officer's appointment is terminated. |
| `status-change` | Company status moves — e.g. active → liquidation, dissolved, administration. |
| `charge` | A charge is newly registered, or an existing one changes status (outstanding → satisfied). |
| `incorporation` | Lead-gen mode: a company matching your SIC filter was newly incorporated. |

### Input options

| Input | Type | Default | What it does |
|---|---|---|---|
| `apiKey` | string (secret) | — | **Required.** Your free Companies House REST API key (see above). |
| `companyNumbers` | array | — | Watch-list. `00445790`, `SC900284`, `OC301540`. All-digit numbers are zero-padded for you, so `445790` also works. |
| `events` | multi-select | filings, officers, status, charges | Which changes to report. Fewer events = fewer API requests per company = faster runs. |
| `incorporationFilter` | object | — | Lead-gen mode: `{"sicCodes": ["62012"], "incorporatedSinceDays": 7}`. Requires `incorporations` in `events`. |
| `maxItems` | integer | 500 | Cap on changes emitted per run. The rest carry over to the next run. |

Both modes can run together in one run.

### Update frequency & run time

Companies House updates continuously through the working day, so **hourly or
daily** are both sensible schedules. Run time is governed by the register's
rate limit (600 requests per 5 minutes), which the actor paces itself against:
roughly **4 requests per company per run** with all events selected, so ~100
companies takes well under a minute and a 700-company watch list takes about
20 minutes. Select fewer `events` to cut the request count per company.

A run where nothing changed emits zero rows and costs only the start fee plus
the per-company check — that is the normal, healthy result on a quiet day.

### Pricing

| Event | Price (USD) | Charged |
|---|---|---|
| Actor start | $0.005 | Once per run |
| Change detected | $0.01 | Once per change emitted to the dataset |
| Company checked | $0.0003 | Once per watched company compared to its baseline |

Watching 100 companies daily with a handful of changes a day costs a few cents
per run. You are only charged for changes actually pushed to your dataset.

### Notes and limits

- Officers are read from the register's public officer list. **Dates of birth
  are deliberately not collected** — only the month/year the register itself
  publishes is available, and this actor does not put it in your dataset.
- The register's `has_charges` profile flag is unreliable (some companies
  report `false` while holding 136 charges), so the actor checks the charges
  endpoint itself rather than trusting the flag.
- A company number that is not on the register is logged and skipped — one bad
  number never kills a run.
- A rejected API key stops the run immediately with an instruction that names
  the fix, rather than silently returning nothing.
- Data is Crown copyright, published by Companies House under the Open
  Government Licence.

### Maintenance

Schema checked weekly against the live register. Field names within a major
version are additive-only: new fields may appear, existing ones keep their
names, types and meaning.

### Changelog

- **0.1** — First release. Watch-list mode (filings, officers, status,
  charges) and lead-gen mode (new incorporations by SIC code), fair
  cross-company budgeting, client-side rate limiting.

# Actor input Schema

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

YOUR OWN free Companies House REST API key — the run uses your quota and your 600-requests-per-5-minutes rate limit, not a shared one. Get one in about five minutes: sign in at developer.company-information.service.gov.uk → 'Create an application' (choose the Live environment) → 'Create new key' → pick 'REST' (NOT 'Streaming') and leave the IP restriction empty. Paste it here.

## `companyNumbers` (type: `array`):

Companies House numbers to monitor, e.g. 00445790 (Tesco PLC), SC900284, OC301540. All-digit numbers are zero-padded to 8 characters for you, so '445790' also works. Leave empty to run lead-gen mode only.

## `events` (type: `array`):

Which kinds of change produce a dataset record. Fewer events means fewer API requests per company, so a big watch list runs faster.

## `incorporationFilter` (type: `object`):

Only used when 'incorporations' is selected above. Finds companies newly registered at Companies House matching these SIC codes within the window — a lead list of brand-new UK businesses in your sector.

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

Cap on change records emitted in a single run (cost control). The cap is shared fairly across watched companies, so one noisy company cannot crowd out the rest; anything over the cap is emitted on the next run.

## Actor input object example

```json
{
  "companyNumbers": [
    "00445790",
    "00519500"
  ],
  "events": [
    "filings",
    "officers",
    "status",
    "charges"
  ],
  "incorporationFilter": {
    "sicCodes": [
      "62012"
    ],
    "incorporatedSinceDays": 7
  },
  "maxItems": 500
}
```

# Actor output Schema

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

No description

# 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 = {
    "companyNumbers": [
        "00445790",
        "00519500"
    ],
    "incorporationFilter": {
        "sicCodes": [
            "62012"
        ],
        "incorporatedSinceDays": 7
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datadeltas/uk-companies-house-monitor").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 = {
    "companyNumbers": [
        "00445790",
        "00519500",
    ],
    "incorporationFilter": {
        "sicCodes": ["62012"],
        "incorporatedSinceDays": 7,
    },
}

# Run the Actor and wait for it to finish
run = client.actor("datadeltas/uk-companies-house-monitor").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 '{
  "companyNumbers": [
    "00445790",
    "00519500"
  ],
  "incorporationFilter": {
    "sicCodes": [
      "62012"
    ],
    "incorporatedSinceDays": 7
  }
}' |
apify call datadeltas/uk-companies-house-monitor --silent --output-dataset

```

## MCP server setup

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

```

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/zUA6t7lICJlelI5tf/builds/6nbf1w0IJ7LdgTUdu/openapi.json
