# Companies House Watchlist – Change Alerts (`hllerdgn80/companies-house-watchlist`) Actor

Track a list of UK company numbers over time using the free official Companies House API and get only what CHANGED since the last run: new/resigned officers, new/ceased PSCs, new or satisfied charges, new filings, and company status changes (e.g. active to dissolved).

- **URL**: https://apify.com/hllerdgn80/companies-house-watchlist.md
- **Developed by:** [Halil Erdogan](https://apify.com/hllerdgn80) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Companies House Watchlist — change alerts, not another snapshot

Give it a list of UK company numbers and your own free Companies House API
key. Run it again later (daily, weekly — however you schedule it) against
the same list, and instead of another static export it tells you **only
what changed since last time**:

- a director or secretary was **appointed** or **resigned**
- a **person with significant control (PSC)** was added or ceased
- a **charge (mortgage/security interest)** was newly **registered** — a
  real signal that the company just took on new secured lending/finance —
  or an existing charge was **satisfied** (paid off)
- a **new filing** appeared in the company's filing history
- the company's own **status changed** (e.g. `active` → `dissolved`,
  `active` → `administration`), or an insolvency-history flag started

The first run for any company is a **baseline**: it stores the current
state and reports zero changes (nothing to compare against yet). Every run
after that reports real deltas.

### Why this and not the other Companies House Actors

The Apify Store already has several Companies House Actors — checked live,
27 September 2026, via the Store's own public API
(`api.apify.com/v2/store?search=companies house`):

| Actor | Total users | What it does |
|---|---|---|
| `companies-house-scraper` | 95 | company profile + officers + PSCs + charges, one-shot |
| `uk-companies-house-scraper` | 98 | company profile + officers, one-shot |
| `uk-companies-house-bulk-scraper` | 60 | bulk export of 5M+ companies, one-shot |
| `uk-companies-house-enricher` | 23 | profile + financials enrichment, one-shot |
| `companies-house-uk-financials-scraper` | 8 | parsed accounts + officers + PSCs, one-shot |

Every one of them is a **snapshot** tool: point it at a company and it hands
back the current state. None of them keep any memory of a previous run, so
none of them can answer the question a compliance analyst, credit team or
sales-intelligence user with an existing watchlist actually asks: *"has
anything happened since I last checked?"* This Actor is built specifically
to answer that question — it stores each company's snapshot in its own
Apify key-value store between runs and diffs the new snapshot against it,
so scheduling it (e.g. once a day) turns it into an actual monitoring feed
instead of a repeated manual lookup.

### Data source

Everything comes from the UK government's own **official, free Companies
House Public Data API**
(`api.company-information.service.gov.uk`, documented at
developer-specs.company-information.service.gov.uk). No scraping of the
find-and-update.company-information.service.gov.uk website, no ToS issue:
this is Companies House's own REST API, built for exactly this kind of
integration. A free API key takes about two minutes to register at
[developer.company-information.service.gov.uk](https://developer.company-information.service.gov.uk/)
— no card, no approval wait, no paid tier required for the endpoints this
Actor uses (company profile, officers, PSCs, charges, filing history).

Verified live (27 September 2026, unauthenticated): a request to
`GET /company/00000006` without a key returns HTTP 401
`{"error":"Empty Authorization header","type":"ch:service"}` — confirming
the endpoint is live and that a key is the only credential needed.

### Input

- **Companies House API key** (your own, free, marked secret) — required
- **Company numbers** — one per line, or paste a block of text (commas/
  semicolons/newlines all work). Plain numeric numbers are zero-padded to 8
  digits automatically (`6` → `00000006`); Scottish (`SC`), Northern
  Irish/other (`NI`, `R0`) and LLP (`OC`, `SO`) prefixes are kept as given.
- Toggle which categories to watch: officers, PSCs, charges, filings (all
  on by default)
- Concurrency (1–10; Companies House's public API allows 600 requests per
  5 minutes per key — keep this low if you watch all four categories,
  which is up to 5 requests per company per run)

### Output (one row per company per run)

```json
{
  "company_number": "00000006",
  "company_name": "EXAMPLE COMPANY LIMITED",
  "company_status": "active",
  "is_baseline_run": false,
  "changes_found": 2,
  "changes": [
    {
      "event": "charge_registered",
      "detail": "New charge #3 (A registered charge) registered on 2026-09-20 in favour of Big Bank plc",
      "data": { "...": "full charge record" }
    },
    {
      "event": "officer_resigned",
      "detail": "Jane Doe (director) resigned on 2026-09-22",
      "data": { "...": "full officer record" }
    }
  ],
  "current_officer_count": 4,
  "current_psc_count": 1,
  "current_open_charge_count": 2,
  "status": "ok"
}
```

A company with no changes since last run still gets a row (`changes_found:
0`, `changes: []`) — useful for a "still clean" confirmation, and it means
your dataset always has one row per company per run for easy scheduling
and history.

### Pay-per-event

The custom event `company-checked` is charged once per company that was
actually reachable on the register (`status: "ok"`), whether or not any
change was found — a "nothing changed" result is still a real check you
paid to have run. `not_found` and `unauthorized` rows are not charged.

### Honest limits (kept out rather than faked)

- This Actor watches **officers, PSCs, charges, filing history and company
  status** — it does **not** parse company **accounts/financials** (iXBRL);
  that is a materially different parsing job other Actors in this niche
  specialise in, and adding a shallow version here would risk wrong
  numbers rather than a real feature.
- The "baseline" run intentionally reports zero changes even though, e.g.,
  every existing officer looks "new" internally — reporting a company's
  entire existing officer list as if it just happened would be misleading
  on day one; real alerts start from run two.
- Companies House's officer/PSC records do not expose a single stable
  numeric ID in the public API the way an internal database would; this
  Actor keys officers/PSCs by their `links.self`/appointment link (stable
  per person per role) and falls back to name — matched. If Companies
  House itself renames or re-issues a link, a resignation+reappointment
  could show as `officer_removed_from_register` + `officer_appointed`
  rather than a single event; this is documented rather than silently
  hidden.

### Related Actors in this account

- `corporate-kyc-intelligence` — GLEIF LEI ownership tree & compliance
  flags for any company worldwide (single-lookup, not UK-specific, not a
  watchlist)
- `uk-planning-applications` — UK local council planning application
  search/monitoring via the PlanIt API

# Actor input Schema

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

Register a free key in two minutes at developer.company-information.service.gov.uk (Manage applications -> Add an application -> REST API key). No card, no approval wait. Required - the Actor cannot call the official API without it.

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

One per line: an 8-character Companies House number (e.g. 00000006), or a Scottish/NI/LLP number with its letter prefix (e.g. SC012345, OC012345). Plain numbers are zero-padded automatically. Duplicates are removed.

## `companyNumbersText` (type: `string`):

Paste many company numbers at once: one per line (commas and semicolons also separate entries). Combined with the list above.

## `watchOfficers` (type: `boolean`):

Alert on new appointments and resignations.

## `watchPscs` (type: `boolean`):

Alert on new PSCs notified and PSCs who ceased.

## `watchCharges` (type: `boolean`):

Alert on new charges registered (a real signal of new secured lending/finance) and charges satisfied (paid off).

## `watchFilings` (type: `boolean`):

Alert on any new document appearing in the company's filing history (accounts, confirmation statements, resolutions, etc.).

## `maxConcurrency` (type: `integer`):

How many companies to check in parallel. Companies House's public API allows 600 requests per 5 minutes per key; keep this low if you also watch charges/filings/officers/PSCs together (up to 5 requests per company).

## Actor input object example

```json
{
  "companyNumbers": [
    "00000006",
    "SC012345"
  ],
  "watchOfficers": true,
  "watchPscs": true,
  "watchCharges": true,
  "watchFilings": true,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (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",
        "SC012345"
    ]
};

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

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

```

## MCP server setup

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

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/OsKyh6dkUIPA7WyPc/builds/Wisixk8sNLIrBwD9a/openapi.json
