UK Companies House Scraper
Pricing
from $1.79 / 1,000 results
UK Companies House Scraper
Extract UK Companies House company data by name search, company number or profile URL: name, number, status, type, incorporation date, registered address, SIC codes, previous names and officers with roles and appointment dates. Filter by status or SIC. No login.
Pricing
from $1.79 / 1,000 results
Rating
0.0
(0)
Developer
Axiom Works
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Returns: one row per company with companyName, companyNumber, status, type, incorporatedOn, registeredAddress, sicCodes, officers, previousNames, and sourceUrl.
Input: {"searchQueries":["tesco"],"maxItems":5}
Best for: company verification, targeted company lists, and checking historical registered names.
{"id":"00445790","companyName":"TESCO PLC","companyNumber":"00445790","status":"Active","type":"Public limited Company","incorporatedOn":"27 November 1947","incorporatedOnIso":"1947-11-27","registeredAddress":"Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA","sicCodes":["47110 - Retail sale in non-specialised stores with food, beverages or tobacco predominating"],"officers":[{"name":"TAYLOR, Christopher Jon","role":"Secretary","status":"Active","appointedOn":"14 April 2025","appointedOnIso":"2025-04-14"}],"officerCount":74,"previousNames":[{"name":"TESCO STORES (HOLDINGS) LIMITED","period":"27 Nov 1947 - 14 Dec 1981"}],"sourceUrl":"https://find-and-update.company-information.service.gov.uk/company/00445790"}
Collect public UK company search results and company profiles from the Companies House Find and Update service. Supply company name searches, exact company numbers, or both. Each result represents one company, identified by its Companies House number. The Actor can also collect the public officer appointment list linked from each profile. It uses the public website and does not require a Companies House login.
What does UK Companies House Scraper do?
UK Companies House Scraper searches the public company register by keyword or opens known company numbers directly. It reads the company overview page for the registered name, company number, current status, legal type, incorporation date, registered office address, and SIC descriptions. When officer collection is enabled, it visits the officers tab and follows its page links until the available appointment pages have been read. It returns a structured company record in the run's default dataset.
A name search can match the current name or a previous name. The Actor returns the current registered name from the company profile, so a match may not contain the keyword you searched. This distinction matters when reviewing historical names or checking whether a company changed its name. A company number is a more precise input because the number is the stable register identifier. If both input lists are supplied, exact company numbers are processed first, then search results.
The Actor reads public website pages without a login and is not affiliated with Companies House. Each record includes its profile URL. Register content changes over time, so later runs may show new details.
What data can you get?
| Field | Meaning |
|---|---|
id | Stable company number used as the record identifier. |
companyName | Current registered company name on the profile. |
companyNumber | Companies House number, including leading zeroes or letter prefixes. |
status | Status shown on the company overview, such as Active or Dissolved. |
type | Company type as shown on the overview, when available. |
incorporatedOn | Human-readable incorporation date from the overview, when available. |
incorporatedOnIso | The same date in YYYY-MM-DD format when it can be parsed. |
registeredAddress | Registered office address shown on the overview, when available. |
sicCodes | SIC activity code descriptions listed on the overview. |
pscs | Persons with significant control (name, status, notified and ceased dates, nature of control), only when includePscs is true. |
pscCount | Active PSC count reported by the register, only when includePscs is true. |
officers | Public officer appointment entries when includeOfficers is true. |
officerCount | Number of officer appointments reported on the officers page, when collected. |
previousNames | Earlier registered names with the displayed period plus ISO from and to dates. |
nextAccountsMadeUpTo | Period end date of the next accounts, ISO date. |
nextAccountsDueBy | Filing deadline for the next accounts, ISO date. |
lastAccountsMadeUpTo | Period end date of the last filed accounts, ISO date. |
nextConfirmationStatementDate | Next confirmation statement date, ISO date. |
confirmationStatementDueBy | Filing deadline for the next confirmation statement, ISO date. |
lastConfirmationStatementDate | Date of the last confirmation statement, ISO date. |
dissolvedOn | Dissolution date for dissolved companies, ISO date; null otherwise. |
correspondenceAddress, overseasAddress | Overseas entities only: UK correspondence address and the address in the place of incorporation; null for other company types. |
incorporatedIn, registrationNumber, legalForm, parentRegistry | Overseas companies and entities only: home country, home registry number (null when the register shows N/A), legal form and parent registry; null otherwise. |
sourceUrl | URL of the company profile that supplied the record. |
Each officer entry can include a name, role, status, appointment date, resignation date, nationality, month and year of birth, and country of residence. Some values are absent from the public page, so those properties can be null. Officer entries are nested inside the parent company record. The run's item limit counts companies, not the number of officers contained in a company. When officer collection is disabled, officers is an empty array and officerCount is null.
Some company types do not publish every field. For example, a branch entry can have an address and status while lacking an incorporation date or SIC codes. In those cases, optional text fields are null and sicCodes is an empty array. The Actor does not invent values to fill gaps. sourceUrl and id remain available for every returned company.
How to use
Open the Actor input form and enter search terms in searchQueries, exact eight-character identifiers in companyNumbers, or public profile links in companyUrls. Set maxItems to the maximum number of company records needed. Leave includeOfficers enabled if appointments are part of your workflow. Run the Actor and read the resulting dataset. The dataset can be downloaded in the formats offered by Apify or accessed through the API.
For an exploratory search, start with a short, distinctive company name and a small item limit. Search results can include current names and matches on historical names, so inspect companyName and companyNumber before treating a result as the organization you intended. If you already know the number, use companyNumbers to avoid ambiguity. Multiple searches can find the same company; the Actor keeps one record per company number within a run.
The scraper makes sequential requests at least one second apart. It applies status and SIC filters before fetching officers, avoiding officer-page requests for excluded companies. Officer pagination can extend a run. The run stops at maxItems. Empty searches return zero items with a warning. Missing profiles are skipped, never inserted as error records.
Input
| Field | Type | Default | How to use it |
|---|---|---|---|
searchQueries | Array of strings | Empty | Company names or keywords to search. Supply this or companyNumbers. |
companyNumbers | Array of strings | Empty | Exact eight-character Companies House numbers. Supply this or searchQueries. |
companyUrls | Array of strings | Empty | Public Companies House company profile URLs; can be mixed with numbers and searches. |
statuses | Array of strings | Empty | Keep profiles with an exact status match, ignoring case. |
sicCodePrefixes | Array of strings | Empty | Keep profiles with a SIC code starting with any supplied numeric prefix. |
includeOfficers | Boolean | true | Read every available public officers page for each company. |
includePscs | Boolean | false | Also read the persons-with-significant-control pages and add pscs and pscCount to each company. |
maxItems | Integer | 50 | Maximum company records to return, from 1 to 10000. |
proxyConfiguration | Proxy settings | Proxy off | Configure Apify Proxy for site requests. The Actor also attempts a proxy fallback after a block response. |
The console prefill shows tesco as an example search and a small item limit. Prefill values help demonstrate the form; API callers should supply their own search terms, numbers, or URLs. At least one target list must have a nonempty value. Company numbers must have eight letters or digits. Leading zeroes matter, so pass identifiers as strings rather than JSON numbers. Filters apply to both direct lookups and search results; an empty filter includes all values.
{"searchQueries": ["tesco"],"includeOfficers": true,"maxItems": 5,"proxyConfiguration": { "useApifyProxy": false }}
To retrieve known companies, replace searchQueries with companyNumbers, for example "companyNumbers": ["00445790", "09384423"]. You can provide both lists in one run. Exact numbers are handled first, while duplicates found later in search results are ignored. A small maxItems can therefore fill entirely from the exact number list.
You may also paste a profile link in companyUrls. For an active retail list, use "statuses": ["Active"] and "sicCodePrefixes": ["47"] with a relevant search term. The Actor checks these filters against the profile it actually opens. It reads subsequent search pages until it has enough matching companies, finds no new results, or reaches the page guard. Each accepted company still uses one dataset row.
Output
The following example is based on a public profile observed during development. Register details can change, and a fresh run may return different officer entries. The shortened officers array illustrates the nested shape; the Actor returns all parsed entries from available officer pages when enabled.
{"id": "00445790","companyName": "TESCO PLC","companyNumber": "00445790","status": "Active","type": "Public limited Company","incorporatedOn": "27 November 1947","incorporatedOnIso": "1947-11-27","registeredAddress": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA","sicCodes": ["47110 - Retail sale in non-specialised stores with food, beverages or tobacco predominating"],"officers": [{"name": "TAYLOR, Christopher Jon","role": "Secretary","status": "Active","appointedOn": "14 April 2025","resignedOn": null,"nationality": null,"dateOfBirth": null,"countryOfResidence": null}],"officerCount": 74,"previousNames": [{"name": "TESCO STORES (HOLDINGS) LIMITED", "period": "27 Nov 1947 - 14 Dec 1981", "from": "1947-11-27", "to": "1981-12-14"}],"sourceUrl": "https://find-and-update.company-information.service.gov.uk/company/00445790"}
A company number provides a stable record key across runs. The id and companyNumber fields are intentionally equal. The company profile is the source for top-level details, and the linked officers pages supply the nested appointments. officerCount reflects the count displayed by the officers page, while the officers array contains the appointment entries parsed from its available pages. These values can differ if the site changes while a run is in progress.
For verification workflows, an advanced hidden input named __verifySnapshots can save source text for the first ten returned records under the SNAPSHOTS key in the default key-value store. It is intended for checking extracted fields against the public pages. Ordinary users can rely on the record's sourceUrl and need not enable snapshots.
How much does it cost?
This Actor is charged per result added to the dataset. A company that appears in more than one search is pushed once, so duplicates within a run do not create additional result events. maxItems is the upper bound on company result events for a run. A run with no matching companies pushes no result records. For the current charging details, see the Actor's Pricing tab on Apify. The Pricing tab is the source for current terms because they can change.
The includeOfficers setting affects how many public pages the Actor visits, but officer entries are part of a company result rather than separate dataset rows. An officer list with many pages can increase run duration. Set the item limit to the number of company profiles you actually need and disable officer collection when your work only needs profile facts.
Use with AI agents (MCP)
Apify's MCP server can expose this Actor as a tool to an AI agent. Configure a server with the Actor's Store path in the tools parameter:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?tools=axiomworks/uk-companies-house-scraper"}}}
An agent can then run a company name search and inspect the structured output. Give the agent an exact company number when you have one, and ask it to cite sourceUrl when using the result in a report. Useful prompts include “Find up to five companies matching Tesco and show their company numbers and statuses” and “Retrieve company 00445790 with officers and summarize the registered address and SIC description.” The agent should treat a name search as candidate discovery, since matches on previous names may have a different current name.
The first input fields are the search targets, followed by the options agents most often need. The descriptions explain what values to provide and the item limit. An agent calling the Actor through an API must pass at least one target list; console prefill examples are not automatically submitted by every integration. A result is evidence from the public page at run time, not a permanent statement about the company.
Integrations and API
Apify provides clients and an HTTP API for starting an Actor run and reading its dataset. Replace the example API token placeholder with a token managed by your own environment. Never put a real token into shared source code or reports. The examples below show the input shape; adapt the response handling to your application.
Python example:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("axiomworks/uk-companies-house-scraper").call(run_input={"companyNumbers": ["00445790"],"includeOfficers": True,"maxItems": 1,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["companyNumber"], item["status"], item["sourceUrl"])
JavaScript example:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('axiomworks/uk-companies-house-scraper').call({searchQueries: ['tesco'],maxItems: 5,includeOfficers: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const item of items) process.stdout.write(`${item.companyNumber}: ${item.companyName}\n`);
cURL example:
curl -X POST \'https://api.apify.com/v2/acts/axiomworks~uk-companies-house-scraper/run-sync-get-dataset-items' \-H "Authorization: Bearer $APIFY_TOKEN" \-H 'Content-Type: application/json' \--data '{"companyNumbers":["00445790"],"maxItems":1,"includeOfficers":false}'
The synchronous API route suits short requests. For larger searches, start an asynchronous run and read its dataset afterward. Join records by companyNumber, the register identifier.
FAQ
Why is a search result name different from the keyword? A search can match a previous company name. The Actor returns the current name from the profile page and keeps the stable company number as its identifier. Review the source page when the match is surprising.
Why is an incorporation date or SIC list empty? Some register entries do not expose those fields on their overview page. The Actor preserves the missing value as null or an empty array. It does not infer an incorporation date from another field.
What does maxItems count? It counts company records pushed to the dataset. It does not count search pages, officer pages, or nested officer entries. If fewer matching profiles are available, the dataset contains fewer records.
Can I search several terms at once? Yes. Supply several strings in searchQueries. The Actor processes them in order and removes companies already emitted by an earlier query or an exact number input.
Can I paste profile links? Yes. Put public company overview URLs in companyUrls. The Actor extracts the eight-character company number and rejects URLs outside the Companies House profile path.
How are filters applied? statuses matches the profile status without regard to case. sicCodePrefixes matches the start of any SIC code on the profile. If both are supplied, both must match before a company is output.
Does the Actor need a login? No. It reads public company overview and officers pages. If the site challenges or throttles a request, the Actor waits and retries. After a block response on a direct connection, it also attempts to retry through Apify Proxy when available.
Why might a run take longer with officers enabled? A single company can have several officers pages. The Actor reads the available pages sequentially at a modest request rate to avoid flooding the site.
Is it legal to scrape UK Companies House?
Companies House publishes these company and officer details on public pages. Whether a particular use is permitted depends on your purpose, jurisdiction, applicable law, and the site's current terms. Review those conditions for your own workflow, especially if you plan to republish or combine personal information about officers. The Actor only accesses pages available without a login and does not solve access challenges. It is an independent tool and is not affiliated with Companies House.
Feedback
If a field is missing or a page layout changes, provide the company number, the affected field, and the relevant run details in the Actor's Apify feedback channel. Include a public source page when possible, and avoid sharing private credentials. Concrete examples help distinguish a parser issue from an optional field that the register did not publish. If you observe a repeated company number in a dataset, or a record beyond your requested maxItems, include that run as well so the issue can be reproduced.