Companies House Company Profile Scraper avatar

Companies House Company Profile Scraper

Pricing

from $3.20 / 1,000 company profile returneds

Go to Apify Store
Companies House Company Profile Scraper

Companies House Company Profile Scraper

Extract one company profile per row from the UK's Companies House register: number, name, status, type, registered office, SIC codes, accounts and filing dates, officers and persons with significant control. Feed it company page URLs, bare company numbers or register search terms.

Pricing

from $3.20 / 1,000 company profile returneds

Rating

0.0

(0)

Developer

Pradio Actors

Pradio Actors

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

What does Companies House Company Profile Scraper do?

Companies House Company Profile Scraper reads the UK Companies House register and returns one detailed company profile per row. The profile carries the company's number, name, status, type, registered office, SIC codes, accounts and filing dates, plus its officers and persons with significant control.

Give it a company name or a trade as a search query, or paste company page URLs and bare company numbers. The register's own search and company pages are read over plain HTTP: no login, no key, no browser.

A resolved company costs $0.0032; a miss costs nothing and its row says why. On a measured run over 148 companies it had never seen, every one resolved and was charged once.

Who uses Companies House Company Profile Scraper

WhoWhat they use it for
Sales and growth teamsA prospect's legal name, registered office, SIC codes and filing dates, straight from the UK register
Onboarding and compliance teamsA counterparty's live status, officers and PSCs for KYC and due-diligence checks
Credit and risk analystsAccounts dates, overdue flags, charges and insolvency markers on the companies they score
Investigators and data teamsStructured profiles of UK companies at list scale, deduplicated on the register page

Features

  • Three ways in. startUrls takes Companies House company page URLs, /search?q= results URLs and bare company numbers; searchQueries takes register search terms such as a company name or a trade.
  • The register's own search. Queries are answered by the Companies House search itself; no external engine and no key is involved. Officer hits in the results are skipped: a query returns companies, not people.
  • The full register entry, not just the summary. Each resolved company's register document, officers tab and persons-with-significant-control tab are all read. A profile carries its people and its register counts, not just its summary line.
  • One profile per company, once. Rows are deduplicated on the register page URL before anything is written or charged. A profile is written to the dataset first and billed second.
  • Bounded and polite. Reads go one at a time with a pause between them. A refused read backs off; if the refusal holds, the run fails rather than push past a block.
  • Proxy support. proxyConfiguration sends every register read through your Apify proxy setup.
  • A verdict on every entry. A number the register has no company under comes back not_found. A pasted link off the register's host comes back bad_url. Neither is charged.

What you can count on

  • You pay only for profiles whose row_status reads ok. An entry the run cannot answer is pushed as an uncharged ITEM_STATUS row that names it and says why.
  • Every profile is charged only after it is written to your dataset; a row you cannot see is never billed.
  • A run that finds nothing returns one PROFILE_NOT_FOUND row that says so, never an empty dataset.
  • A spending limit stops the run cleanly, with a STOPPED_EARLY row saying how many profiles were returned and how many were not.
  • Every run writes a RUN_SUMMARY entry with rowsFetched, rowsPushed, rowsCharged, rowsUncharged, duplicatesDropped and stoppedEarly, so a short run and a broken one are told apart.
  • If the register changes what it answers, the run fails with the error in the log. It never returns rows full of nulls and calls it a success.
  • No register value is invented: a field the register does not show is null, and the fields that can stay empty are named under Limits. The few computed fields (lead_score, the *_count rollups and the *_on_register counters) are derived from the register's own fields and say so in the field table.

Why this one

The most-used alternative on this platform was run against the same 20-company search on 2026-09-20, with its officer and PSC options switched on.

  • Its person fields came back empty. All 20 of its rows left every officer-level field it declares empty: names, roles, appointment and resignation dates, dates of birth, nationalities, occupations, service addresses. A profile from this Actor carries the officers and PSCs the register lists.
  • Lower price. The most-used alternative on this platform charges $0.004 a profile; this Actor charges $0.0032, a fifth less per row.
  • It resolves what it has never seen. On a separate measured run over 148 UK company numbers taken from an external list, this Actor resolved all 148, each charged once.
  • A miss costs nothing and says why. An entry the register cannot answer comes back as an uncharged row naming it, with not_found, bad_url or bad_input as the verdict.
  • The source URL is on every row. pageUrl points back to the register page each profile was read from, so any value can be checked at the source.

What data does Companies House Company Profile Scraper return?

One profile per resolved company, written to the dataset as the run goes. A data row carries 38 fields. This is a real row from a live run, with the officers list left out for length:

{
"company_name": "GREEN ENERGY LIMITED",
"pageUrl": "https://find-and-update.company-information.service.gov.uk/company/07109264",
"entry_type": "company",
"company_number": "07109264",
"company_status": "Active",
"company_type": "Private Limited Company",
"registered_office_address": "BLACK SWAN HOUSE, 23 BALDOCK STREET, WARE, HERTFORDSHIRE, SG12 9DH",
"incorporated_on": "2009-12-21",
"sic_codes": [
{ "code": "35130", "description": "Distribution of electricity" },
{ "code": "35140", "description": "Trade of electricity" }
],
"next_accounts_made_up_to": "2026-04-30",
"next_accounts_due_by": "2027-01-31",
"last_accounts_made_up_to": "2025-04-30",
"accounts_overdue": false,
"accounts_summary": "Accounts: next accounts made up to 2026-04-30 due by 2027-01-31; last accounts made up to 2025-04-30",
"confirmation_statement_next_date": "2026-12-19",
"confirmation_statement_due_by": "2027-01-02",
"confirmation_statement_last_date": "2025-12-19",
"confirmation_statement_overdue": false,
"pscs": [
{
"name": "Green Energy (Uk) Plc",
"kind": "corporate-entity",
"status": "Active",
"notified_on": "2016-07-01",
"ceased_on": null,
"natures_of_control": [
"Ownership of shares – 75% or more",
"Ownership of voting rights - 75% or more",
"Right to appoint or remove directors"
],
"date_of_birth": null,
"nationality": null,
"country_of_residence": null,
"correspondence_address": "Black Swan House, 23 Baldock Street, Ware, England, SG12 9DH"
}
],
"listing_address": "Black Swan House, 23 Baldock Street, Ware, Hertfordshire, SG12 9DH",
"search_query": "green energy",
"source": "search",
"has_charges": false,
"has_insolvency_history": false,
"officers_on_register": 9,
"resignations_on_register": 6,
"psc_statements_on_register": 0,
"is_active": true,
"officers_count": 9,
"active_officers_count": 3,
"resigned_officers_count": 6,
"directors_count": 2,
"psc_count": 1,
"sic_code_list": ["35130", "35140"],
"row_status": "ok",
"lead_score": 100,
"row_type": "ROW"
}

Each officers entry carries name, role, status, appointed and resigned dates, nationality, occupation and country of residence. It also carries month and year of birth and correspondence_address, the service address the register publishes. Every field the schema declares:

FieldWhat it carries
company_nameThe registered company name, read from the register's company document or the search listing.
pageUrlThe URL of the company's overview page on the register; also the run's deduplication key.
entry_typeThe register entry kind; company on every profile this source returns.
company_numberThe Companies House company number the profile was resolved under.
company_statusThe register's live status for the company, such as Active or Dissolved.
company_typeThe register's company category, such as Private Limited Company.
registered_office_addressThe registered office address as the register prints it, in one line.
incorporated_onThe incorporation date, ISO YYYY-MM-DD.
sic_codesThe company's filed SIC codes, each as a code and its description.
next_accounts_made_up_toThe period end the next accounts cover, from the register's accounts block.
next_accounts_due_byThe due date the register prints for the next accounts, ISO.
last_accounts_made_up_toThe made-up-to date of the last filed accounts, ISO.
accounts_overduetrue when the register marks the accounts overdue or the due date has passed; null where the register shows no accounts block.
accounts_summaryThe accounts dates joined into one line, as the company page prints them.
confirmation_statement_next_dateThe date the next confirmation statement covers, from the register's confirmation block.
confirmation_statement_due_byThe due date the register prints for the next confirmation statement, ISO.
confirmation_statement_last_dateThe last confirmation statement's made-up-to date, ISO.
confirmation_statement_overduetrue when the register marks the statement overdue or its due date has passed; null where the register shows no confirmation block.
officersThe officers tab's appointments, each with name, role, status, dates and the identity fields the register prints. null when none are listed.
pscsThe PSC tab's entries, each with name, kind, status, dates and natures of control. null where the register shows an exemption statement instead.
listing_addressThe address the search listing printed; filled only on rows found through a search.
search_queryThe query the company was found under; filled only on rows found through searchQueries or a pasted /search?q= URL.
sourceHow the company was reached: search for a query hit, url for a pasted page or number.
has_chargestrue when the register's document for the company carries mortgage charges.
has_insolvency_historytrue when the register shows an insolvency marker or an insolvency status word.
officers_on_registerHow many officer appointments the register lists for the company.
resignations_on_registerHow many of those appointments have ended, per the officers tab.
psc_statements_on_registerHow many PSC statements the register shows, including an exemption statement filed instead of a PSC list.
is_activetrue when the register's status for the company is Active; null where it shows no status.
officers_countThe number of entries in this profile's officers list.
active_officers_countOfficers with no resignation on the register.
resigned_officers_countOfficers whose appointment has ended.
directors_countActive officers whose role is a director role.
psc_countThe number of entries in this profile's pscs list.
sic_code_listThe SIC code strings alone, for filtering or joining.
lead_scoreA 0-100 rollup of the register's own signals: active status, filings current, officers and PSCs listed, SIC classified.
row_statusThe row's own verdict: ok on a profile; on an ITEM_STATUS row, the miss verdict the source returned (not_found, bad_url, bad_input).
row_typeROW on a profile; ITEM_STATUS on an uncharged per-entry miss; PROFILE_NOT_FOUND when the register answered with nothing; STOPPED_EARLY when a charge limit ended the run.
reasonStatus rows only: why the run returned no profiles, or why it stopped early.
rowsFetchedStatus rows only: how many rows the source produced before de-duplication and the cap.
rowsReturnedStatus rows only: how many profiles were written to the dataset.
rowsRemainingStatus rows only: how many fetched rows were not returned.

How much does it cost?

Each company profile written to your dataset bills one profile-returned event: $0.0032.

Profiles you ask forEvents billedCost
100up to 100$0.32
1,000up to 1,000$3.20
10,000up to 10,000$32

Not charged: ITEM_STATUS miss rows (not_found, bad_url, bad_input), the PROFILE_NOT_FOUND and STOPPED_EARLY rows, and repeats dropped before anything is written.

Apify also bills its own apify-actor-start event on every run at $0.00005 per event, one event per GB of run memory with a minimum of one. That charge is the platform's; this Actor adds nothing on top.

In the measured run every entry resolved, so a list of 100 companies cost $0.32 plus the $0.00005 start event, and 1,000 companies cost $3.20 plus the start event.

How do I use Companies House Company Profile Scraper?

  1. Open the Actor page and press Start. The input already carries a working query; there is no key and no login.
  2. Profiles land in the dataset as they are read. Export them as JSON, CSV or Excel, or pull them through the API.

The input that produced the sample row:

{
"searchQueries": ["green energy"]
}

Or point it at companies directly. startUrls accepts a company page URL, a /search?q= results URL, or a bare company number:

{
"startUrls": [
"https://find-and-update.company-information.service.gov.uk/company/07109264",
"07109264",
"https://find-and-update.company-information.service.gov.uk/search?q=green%20energy"
]
}

Through the API:

curl -X POST "https://api.apify.com/v2/acts/Pradio~companies-house/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" -H "Content-Type: application/json" -d "{\"searchQueries\":[\"green energy\"]}"

Input

InputDefaultWhat it does
startUrlsemptyCompanies House company page URLs, /search?q= results URLs or bare company numbers; every company they resolve to is read once.
searchQueries["green energy"]Terms run through the register's own search; each company hit joins the lookup queue under the per-query cap.
proxyConfigurationnoneSends every register read through your Apify proxy setup.
maxItemsnoneThe most rows one run returns; leave it unset for no cap.
maxCompaniesPerSearchQuerymaxItems, else 20The most companies one search query may add to a run.

startUrls

Three shapes work here: a company page URL copied from the register, a /search?q= results URL, or a bare company number such as 07109264. A URL from any other host, or a string that is none of these, comes back as an uncharged bad_url row naming the entry. A typo does not stop the run.

searchQueries

Each entry is run through the register's own search and its company hits are resolved in order; officer hits are skipped. One query reads at most 50 pages of results. maxCompaniesPerSearchQuery bounds how many hits one query may add: unset, it falls back to maxItems, or 20 when that is unset too.

maxItems and maxCompaniesPerSearchQuery

maxItems caps the whole run's output. maxCompaniesPerSearchQuery caps what a single query may contribute, so one broad term cannot spend the whole budget. The cap counts profiles and miss rows alike. A run that reaches your Apify spending limit stops cleanly with a STOPPED_EARLY row instead of charging past it.

proxyConfiguration

Optional. When set, every register read goes through the configured Apify proxy, which is worth doing if a run meets a refusal on a shared address.

Output

A run writes data rows with row_type: "ROW" and, when something needs saying, status rows. Everything lands in the default dataset.

  • ROW: a resolved company profile, charged after it is written.
  • ITEM_STATUS: a per-entry miss, pushed so the miss is visible. A company number the register does not know comes back not_found; an unusable entry bad_url; a run with no usable input bad_input. Never charged.
  • PROFILE_NOT_FOUND: the register answered and produced no company hits. One row, never charged, and reason says why.
  • STOPPED_EARLY: the charge limit ended the run. One row, never charged, carrying rowsReturned and rowsRemaining.

An empty result is an answer, not a failure: the run writes one PROFILE_NOT_FOUND row and charges nothing, rather than leaving an empty dataset.

RUN_SUMMARY in the default key-value store carries rowsFetched, rowsPushed, rowsCharged, rowsUncharged, duplicatesDropped and stoppedEarly for every run.

What can you do with the data?

  • A sales team searches a trade such as "green energy" and gets UK companies with offices, SIC codes and filing dates for a prospect list.
  • An onboarding analyst pastes a supplier's company number; the profile returns its live status, officers and PSCs for the KYC file.
  • A credit analyst filters on accounts_overdue and has_insolvency_history, and reads the register's officer and PSC counts without opening each company page.
  • A data team pulls profiles for a whole sector and joins on company_number or sic_code_list.

Use Companies House Company Profile Scraper with AI agents

Add this Actor to an MCP-capable client:

claude mcp add --transport http apify "https://mcp.apify.com?tools=Pradio/companies-house"

The agent can then read the input schema, start runs and pull the dataset on its own.

Personal data

Some rows name people. officers and pscs carry what Companies House publishes for inspection under the Companies Act 2006. An officer's or PSC's entry may carry a name, a service or correspondence address, month and year of birth, nationality, occupation and role. The purpose this serves is company research, due diligence and compliance on UK companies.

  • Only what the register publishes. No usual residential addresses, no day of birth (the register itself withholds it), and nothing enriched from other sources. Rows carry structured register fields only: no filed documents, no accounts text, no document images.
  • Transparency. Every profile's pageUrl points back to the register page it was read from, so any value can be checked at the source.
  • Controller and contact. Companies House controls the register's own publication; for the rows you export, you are the controller. Questions go through this Actor's Issues tab on the Apify Store.
  • Deletion. A person named in a row can ask for deletion or correction through the same Issues tab, and the request is honoured. Companies House also runs its own protection process for the register itself.
  • Reuse. Companies House material is reused under the Open Government Licence. Its one condition is credit: "Contains public sector information licensed under the Open Government Licence v3.0." Crown insignia are not reproduced.

Release notes

  • 0.1, 2026-09-20: first public release. One company profile per row from the UK Companies House register: number, name, status, type, registered office, SIC codes, accounts and filing dates, officers and persons with significant control. Search terms, company page URLs or bare company numbers in; a miss costs nothing and says why.

Limits

  • It reads the Companies House register only. A URL pasted from another host comes back as an uncharged bad_url row naming it.
  • One profile per company. The register's filed documents, accounts text and document images are never returned; rows carry structured register fields only.
  • search_query and listing_address are filled only on rows found through a search; a direct lookup has no query to echo and no listing to quote.
  • pscs is null where the register shows an exemption statement instead of a PSC list, which is most large listed companies. Those statements are counted in psc_statements_on_register. In the measured 148-company run, 63 profiles carried a PSC list.
  • accounts_overdue and confirmation_statement_overdue are null where the register shows no accounts or confirmation block; is_active is null where it shows no status.
  • Officer and PSC birth dates are month and year only; the register withholds the day, and it does not publish usual residential addresses at all.
  • Reads are sequential with a pause between them, so a large run takes a while. One query reads at most 50 search pages; a longer result list is cut there, and maxItems caps the whole run.
  • A refused or changed page fails the run with the error in the log rather than returning rows of nulls; wait and re-run, or set proxyConfiguration.
  • For bulk copies of the whole register, Companies House's own free bulk data products are the right source; this Actor is for looking companies up.

Troubleshooting

The run returned fewer profiles than I expected. maxItems caps the whole run and maxCompaniesPerSearchQuery caps one query, and the register's own list may end first. RUN_SUMMARY says which: rowsFetched against rowsPushed, with duplicatesDropped for repeats.

I got one PROFILE_NOT_FOUND row and nothing else. The register answered and no company hits matched: that is the answer, not an error, and it is not charged. Check the query's spelling, or try the register's own search page to see what it returns for the same term.

A company number came back not_found. The register has no company under that number; the row is not charged. Check the number on the register's own site.

The run failed with a refusal error. Companies House declined a read and the run stopped rather than scrape through a block. Wait and re-run, or set proxyConfiguration to send reads through your proxy.

pscs is null on a large listed company. The register shows an exemption statement there instead of a PSC list; the statement is counted in psc_statements_on_register. It is the register's answer, not a defect.

Something still off? Open an issue on this Actor's Issues tab on the Apify Store.

FAQ

Can I use integrations with Companies House Company Profile Scraper? Yes. The dataset plugs into Apify integrations such as Make, Zapier and webhooks, and the API or an Apify schedule can run it on a loop.

Can I use Companies House Company Profile Scraper with the Apify API? Yes. The curl line under "How do I use" is a working call; swap in your token and your input.

Can I use Companies House Company Profile Scraper through an MCP server? Yes. The command under the AI agents heading adds it to an MCP client. An agent can then call it like any other tool.

What do duplicates and misses cost? Nothing. Say a query lists 50 company hits and three of them name companies another entry already gave. The run writes 47 profiles and charges 47 events; the repeats are dropped before anything is written. Every miss is an uncharged status row.

Is it legal to scrape Companies House? The register is public and published under the Companies Act 2006 for inspection. This Actor reads the same public pages a browser shows, one at a time and inside the register's published limits, and returns structured fields only. For the people named in rows, see the Personal data section; for bulk copies, use Companies House's free bulk data products.

See also

From the same publisher:

Not affiliated

This Actor is not affiliated with, associated with, endorsed by or sponsored by Companies House or the UK government. It reads public pages of the UK company register and returns what they show.