# UK Disqualified Directors (`spookyweb/uk-disqualified-directors`) Actor

Searches the Companies House register of disqualified company directors by name, company or postcode and returns the start and end dates, the reason, the court, the case reference and the companies involved.

- **URL**: https://apify.com/spookyweb/uk-disqualified-directors.md
- **Developed by:** [丂卩ㄖㄖҜㄚ](https://apify.com/spookyweb) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 officers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Disqualified Directors

Search the Companies House register of disqualified company directors and get every match as a clean row, with the start and end dates, the statutory reason, the court, the case reference and the companies the disqualification relates to. No API key, no account, no login.

### 🔍 What does UK Disqualified Directors do?

It searches the **register of disqualified directors** published by [Companies House](https://find-and-update.company-information.service.gov.uk/) and returns one row per officer. Type a surname, a full name, a company name or a postcode, and every matching entry comes back with the disqualification dates and the reason attached.

The register is the **statutory list of people and companies barred from running a UK company**. A director ends up on it through an undertaking agreed with the Insolvency Service, an order made by a court, or a designation under UK sanctions legislation. The easiest way to try it is to run the prefilled search for `smith` and look at the output table.

Most name lists stop at the name. This one opens each officer's own register page as well, which is where the **start date, end date, statutory reason, court, case reference and the companies involved** actually live. That is the difference between knowing somebody shares a name with a disqualified director and knowing whether they are barred today, until when, and what for.

### 📊 What data can I extract from the disqualified directors register?

One row per officer. Every field below is published by Companies House itself, and nothing is inferred, enriched or joined to any other source.

| Field | Description |
|---|---|
| `officerId` | Companies House identifier for the register entry, stable across runs |
| `name` | Name as published, including any alias the register records |
| `officerType` | `natural` for a disqualified person, `corporate` for a disqualified company |
| `dateOfBirth` | Date of birth as published, `YYYY-MM-DD`, null for corporate entries |
| `nationality` | Nationality as published on the officer page |
| `description` | The one line summary the register prints under the name |
| `addressSnippet` | Address given by the disqualifying authority, as one line |
| `address` | The same address split into `premises`, `addressLine1`, `addressLine2`, `locality`, `region`, `postalCode` and `country` |
| `postcode` | Postcode on its own, for sorting and joining |
| `disqualificationCount` | How many disqualifications the register holds for this officer |
| `isCurrentlyDisqualified` | True when at least one disqualification was still running on the retrieval date |
| `disqualificationType` | `Undertaking`, `Court order` or `Sanction`, for the leading entry |
| `startDate` | Date the leading disqualification began |
| `endDate` | Date it ends, null on a sanction, which runs until the designation is lifted |
| `reason` | The statutory reason, quoted from the register |
| `caseReference` | Case reference, sometimes several separated by commas |
| `court` | Court that made the order, null on an undertaking or a sanction |
| `sanctionListReference` | UK sanction list reference, on sanction entries only |
| `companyNames` | Companies the leading disqualification relates to |
| `disqualifications` | Every disqualification held by the officer, most recent first, each with its own type, dates, case, court, companies, reason and `isInForce` flag |
| `detailsUrl` | The public Companies House page the row was read from |
| `retrievedAt` | When the row was collected, ISO 8601 |

An officer can hold more than one disqualification. When they do, the flat fields describe the leading one, meaning whichever is still in force, or the most recent if none is, and the `disqualifications` array carries the full set.

### 💡 Why search the disqualified directors register?

**Counterparty checks.** Run a supplier, a contractor or a new client through the register before signing, and get the dates back rather than a yes or no, so a disqualification that ended in 2019 is not treated like one that runs to 2036.

**Onboarding and KYC.** Screen a batch of director names in one run and keep `detailsUrl` on every row, so an analyst reviewing a hit lands straight on the official page instead of searching for it again.

**Insolvency and restructuring work.** Search a company name and see which of its former directors were disqualified for conduct while acting for it, with the case reference and the court attached.

**Journalism and research.** Pull the entries behind a company, a postcode or a surname and get the statutory reason verbatim, which is the part that says whether this was unfit conduct, a conviction, or a sanctions designation.

**Register monitoring.** Re-run the same search on a schedule and diff the output, because `officerId` is stable, so a new entry against a name you watch shows up as a new row.

### 🚀 How do I use UK Disqualified Directors?

1. Click **Try for free**.
2. Put a surname, a full name, a company name or a postcode into `query`. The register matches on the name and on the address the disqualifying authority gave.
3. Leave `fetchDisqualificationDetails` on, so each row comes back with its dates, reason, court and companies.
4. Narrow it if you want to: `officerType` splits people from companies, `disqualificationType` keeps undertakings, court orders or sanctions, and `activeOnly` drops disqualifications that have already expired.
5. Set `maxResults` to cap what the run can cost, and `maxRecordsScanned` to cap how far it reads when the filters are narrow.
6. Click **Start**, then download the results as JSON, CSV or Excel, or read them from the API.

### ⬇️ Input

```json
{
  "query": "smith",
  "officerType": "natural",
  "activeOnly": true,
  "fetchDisqualificationDetails": true,
  "maxResults": 100
}
```

| Field | Type | Default | What it does |
|---|---|---|---|
| `query` | string | `smith` | Name, company name or postcode to search. Required |
| `officerType` | string | `any` | `any`, `natural` for people, `corporate` for companies |
| `disqualificationType` | string | `any` | `any`, `Undertaking`, `Court order` or `Sanction` |
| `activeOnly` | boolean | `false` | Keep only disqualifications still in force on the run date |
| `fetchDisqualificationDetails` | boolean | `true` | Open each officer page for the dates, reason, court and companies |
| `maxResults` | integer | `100` | Hard cap on billable results. Maximum 300 |
| `maxRecordsScanned` | integer | `400` | Safety stop on how many officers are read when the filters are narrow |

`activeOnly` and `disqualificationType` are read from the officer page, so setting either one switches `fetchDisqualificationDetails` back on and says so in the log. A filter that is accepted and then never applied is worse than one that is rejected, because it hands back the wrong answer with full confidence.

### ⬆️ Output

#### Table view

Results arrive as a **Disqualified officers** table you can sort and filter in the Console, with the name, type, date of birth, disqualification dates and the link to the register entry lined up for scanning. A second view, **Cases and companies**, lines up the reason, the case reference, the court and the companies instead, which is the view to use when you are reading why rather than who.

#### JSON

A typical row, with fictional values in place of a real person:

```json
{
  "officerId": "b0FM3wgkYJ_p3TGirZotCfndF7c",
  "name": "Jane Alexandra EXAMPLE",
  "officerType": "natural",
  "dateOfBirth": "1980-01-01",
  "nationality": "British",
  "description": "Born on 1 January 1980 - Disqualified",
  "addressSnippet": "1 Example Street, Exampleton, United Kingdom, EX1 1EX",
  "postcode": "EX1 1EX",
  "disqualificationCount": 1,
  "isCurrentlyDisqualified": true,
  "disqualificationType": "Undertaking",
  "startDate": "2024-03-05",
  "endDate": "2031-03-04",
  "reason": "Company Directors Disqualification Act 1986 (Section 7): Disqualification order or undertaking; and reporting provisions",
  "caseReference": "INV0000000",
  "court": null,
  "sanctionListReference": null,
  "companyNames": ["EXAMPLE TRADING LTD"],
  "detailsUrl": "https://find-and-update.company-information.service.gov.uk/disqualified-officers/natural/b0FM3wgkYJ_p3TGirZotCfndF7c",
  "retrievedAt": "2026-08-16T09:00:00.000Z"
}
```

`disqualificationCount` and `isCurrentlyDisqualified` are null, not zero and false, when `fetchDisqualificationDetails` is off. Nothing about the disqualification has been read in that mode, and unknown is not the same statement as none about a named person.

Every run also writes a `RUN_SUMMARY` record to the key-value store with the search that ran, how many entries the register held, how many officers were read and saved, how many pages could not be read, and why the run stopped: `complete`, `max-results-reached`, `scan-limit-reached`, `time-limit-reached`, `page-limit-reached`, `charge-limit-reached` or `error`.

### The three kinds of disqualification

The register mixes three routes onto the same list, and they do not carry the same fields.

**Undertaking.** The director agreed not to act rather than fight it in court. `caseReference` starts with `INV` and there is no `court`. This is the commonest kind.

**Court order.** A judge imposed it. There is a `court`, and `caseReference` is the court's own reference, occasionally several of them separated by commas.

**Sanction.** A designation under the Sanctions and Anti-Money Laundering Act 2018. These carry a `sanctionListReference` instead of a case reference, have **no end date**, and are usually `corporate` rather than `natural`. An open ended sanction that has already started is reported as in force, because it runs until the designation is lifted.

### What the search matches, and how far it pages

The register is searched by **name and by the address the disqualifying authority provided**. A surname works, a full name works, a company name works, and a postcode works. A town or city name on its own does not, because the locality is not part of the searchable text.

Companies House serves this search **20 records at a time and will not page past the 2,000th match**. A query with more matches than that logs a warning and reads from the start of the list, so a very common surname is better split into full names than run wide. `maxResults` caps a single run at 300 officers and `maxRecordsScanned` caps how many are read looking for them, so a narrow filter over a common name stops and says so rather than running until the clock does. Requests are paced deliberately and run one at a time, because this is a government service and there is no reason to lean on it.

### Data source

Companies House, [find-and-update.company-information.service.gov.uk](https://find-and-update.company-information.service.gov.uk/), published under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). The register of disqualified directors is a **statutory public register**: Companies House is required to publish it, and the entries are public precisely so that anyone dealing with a director can check.

This Actor returns what the register publishes and nothing else. There is no enrichment, no matching against other sources, no address lookup and no attempt to link an entry to a living person beyond the identifiers Companies House itself prints. Entries are a snapshot, so link back to `detailsUrl` for the current position.

### 💰 How much does it cost?

You pay per officer returned, so a run that saves 100 officers is 100 billable results. Nothing else is charged: opening an officer's page for the dates and the reason costs you no extra.

Set `maxResults` to cap what a run can cost. Use `officerType`, `disqualificationType` and `activeOnly` to avoid paying for rows you were going to throw away, since a filtered row is never saved and never billed. A search that matches nobody saves nothing and costs nothing. Paid Apify plans get a lower rate per officer.

### 🔌 Integrations

Send results straight to Google Sheets, Slack, Airtable, Zapier, Make or your own webhook using [Apify integrations](https://docs.apify.com/platform/integrations). Schedule a run so a watched name is rechecked every week, monitor runs from the Console, and trigger a run from another tool when a new supplier or client record is created.

### 🔗 Using UK Disqualified Directors with the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/spookyweb~uk-disqualified-directors/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "smith", "officerType": "natural", "activeOnly": true, "maxResults": 100}'
```

Or with the Apify client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('spookyweb/uk-disqualified-directors').call({
  query: 'smith',
  officerType: 'natural',
  activeOnly: true,
  maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Full detail is in the [Apify API reference](https://docs.apify.com/api/v2), and every run is also callable from the [Python](https://docs.apify.com/api/client/python) and [JavaScript](https://docs.apify.com/api/client/js) clients.

### ❓ FAQ

#### Do I need a Companies House API key?

No. The Companies House REST API does require a free key, but this Actor does not use it. It reads the same register from the public Companies House service, which needs no key, no account and no sign in.

#### How do I tell whether somebody is disqualified right now?

Read `isCurrentlyDisqualified`. It is true when at least one of the officer's disqualifications was still running on `retrievedAt`, comparing against `endDate` inclusively, false when every one of them has ended, and null when `fetchDisqualificationDetails` was off and no page was read. Set `activeOnly` to true and only the officers still disqualified are returned at all. Expired entries stay on the register, so a hit on a name is not the same thing as a live disqualification.

#### What does the reason field actually say?

It quotes the statute. Section 6 of the Company Directors Disqualification Act 1986 is unfit conduct as a director of an insolvent company, Section 7 covers a disqualification order or undertaking, Section 2 is disqualification on conviction of an indictable offence, and Section 3A of the Sanctions and Anti-Money Laundering Act 2018 covers designated persons. The text is copied from the register rather than summarised.

#### Can I search by company instead of by person?

Yes. Put the company name into `query`. The register matches disqualified corporate entities by their own name, and the `companyNames` field on each row lists the companies a person's disqualification relates to, so a company search and a company name in the output are two different things worth checking.

#### Why do some rows have no end date?

Because they are sanctions. A disqualification under sanctions legislation runs for as long as the designation does, so the register prints a start date and nothing else. Those rows carry a `sanctionListReference` and are reported as in force once they have started.

#### How many results can one search return?

`maxResults` tops out at 300, which is what one run reads inside the 300 second default run timeout with the disqualification details switched on, since that is one page fetch per officer. A run that gets close to the limit stops on its own, keeps every row it collected and records `time-limit-reached` in the run summary, rather than being killed part way through. Raise the run timeout in the Console for a longer pull, or split the search into narrower queries, for example a full name rather than a surname.

Companies House itself serves 20 records per page and refuses to page beyond the 2,000th match, so 2,000 is the absolute ceiling for a single search term however many matches the register reports.

#### Does an officer ever have more than one disqualification?

Yes, and the register puts them all on one page. `disqualificationCount` says how many, the `disqualifications` array carries each one with its own dates, case, court, companies and reason, and the flat fields on the row describe whichever is still in force or, failing that, the most recent.

#### What happens if my search matches nobody?

The run finishes successfully with an empty dataset and a log line telling you so. A clean director is the normal case and is not an error, so nothing fails and nothing is billed.

### ⚖️ Is it legal to search the disqualified directors register?

Companies House publishes the register of disqualified directors under a statutory duty, and it is free to search by anyone, without an account. It exists so that people dealing with a company can find out whether a director is barred. The data is available under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/), which permits commercial use with attribution.

Because the register names individuals, this Actor deliberately publishes only what Companies House publishes and adds nothing to it. If you are processing these rows in the UK or the EU you are still the controller of what you do next, so use them for the purpose the register exists for and keep the `detailsUrl` link so any hit can be verified against the official page. Apify's [ethical scraping guide](https://blog.apify.com/is-web-scraping-legal/) covers the wider picture.

### 👍 Your feedback

Found a bug, or want a field that is not here yet? Open an issue on the Actor's Issues tab. Requests that make the data more useful get built, and problems get fixed quickly.

### 🔎 You might also like

| Actor | What it does |
|---|---|
| [UK Insolvency Register Search](https://apify.com/spookyweb/uk-insolvency-register-search) | Individual Insolvency Register search for bankruptcies, IVAs and debt relief orders |
| [UK Food Hygiene Ratings](https://apify.com/spookyweb/uk-food-hygiene-ratings) | Official FSA hygiene ratings for every UK food business, by council, postcode or rating |
| [UK Planning Applications](https://apify.com/spookyweb/uk-planning-applications) | Planning applications from every UK council, tagged by the type of work proposed |
| [Company Email Finder](https://apify.com/spookyweb/company-email-finder) | Company domain in, work email addresses out, with the pattern inferred from the site |

# Actor input Schema

## `query` (type: `string`):

Who to look for on the disqualified directors register. A surname such as smith, a full name such as john smith, a disqualified company name, or a postcode such as SW1A 1AA. The register is searched by name and by the address the disqualifying authority gave, so a town name on its own will not match.

## `officerType` (type: `string`):

Whether to keep disqualified people, disqualified corporate entities, or both. Corporate entries are mostly companies disqualified under sanctions legislation rather than individual directors.

## `disqualificationType` (type: `string`):

Keep only officers holding a disqualification of this kind. An undertaking is agreed with the Insolvency Service, a court order is imposed by a judge, and a sanction comes from the UK sanctions list. Read from the officer page, so it turns disqualification details on.

## `activeOnly` (type: `boolean`):

Drop officers whose disqualification period has already ended. The register keeps entries after they expire, so this is the difference between people who cannot be a director today and people who once could not. Read from the officer page, so it turns disqualification details on.

## `fetchDisqualificationDetails` (type: `boolean`):

Open each officer page to collect the start and end dates, the reason, the court, the case reference, the nationality and the companies involved. Leave it on. Turning it off returns names and addresses only, and costs one request per officer less.

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

Hard cap on how many officers a run returns. Each officer saved is one billable result. The ceiling is 300 because reading one officer page each is what fits inside the 300 second default run timeout, and a run that runs out of time stops cleanly and keeps everything it collected.

## `maxRecordsScanned` (type: `integer`):

Safety stop on how many officers the run reads before giving up on filling the result cap. It matters when officerType, disqualificationType or activeOnly are narrow, because those are applied after each officer page has been fetched, and a search that matches almost nobody would otherwise read the register until the run is killed.

## Actor input object example

```json
{
  "query": "smith",
  "officerType": "any",
  "disqualificationType": "any",
  "activeOnly": false,
  "fetchDisqualificationDetails": true,
  "maxResults": 20,
  "maxRecordsScanned": 400
}
```

# Actor output Schema

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

One row per disqualified officer, with the disqualification dates, reason and companies.

## `runSummary` (type: `string`):

The search that ran, how many entries the register held and why the run stopped.

# 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 = {
    "query": "smith",
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("spookyweb/uk-disqualified-directors").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 = {
    "query": "smith",
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("spookyweb/uk-disqualified-directors").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 '{
  "query": "smith",
  "maxResults": 20
}' |
apify call spookyweb/uk-disqualified-directors --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,spookyweb/uk-disqualified-directors"
        }
    }
}

```

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/a2oAMAoA4YanK6fxX/builds/fhsRSgUxa4hIIqTfX/openapi.json
