# UK Company Change Monitor - Companies House watchlist (`minimal_ricegrass/uk-company-change-monitor`) Actor

Watch a list of UK company numbers and get only what changed at Companies House each run - status, name, registered office, accounts, charges, officers, filings - with optional webhook POST.

- **URL**: https://apify.com/minimal\_ricegrass/uk-company-change-monitor.md
- **Developed by:** [FJ Banks](https://apify.com/minimal_ricegrass) (community)
- **Categories:** Business, Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.02 / actor start

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 Company Change Monitor — Companies House watchlist

Give it a list of UK company numbers — your **customers, suppliers, competitors,
prospects, portfolio companies** — and on every scheduled run it checks
Companies House and emits **only what changed** since the last run:

- **status** — e.g. active → *in administration* / *liquidation* / *dissolved*
- **name** change
- **registered office** move
- **accounts** filed, or newly **overdue**
- **charges** (mortgages) added, removed or satisfied
- **officers** appointed or resigned
- any **new filing** at all (category + description)

Optional webhook POST to Slack, Zapier, Make or n8n.

### Who it's for

| Buyer | Use |
|---|---|
| Credit control / finance teams | A customer entering administration, or accounts going overdue — before it's a bad debt |
| Compliance / KYC / onboarding | Keep KYC current: directors, PSCs, addresses, status, without manual re-checks |
| Account managers / CS | A client changed name, moved, or took on new debt — a reason to call |
| Competitive intelligence | A rival raising a charge (funding), changing directors, or filing accounts |
| M\&A / corp dev / search funds | Signals on a target list — new charges, director exits, filings |
| Suppliers on credit terms | Early warning on the businesses you invoice |

### Quick start

1. **Free Companies House key:** developer.company-information.service.gov.uk →
   register an application → create a **REST** key (Live). Paste into `apiKey`.
2. Put your company numbers in **`companyNumbers`** (8 chars each, e.g.
   `12345678` or `SC123456`).
3. Choose **`watch`** — which change types you care about (default: all).
4. Run once (it just records the baseline). Set `emitOnFirstSight: true` on that
   first run if you want a `now_watching` row per company to confirm the list.
5. **Schedule** it — daily is typical; more often for a hot watchlist.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `apiKey` | string *(secret)* | — | **Required.** Companies House REST key (Live). |
| `companyNumbers` | string\[] | — | **Required.** Company numbers to watch. Spaces ignored, case-insensitive. |
| `watch` | string\[] | all | Any of `status`, `name`, `address`, `accounts`, `charges`, `officers`, `filings`. |
| `emitOnFirstSight` | boolean | `false` | Emit a `now_watching` record the first time each company is seen. |
| `webhookUrl` | string | — | POST `{source, count, changes[]}` each run. |
| `maxCompanies` | integer 1–2000 | `500` | Cap per run. CH allows 600 requests / 5 min; this actor makes 2–4 per company. |

### Output

One dataset item per detected change:

| `change_type` | Extra fields |
|---|---|
| `now_watching` | `company_status` *(first-sight only)* |
| `status_changed` | `from`, `to` |
| `name_changed` | `from`, `to` |
| `address_changed` | `from`, `to` |
| `accounts_filed` | `made_up_to` |
| `accounts_overdue` | `next_due` |
| `charge_added` | `count`, `charge_ids` |
| `charge_removed` | `count` |
| `charge_satisfied` | `outstanding` |
| `officer_appointed` | `officers` (`"NAME|role"`) |
| `officer_resigned` | `officers` |
| `new_filing` | `category`, `description`, `date` |

Every item also has `company_number`, `company_name`, `detected_at`.

#### Webhook payload

```
POST <webhookUrl>
{ "source": "uk-company-change-monitor", "count": 3, "changes": [ /* dataset items */ ] }
```

### How it works

For each company the actor builds a small **snapshot** (the watched fields from
the profile, charges, officers and latest-filing endpoints), stores it in a
**named** key-value store (`uk-company-change-state`, one record per company),
and on the next run diffs the new snapshot against the stored one. Requests per
company: 1 (profile) + 1 each for charges / officers / filings that are in
`watch` — so 2–4. A `429` stops the run cleanly and it resumes next time;
companies that error (e.g. an invalid number) are listed in `RUN_SUMMARY.problems`
and skipped, not fatal.

### Local development

```bash
npm install
npm test
echo '{"apiKey":"YOUR_KEY","companyNumbers":["00000006"],"emitOnFirstSight":true}' > storage/key_value_stores/default/INPUT.json
npm start
```

### Deploy

```bash
npm i -g apify-cli && apify login && apify push
```

### Data source & licensing

Data from the **Companies House Public Data API**
(`api.company-information.service.gov.uk`), public register data under the
[Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).
Requires your own free API key.

### Related actors

Part of a small suite of UK public-register monitors, same publisher, same
pattern (incremental, no duplicates, webhook-ready):

- **[UK New Company Monitor](https://apify.com/minimal_ricegrass/uk-newco-monitor)** — new incorporations by SIC / location
- **[UK Insolvency Notice Monitor](https://apify.com/minimal_ricegrass/uk-insolvency-monitor)** — winding-up, administration, bankruptcy (The Gazette)
- **[UK Food Business Monitor](https://apify.com/minimal_ricegrass/uk-food-monitor)** — new food businesses + hygiene-rating changes (FSA)
- **[UK Public Tender Monitor](https://apify.com/minimal_ricegrass/uk-tender-monitor)** — public-sector tenders by CPV / value (Contracts Finder)

***

### Changelog

- **0.1** — Initial release: watchlist snapshots + diff across status, name,
  address, accounts, charges, officers and filings; per-company state; webhook;
  rate-limit-safe resume.

# Actor input Schema

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

Free REST key from developer.company-information.service.gov.uk (register an application, Live key).

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

8-character Companies House numbers, e.g. "12345678" or "SC123456". Spaces are ignored.

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

Which kinds of change to report.

## `emitOnFirstSight` (type: `boolean`):

The first time a company is checked there is nothing to compare against. Turn on to emit a 'now\_watching' record so you can confirm the watchlist.

## `webhookUrl` (type: `string`):

POST the changes from each run to this URL (Slack, Zapier, Make, n8n, custom).

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

Cap on watchlist size processed per run. Companies House allows 600 requests / 5 min and this actor makes 2-4 requests per company.

## Actor input object example

```json
{
  "companyNumbers": [
    "00000006",
    "02050399"
  ],
  "watch": [
    "status",
    "name",
    "address",
    "accounts",
    "charges",
    "officers",
    "filings"
  ],
  "emitOnFirstSight": false,
  "maxCompanies": 500
}
```

# Actor output Schema

## `changes` (type: `string`):

Companies House changes across the watchlist since the last run.

## `table` (type: `string`):

No description

## `runSummary` (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": [
        "00000006",
        "02050399"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("minimal_ricegrass/uk-company-change-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": [
        "00000006",
        "02050399",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("minimal_ricegrass/uk-company-change-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": [
    "00000006",
    "02050399"
  ]
}' |
apify call minimal_ricegrass/uk-company-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,minimal_ricegrass/uk-company-change-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/dsZcElbhca0DX06La/builds/5xHWV5MaptflfpDjm/openapi.json
