# UK Companies House Watcher – Company Change Alerts (`polychrome_haymow/uk-companies-house-watcher`) Actor

Monitor UK companies via the official Companies House API. Get alerts on status, name, registered office, SIC, insolvency, charges, new filings and officer appointments/resignations. No personal data.

- **URL**: https://apify.com/polychrome_haymow/uk-companies-house-watcher.md
- **Developed by:** [Levani Zurabiani](https://apify.com/polychrome_haymow) (community)
- **Categories:** Business, Integrations
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 company checkeds

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 Companies House Watcher – Company Change Alerts

Monitor a watchlist of UK companies with the **official Companies House Public Data API** and get one clean record for each company that changed: status, name, registered office, SIC codes, insolvency/charges flags, new filing-history items, and officer appointments/resignations (role and date only).

**Who it's for:** credit controllers and finance teams, KYC/AML and supplier-risk teams, insolvency practitioners, B2B sales teams tracking accounts, investors and journalists.

### Get a free API key

The actor needs a free Companies House REST API key:

1. Register at the Companies House developer hub: https://developer.company-information.service.gov.uk/
2. Create an application (choose **Live**), then add a **REST** API key.
3. Paste the key into the `apiKey` input (stored as an encrypted secret). Alternatively set the `COMPANIES_HOUSE_API_KEY` environment variable.

Use of the API is subject to the Companies House developer terms and conditions: https://developer-specs.company-information.service.gov.uk/terms-and-conditions (rate limit 600 requests per 5 minutes: https://developer-specs.company-information.service.gov.uk/guides/rateLimiting).

### How it works

1. Add company numbers (e.g. `00445790`, `SC005336`). You can also add companies from a **name search** or a **SIC-code search**.
2. The first run saves a baseline snapshot of each company in a **named key-value store** (`stateStoreName`). That store stays in your account between runs.
3. Schedule the actor to run daily or weekly. Each run compares the live data with the snapshot and outputs only what changed (`onlyChanges: true`).

### What is detected

| Change | Field |
|---|---|
| Status (e.g. active → liquidation / dissolved) | `companyStatus`, `companyStatusDetail`, `dateOfCessation` |
| Name change | `companyName` |
| Registered office moved | `registeredOffice`, `registeredOfficeIsInDispute` |
| SIC codes changed | `sicCodes` |
| Insolvency history / charges flags | `hasInsolvencyHistory`, `hasCharges` |
| Accounts / confirmation statement overdue | `accountsOverdue`, `confirmationStatementOverdue` |
| New filings | `newFilings[]` (transaction id, date, category, form type, description code) |
| Officer appointed / resigned | `officerChanges[]` = `{ role, change, date }` |

### Input example

```json
{ "companyNumbers": ["00445790", "02366995", "SC005336"], "onlyChanges": true }
```

SIC search: `{ "searchMode": "sic", "sicCodes": ["62020"], "companyStatus": "active", "maxResults": 500 }`

### Output example

```json
{
  "companyNumber": "01234567", "companyName": "EXAMPLE TRADING (UK) LIMITED", "companyStatus": "liquidation",
  "hasChanges": true, "firstSnapshot": false,
  "changes": [{ "field": "companyStatus", "before": "active", "after": "liquidation" }],
  "newFilings": [{ "transactionId": "MzAz", "date": "2026-10-01", "category": "officers", "type": "TM01", "description": "termination-director-company-with-name-termination-date" }],
  "officerChanges": [{ "role": "director", "change": "resigned", "date": "2026-09-30" }],
  "companyUrl": "https://find-and-update.company-information.service.gov.uk/company/01234567",
  "source": "Contains public sector information licensed under the Open Government Licence v3.0 (Companies House)"
}
```

### Pricing

Pay per event. Platform compute is included.

- **$0.0025 per company checked** (profile + filings + officers, compared with the last snapshot)
- **$0.004 per change alert** (only for companies that actually changed)

Example: a daily watch of 500 companies where 10 change costs 500 × $0.0025 + 10 × $0.004 = **$1.29 per run**. A changed company costs $0.0065 in total. Set *max cost per run* to cap spending. The actor stops cleanly when the limit is reached.

### Integrations (Zapier / Make)

Use Apify's **Zapier** or **Make** integration, or a **webhook** on "run succeeded", to send changed companies to Slack, email, Google Sheets or your CRM. Because only changes are output, every dataset item can be treated as an alert. Schedule runs in Apify Console (e.g. daily at 07:00 UK time).

### FAQ

**Where does the data come from?** Only from the official Companies House Public Data API (`api.company-information.service.gov.uk`). The actor does no website scraping.

**Is personal data included?** No. Output is company-level only. Officer names, birth dates, nationalities, occupations, and residential or service addresses are never output or stored. Officer changes show only the role and the appointment or resignation date. Filing `description_values`, which can contain names, are dropped. A final check rejects any record that contains a personal-data field.

**Why can't I see director names?** This is deliberate (data minimisation). You can open `companyUrl` to see the official register.

**How fresh is it?** Companies House updates the API continuously. Each run reads live data.

**How many companies can I watch?** 150 per run by default, up to 10,000 (`maxResults`). The default timeout is 1 hour; raise it for large watchlists. Snapshots are saved every 25 companies, so an aborted or timed-out run keeps its progress. The API allows 600 requests per 5 minutes and each company takes up to 3 requests, so expect about 200 companies per 5 minutes. A 10,000-company run with filings and officers turned on takes about 4 hours. Turn off `checkFilings`/`checkOfficers` to speed it up 3×.

**What does the first run output?** A baseline record for every company (`firstSnapshot: true`). Change alerts start from the second run, and baseline records are not charged as alerts.

**Can I run several watchlists?** Yes. Give each one its own `stateStoreName`.

**Officer changes are limited?** The latest 100 appointments per company are compared. That covers almost all companies.

### Licence & attribution

Contains public sector information licensed under the Open Government Licence v3.0 (Companies House). Every record carries this in `source`.

### Disclaimer

This actor is not affiliated with or endorsed by Companies House. Data is provided "as is" and should be checked against the official register before you make important decisions.

### Running locally

```bash
npm ci
COMPANIES_HOUSE_API_KEY=your-key npx apify run   # or: npm start (uses ./storage)
npm test                                         # unit tests with mocked API responses
```

# Actor input Schema

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

Free REST API key from https://developer.company-information.service.gov.uk/ (create an application, then a REST key). Stored encrypted. Falls back to the COMPANIES_HOUSE_API_KEY environment variable.

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

UK company numbers to watch, e.g. 00445790 or SC123456. Short numeric numbers are zero-padded to 8 digits.

## `searchMode` (type: `string`):

Optionally add companies found by a name search or SIC-code search to the watchlist.

## `searchQuery` (type: `string`):

Used when search mode is 'Company name'.

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

SIC 2007 codes (e.g. 62020). Used when search mode is 'SIC code'.

## `companyStatus` (type: `string`):

Only add search results with this status.

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

Default 150, hard cap 10,000. Limits companies checked (and cost). About 200 companies per 5 minutes with filings and officers on; raise the run timeout for large watchlists.

## `onlyChanges` (type: `boolean`):

After the first (baseline) run, output only companies that changed. Turn off to output every company each run.

## `checkFilings` (type: `boolean`):

Report new filing-history items (1 extra API call per company).

## `checkOfficers` (type: `boolean`):

Report appointments/resignations as role + date only (1 extra API call per company).

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

Named key-value store holding the previous snapshot. Use a different name per watchlist.

## Actor input object example

```json
{
  "companyNumbers": [
    "00445790",
    "02366995",
    "SC005336"
  ],
  "searchMode": "none",
  "maxResults": 150,
  "onlyChanges": true,
  "checkFilings": true,
  "checkOfficers": true,
  "stateStoreName": "uk-companies-house-watcher-state"
}
```

# Actor output Schema

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

All records (JSON; append ?format=csv|xlsx).

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

Changes view.

## `stats` (type: `string`):

Companies checked, records emitted, API requests.

# 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",
        "02366995",
        "SC005336"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("polychrome_haymow/uk-companies-house-watcher").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",
        "02366995",
        "SC005336",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("polychrome_haymow/uk-companies-house-watcher").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",
    "02366995",
    "SC005336"
  ]
}' |
apify call polychrome_haymow/uk-companies-house-watcher --silent --output-dataset

```

## MCP server setup

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

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/BOpJApmmu7kP4tB97/builds/cjx7dBcL5yztersbT/openapi.json
