# Company Registry Search API - Companies House, SIRENE, LEI (`captainhandsome/company-registry-search`) Actor

Search three official company registers at once and get one flat table: UK Companies House, French SIRENE and the global LEI register. A company lookup API returning name, registration number, status, incorporation date, registered address, SIC code and LEI per row. 54 columns per record.

- **URL**: https://apify.com/captainhandsome/company-registry-search.md
- **Developed by:** [Joseph McRell](https://apify.com/captainhandsome) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Company Registry Search - UK, France & Global LEI

Search three official company registers with one query and get a single flat table back. Each row has the same columns no matter which register it came from, so a mixed export opens cleanly in a spreadsheet without any reshaping.

| Source | Register | Key needed |
|---|---|---|
| `uk` | Companies House Public Data API | Included, or bring your own |
| `france` | SIRENE, via the French government's `recherche-entreprises` API | None |
| `global` | GLEIF Legal Entity Identifier register | None |

### What data can I extract?

54 columns per row, the same columns whichever register answered:

- **Identity** - registered name, trading name, previous names, the registration number used by its own national register, LEI, French VAT number, head-office SIRET, BIC codes
- **Status and form** - active / dissolved / ceased, entity category (general, fund, branch, sole proprietor, association, public body), legal form with GLEIF's ISO 20275 codes resolved into readable English, plus the raw form code for machine joins
- **Dates** - incorporation, dissolution, and when the register itself last changed the record
- **Location** - registered office address, city, postal code, country, region; the separate operating headquarters address for LEI rows; latitude and longitude for French rows
- **Size and activity** - SIC / NAF activity code, industry section in English, INSEE size class, employee band, whether the entity is a registered employer, total and open establishment counts
- **Money** - turnover and net income in euros with the fiscal year they belong to, for French companies that file publicly
- **People** - named directors with their roles, and the count of currently appointed officers
- **Group structure** - direct and ultimate parent name and LEI
- **UK compliance** - accounts due and last made-up dates, whether accounts are overdue, confirmation statement due date, registered charges, insolvency history, undeliverable registered office
- **Provenance** - source register, jurisdiction, LEI registration status and next renewal date, and the record's public URL on the register's own site

Directors, previous names, UK compliance columns and group parents come from per-record endpoints; switch on `include_details` to fetch them. Every result is written to the default dataset and can be downloaded as JSON, CSV, Excel, or XML.

#### All 54 columns

**Identity** — `company_name`, `establishment_number`, `lei`, `lei_next_renewal_date`, `lei_registration_status`, `parent_lei`, `parent_name`, `previous_names`, `registration_number`, `trade_name`, `ultimate_parent_lei`, `ultimate_parent_name`, `vat_number`

**Status** — `active_establishment_count`, `company_type`, `entity_category`, `has_charges`, `has_insolvency_history`, `is_employer`, `size_category`, `status`

**Dates** — `dissolution_date`, `financials_year`, `incorporation_date`, `last_updated`

**Location** — `address`, `city`, `confirmation_statement_next_due`, `country`, `headquarters_address`, `headquarters_city`, `headquarters_country`, `latitude`, `longitude`, `postal_code`, `region`

**Money** — `net_income`, `revenue`

**People** — `officer_count`, `officers`

**Contact** — `url`

**Counts and measures** — `accounts_last_made_up_to`, `accounts_next_due`, `accounts_overdue`, `employees`, `establishment_count`

**Other detail** — `activity_section`, `bic_codes`, `certifications`, `jurisdiction`, `legal_form_code`, `registered_office_undeliverable`, `sic_codes`, `source_registry`

### Input example

```json
{
  "search_terms": ["Tesco"],
  "sources": ["uk", "france", "global"],
  "active_only": true,
  "include_details": true,
  "max_items": 50
}
```

`max_items` is a hard output ceiling, split evenly across the selected registers and search terms, so no single register can crowd out the others.

`include_details` buys the columns that only per-company endpoints publish - UK directors, previous names, accounts and confirmation-statement due dates, charges and insolvency history, and the direct and ultimate parent of an LEI row. It costs two extra requests per UK record and two per LEI record, so a detailed run takes noticeably longer. French rows carry everything in the search response and are unaffected either way.

### Output example

One UK row, with `include_details` on. Columns the register does not publish for this entity come back as `null`; the full 54 are in the dataset schema.

```json
{
  "source_registry": "companies_house",
  "jurisdiction": "GB",
  "company_name": "VODAFONE GROUP SERVICES NO.2 LIMITED",
  "previous_names": "VODAFONE GROUP SERVICES LIMITED, VODAFONE AIRTOUCH GROUP SERVICES LIMITED, RACAL TELECOM CENTRAL SERVICES LIMITED",
  "registration_number": "02370135",
  "status": "active",
  "company_type": "ltd",
  "legal_form_code": "ltd",
  "incorporation_date": "1989-04-05",
  "dissolution_date": null,
  "address": "Vodafone House, The Connection",
  "city": "Newbury",
  "postal_code": "RG14 2FN",
  "country": "United Kingdom",
  "region": "Berkshire",
  "sic_codes": "69102, 69201, 78200, 82990",
  "officers": "VODAFONE CORPORATE SECRETARIES LIMITED (corporate-secretary), GOSTOVIC, Stevan (director), PRETORIUS, Sugnet (director), RAGGETT, Andrew Thurston (director)",
  "officer_count": 4,
  "accounts_next_due": "2026-12-31",
  "accounts_last_made_up_to": "2025-03-31",
  "accounts_overdue": false,
  "confirmation_statement_next_due": "2027-03-13",
  "has_charges": false,
  "has_insolvency_history": false,
  "registered_office_undeliverable": false,
  "url": "https://find-and-update.company-information.service.gov.uk/company/02370135"
}
```

A French row instead fills `trade_name`, `latitude` / `longitude`, `establishment_number` (SIRET), `activity_section`, `size_category`, `establishment_count`, `revenue`, `net_income`, `financials_year`, `vat_number` and `certifications`; a GLEIF row fills `lei`, `bic_codes`, the `headquarters_*` columns, `entity_category` and, with `include_details`, `parent_name` / `ultimate_parent_name`.

Every row carries every column. A value the source does not publish is returned as `null` rather than being omitted or merged into a neighbouring field.

### Matching records across registers

GLEIF publishes each entity's number in its **own** national register, and this Actor maps it to `registration_number` - the same column the UK and French rows use. Tesco PLC is `00445790` in both the GLEIF row and the Companies House row, so joining the two sources is a straight key match rather than fuzzy name comparison.

### Common use cases

- Entity resolution across jurisdictions during vendor or counterparty onboarding
- KYC and sanctions-adjacent research where the registration number has to come from an official source
- Enriching a CRM or master-data table with registered names, numbers and addresses
- Finding the subsidiaries of a group by name stem across several countries at once

### Use with AI agents and MCP

Apify's MCP server can discover and call this Actor from an AI workflow. Example intent:

> Find active companies called Tesco in the UK, French and global registers and return their registration numbers and registered addresses.

Use the JSON from **Input example** as the tool arguments. The strict input schema rejects unsupported parameters, and the documented dataset schema tells the agent how to interpret each returned field.

### Pricing and cost control

Output is billed per result at **$0.003 per result** (about $3.00 per 1,000 results), plus a $0.0002 Actor-start charge billed once per gigabyte of memory at run start. Use `max_items` to cap both output volume and charges. The price shown on the Apify Store listing is authoritative.

`max_items` limits both output volume and result-based charges. Start with the bounded default, inspect the rows, then scale deliberately.

### Reliability

The Actor validates input, bounds pagination, and treats each register independently: a register that rate-limits, errors or returns a short page logs a warning and keeps the records it already has instead of failing the run. Records that match more than one search term are deduplicated on source and registration number. A production default-input canary is monitored by the fleet.

### Bringing your own Companies House key

The UK source works without any setup. It runs on a shared Companies House key whose quota - 600 requests per five minutes - is shared by everyone running this Actor, so a very large or time-critical UK run can hit the ceiling and stop early with a rate-limit warning in the log.

If that matters to you, register a free key at [developer.company-information.service.gov.uk](https://developer.company-information.service.gov.uk/), choose application type **REST**, and paste it into `companies_house_key`. The field is stored encrypted. Your key is then used for the whole run and only your own quota applies.

### Limitations and responsible use

- A name search returns similarly named entities. The registers match on the name as it is registered, so a trading name or a misspelling may miss.
- Coverage is what each register publishes. A company that exists but has no LEI has no GLEIF row; a UK company dissolved decades ago may predate the digital record.
- `active_only` is applied by the source where the source supports it. Turn it off to include dissolved and ceased entities.
- SIC codes are present on roughly two of every three Companies House records; French legal form is returned as the INSEE *catégorie juridique* code.
- This tool supplies public reference data, not a KYC decision.

Source licences: Companies House data is published under the Open Government Licence v3.0, SIRENE under Licence Ouverte 2.0, and the GLEIF register under CC0. Use the data lawfully, respect the source terms, and independently validate records before making consequential decisions.

### FAQ

#### What does `include_details` actually add?

UK directors and previous names, accounts and confirmation-statement due dates, registered charges, insolvency history and whether the registered office is undeliverable; and for LEI rows, the direct and ultimate parent. None of that is in the search responses, so it costs two extra requests per UK record and two per LEI record. Leave it off for a fast name-and-address lookup.

#### Does it need my own API key?

No. All three registers work out of the box. A Companies House key of your own is optional and only affects which rate-limit quota the UK source draws on.

#### Why do some rows have an LEI and others do not?

Only the GLEIF register issues LEIs, and only entities that have registered for one appear there. UK and French rows carry an LEI only when the same company also appears in GLEIF.

#### Can I search several company names in one run?

Yes. `search_terms` takes up to 25 names, and every name is searched in every selected register. Records that match more than one term are returned once.

#### Can I export the results?

Yes. Download the default dataset as JSON, CSV, Excel, or XML, or retrieve it through the Apify API.

#### How do I control cost?

Set `max_items` to the most records you want returned, and narrow `sources` to the registers you actually need.

#### Can an AI agent call it?

Yes. The Actor has strict input and semantic output schemas and can be called through Apify's MCP tooling.

#### What happens when one register is down?

The run continues. A failing register logs a warning and contributes no rows; the others still return their records.

# Actor input Schema

## `search_terms` (type: `array`):

One or more full or partial company names. Each name is searched in every selected registry.

## `sources` (type: `array`):

Which official registers to search. All three work without any setup of your own; deselect the ones you do not need to cut run time and cost.

## `companies_house_key` (type: `string`):

Leave blank to use the shared key, whose 600-requests-per-5-minutes quota is shared by everyone running this Actor. For large or time-critical UK runs, get a free key of your own at developer.company-information.service.gov.uk and paste it here.

## `include_details` (type: `boolean`):

Add the columns that only per-company endpoints publish: UK accounts and confirmation-statement due dates, mortgage charges, insolvency history, previous names and current directors, plus direct and ultimate parent for LEI rows. Costs two extra requests per UK record and two per LEI record, so runs take noticeably longer. France needs no extra requests and is unaffected.

## `active_only` (type: `boolean`):

Skip dissolved, ceased and lapsed entities. Turn off to include them.

## `max_items` (type: `integer`):

Hard cap on records returned, split evenly across registries and search terms. Also caps your spend.

## Actor input object example

```json
{
  "search_terms": [
    "Tesco"
  ],
  "sources": [
    "uk",
    "france",
    "global"
  ],
  "include_details": false,
  "active_only": true,
  "max_items": 50
}
```

# Actor output Schema

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

One flat record per company, same columns whichever registry it came from.

# 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 = {
    "search_terms": [
        "Tesco"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("captainhandsome/company-registry-search").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 = { "search_terms": ["Tesco"] }

# Run the Actor and wait for it to finish
run = client.actor("captainhandsome/company-registry-search").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 '{
  "search_terms": [
    "Tesco"
  ]
}' |
apify call captainhandsome/company-registry-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,captainhandsome/company-registry-search"
        }
    }
}
```

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/8EoBRYyZGgiG3IxMT/builds/ZwOJleYRkw0kJwbQe/openapi.json
