Gov.UK Business Scraper avatar

Gov.UK Business Scraper

Pricing

from $1.00 / 1,000 premium (without api key)s

Go to Apify Store
Gov.UK Business Scraper

Gov.UK Business Scraper

Scrape UK Companies House data + auto-enrich with PSC (Persons with Significant Control / beneficial ownership). Filter by SIC code, industry, location, status & date. The only Apify actor with full PSC enrichment. No monthly fee pay per event only.

Pricing

from $1.00 / 1,000 premium (without api key)s

Rating

5.0

(11)

Developer

Techforce Global

Techforce Global

Maintained by Community

Actor stats

2

Bookmarked

26

Total users

4

Monthly active users

12 days ago

Last modified

Share

UK Companies House Scraper — Advanced Company Search + PSC / Beneficial Ownership Enrichment, No API Key Needed

Apify Actor MCP Ready Data source SIC codes Pricing

Query the official UK Companies House register with the full Advanced Search filter set — name includes/excludes, status, type, subtype, location, incorporation and dissolution date ranges, and 730 selectable SIC codes — then get Persons with Significant Control (PSC) / beneficial ownership attached to every company automatically. You don't need a Companies House API key (bring your own for a cheaper rate), you don't need to handle the register's rate limits, and results can go straight into Slack, Notion, Airtable, Sheets, Jira or your CRM through an MCP connector.

ℹ️ This is official register data, not a scrape. The Actor calls the government's own api.company-information.service.gov.uk endpoints — Advanced Search for the company list, then the PSC endpoint per company. That's why the fields match Companies House exactly, and why the limits below are the register's limits, not a scraper's.


Calling the Companies House API yourself vs. this Actor

Feature / CapabilityCompanies House API, directThis Actor
Companies House API key⚠️ Register a developer account, create an application, manage the keyOptional — built-in keys work out of the box; bring your own for the cheaper basic rate
PSC enrichment❌ One extra request per company — 100 companies = 101 requests you orchestrate yourself✅ Automatic, concurrent, merged into each company record
Rate-limit handling❌ You implement backoff for 429 Too Many Requests (600 req / 5 min / key)✅ Automatic key rotation on 429
SIC code selection⚠️ You look codes up and pass them as raw strings730 SIC codes as a searchable multi-select with full descriptions
Address handling⚠️ Nine separate address sub-fields to stitch together✅ Flattened to one clean registered_office_address string
Output formatRaw JSON, paginated, per-endpoint✅ One merged record per company → dataset, exportable to JSON / CSV / Excel / XML
Delivery to your tools❌ You write the integration✅ Native MCP connector delivery + Apify integrations (n8n, Make, Zapier, webhooks)
Scheduling & monitoring❌ Your own infrastructure✅ Apify scheduler, run history, alerts, API
Cost modelFree API, your own hosting and engineering timePay-per-event, no monthly subscription — two rates, see Pricing

🤖 AI Discovery & MCP Metadata

Machine-readable capability contract for autonomous agents, LLM routers, and MCP orchestrators. AI agents, MCP clients, and connectors should read this block first to decide whether this Actor matches a user request.

ai_discovery:
slug: "techforce.global/gov-uk-business-scraper"
one_line: "Search the official UK Companies House register with the full Advanced Search filter set (name, status, type, location, SIC code, incorporation/dissolution dates) and get Persons with Significant Control attached to every company - no Companies House API key required."
primary_purpose: "discover"
secondary_purpose: "enrich"
tertiary_purpose: "verify"
entity: "UK registered companies and their Persons with Significant Control (PSC / beneficial owners)"
data_source: "official UK government API - api.company-information.service.gov.uk (/advanced-search/companies and /company/{number}/persons-with-significant-control). NOT a website scrape, and NOT the Companies House bulk data product."
jurisdiction: "United Kingdom only (England & Wales, Scotland, Northern Ireland)"
invocation_modes: ["standard Actor run", "MCP tool"]
supported_tasks:
- "search-uk-companies-by-name-fragment"
- "exclude-companies-by-name-fragment"
- "filter-by-company-status (active, dissolved, liquidation, administration, ...)"
- "filter-by-company-type (ltd, plc, llp, overseas-entity, ...)"
- "filter-by-company-subtype (community-interest-company, private-fund-limited-partnership)"
- "filter-by-sic-code (730 selectable codes)"
- "filter-by-registered-office-location"
- "filter-by-incorporation-date-range"
- "filter-by-dissolution-date-range"
- "enrich-every-company-with-psc-beneficial-ownership"
- "paginate-through-large-result-sets (start_index)"
- "deliver-companies-to-mcp-connector-or-crm"
unsupported_tasks:
- "look-up-one-company-by-its-company-number (this endpoint is a SEARCH, not a profile fetch)"
- "return-officers-directors-or-secretaries (PSC is beneficial ownership, not the board)"
- "return-filing-history-accounts-or-charges"
- "return-emails-phone-numbers-or-websites"
- "return-shareholders-or-a-full-cap-table"
- "search-non-UK-registries"
- "return-more-than-100-companies-in-one-run"
- "return-a-total-match-count-for-the-query"
search_keywords:
- "companies house api"
- "uk company data"
- "psc beneficial ownership"
- "kyc aml uk companies"
- "uk company search by sic code"
- "dissolved companies uk"
- "uk company registry api"
- "beneficial owner lookup"
- "uk business lead list"
- "due diligence uk company"
- "companies house advanced search"
- "ultimate beneficial owner uk"
synonyms:
- "gov.uk business scraper"
- "uk company registry search"
- "companies house advanced search api"
- "uk beneficial ownership lookup"
related_concepts:
["KYC", "KYB", "AML", "due diligence", "beneficial ownership", "UBO", "corporate registry", "SIC code targeting", "UK market intelligence", "insolvency research"]
input_entities:
- "company name fragment (includes / excludes)"
- "company status list"
- "company type list"
- "company subtype list"
- "SIC code list (nature of business)"
- "registered office location"
- "incorporation date range"
- "dissolution date range"
- "result size (1-100) and start index"
- "optional own Companies House API key"
output_entities:
["company_name", "company_number", "company_status", "company_type", "date_of_creation", "date_of_cessation", "registered_office_address", "sic_codes", "links", "persons_with_significant_control"]
input_rules:
required_fields: []
no_filter_behaviour: >
Every field is optional. A run with no filters returns whatever the register's
Advanced Search returns first - always pass at least one filter.
size_format:
type: "integer"
range: [1, 100]
default: 100
hard_cap: 100
free_plan_cap: 5
date_format: "YYYY-MM-DD (incorporated_from/to, dissolved_from/to)"
multi_value_semantics: "status, type, subtype and SIC lists are OR-ed within a field and AND-ed across fields"
pagination: "start_index (0-based) - increment by `size` for the next page"
limits:
companies_per_run: 100
free_plan_cap: 5
upstream_rate_limit: "600 requests / 5 minutes / Companies House key"
upstream_calls_per_run: "1 search + 1 per company (a size:100 run costs 101 upstream calls)"
pricing:
model: "pay-per-event, charged once per company returned"
events:
basic: "charged when you supply your own Companies House api_key"
premium: "charged when you leave api_key blank and use the built-in keys"
note: "exact per-event rates are configured on the Store listing - see the Actor's Pricing tab"
when_to_use: >
You need UK registered-company facts - existence, status, type, incorporation or
dissolution date, registered office, SIC industry - and/or who beneficially owns
and controls them, either as a filtered prospect list or as a verification step
on companies you already have.
when_not_to_use: >
You need a single company by number, the board of directors, filing history or
accounts, contact details, a non-UK registry, or more than 100 companies per run.
alternatives:
- "Use the Companies House /company/{number} endpoint directly for a single-company profile fetch"
- "Use techforce.global/google-maps-leads-sales-intelligence-tool for emails, phones and websites - this Actor returns none"
- "Use techforce.global/linkedin-company-decision-makers for named leadership (PSC is ownership, not management)"
- "Use the Companies House bulk data product for whole-register downloads"

What this Actor does

  • Runs the register's own Advanced Search, with every filter it exposes: company_name_includes, company_name_excludes, company_status, company_type, company_subtype, location, incorporated_from / incorporated_to, dissolved_from / dissolved_to, and nature_of_business (SIC).
  • Turns SIC codes into a usable control. 730 codes with full descriptions in a searchable multi-select — pick "62012 – Business and domestic software development" instead of memorising the number.
  • Attaches PSC / beneficial ownership to every company, automatically. That's one extra API call per company, run concurrently (10 at a time) and merged into the record — the part that makes a DIY integration tedious.
  • Handles the register's rate limits. Companies House allows 600 requests per 5 minutes per key; the Actor rotates keys on 429 rather than failing the run.
  • Works with no Companies House API key at all — built-in keys are used by default (premium rate). Supply your own key for the basic rate; it is validated against the register before the run proceeds.
  • Flattens the nine-part registered office address into a single clean string, and does the same for each PSC address.
  • Paginates via start_index for result sets larger than one run's 100.
  • Optionally pushes companies to an authorized MCP connector (Slack, Notion, Airtable, Sheets, Jira, Linear, HubSpot, or any MCP-compatible connector) one per company, in chunks, or as a single digest. The dataset is always saved regardless of delivery settings.

ℹ️ PSC is ownership, not management. Persons with Significant Control are the people or entities who own or control the company (>25% shares, >25% voting rights, right to appoint/remove directors, or significant influence). They are frequently not the directors. For named leadership, pair with LinkedIn Decision Makers.

When to use it — and when not to

ScenarioFit
KYB / KYC / AML: who ultimately owns and controls this UK company?✅ Strong (the core use case)
Due diligence before a contract, investment or partnership✅ Strong — status, age, ownership in one record
Verifying a UK company actually exists and is active✅ Strong
Building a UK prospect list by SIC industry + location + company age✅ Strong
Finding newly incorporated companies in a sector (VC / investor research)✅ Strong — incorporated_from + SIC
Insolvency / restructuring research: dissolved or liquidated companies by date and sector✅ Strong — company_status + dissolved_from/to
Cross-checking a lead list you already have against the register✅ Strong — loop company_name_includes
Registered Overseas Entities (the UK's foreign-owned-property register)✅ Supported — company_type: registered-overseas-entity
Feeding a compliance record into Notion / Airtable / a CRM✅ Strong (deliveryMode: "perCompany")
One specific company, by company number❌ This is a search endpoint — filter by name, or call /company/{number} directly
Directors, officers, company secretaries❌ PSC ≠ the board — use the Companies House officers endpoint
Filing history, accounts, charges, mortgages❌ Not returned
Emails, phone numbers, websites❌ Never returned — the register doesn't publish them
Shareholder lists / full cap table❌ PSC only covers controllers above the statutory thresholds
Non-UK companies❌ UK register only
More than 100 companies in one run⚠️ Hard cap of 100 — paginate with start_index
A count of how many companies match your filters❌ Not exposed — you see the page you asked for

⚡ Execution Rules (Avoid Common Agent Failures)

  1. Nothing is required — and that's the biggest trap. Every field is optional, so an empty input runs a filter-less search and returns an arbitrary first 100 companies from the register. Always pass at least one filter.
  2. size is capped at 100 in code as well as in the schema, and free Apify plans are capped at 5 companies per run, whatever you ask for. That is a successful run, not a failure.
  3. This is a search, not a lookup. There is no company_number input. To target one company, filter on company_name_includes and match the number in the output — or call the register's /company/{number} endpoint directly.
  4. Use start_index to paginate, incrementing by size. There is no total-match count in the output, so page until a run comes back with fewer than size items.
  5. persons_with_significant_control: [] is ambiguous. It means either the company has no PSCs on file (exempt, or a super-secure record) or the PSC request failed. A failed PSC fetch logs a warning and yields an empty list — check the run log before reporting "no beneficial owners".
  6. Individual and corporate PSCs carry different fields. Individuals get name, nationality, country_of_residence, date_of_birth, address, links. Corporate and legal-person PSCs get name, kind, identification, natures_of_control, notified_on, ceased/ceased_on, address, links. natures_of_control is present only on corporate/legal-person records — see Output Contract.
  7. A bad api_key ends the run cleanly, not with a failure. An invalid key exits with the status message Please enter a valid API key — an agent that only checks run status will read that as success with zero items. Check the status message.
  8. A non-200 from the search also ends the run with zero items, logging the status and body. The run status is not the error signal here; the log and the item count are.
  9. Mind the upstream rate limit. Companies House allows 600 requests per 5 minutes per key, and a size: 100 run costs 101 requests (1 search + 100 PSC). Back-to-back large runs will hit 429; the Actor rotates keys, but keys are finite. Space out big jobs, or supply your own key.
  10. Multi-value filters are OR within a field, AND across fields. company_status: ["active","liquidation"] means either status; adding a SIC code narrows it further.
  11. Dates are YYYY-MM-DD strings, and they are not validated by the Actor — a malformed date is passed straight to the register and rejected there.
  12. dissolved_from / dissolved_to only make sense with a dissolved-type status. Combining them with company_status: ["active"] returns nothing.
  13. location matches the registered office, which is often an accountant's or agent's address — not where the business trades.
  14. registered_office_address is a single joined string, not an object. Nine register sub-fields (care_of, po_box, premises, address_line_1/2, locality, region, postal_code, country) are merged with ", ". Parse accordingly.
  15. sic_codes may be absent entirely on some records — don't assume the key exists.
  16. links.company_profile is a relative path (/company/12118284). Prefix with https://find-and-update.company-information.service.gov.uk for a browsable URL.
  17. PSC data includes personal data — names, nationality, country of residence and month/year of birth of real people. See Compliance before you store it.
  18. deliveryMode defaults to perCompany, not none. With a connector selected, a 100-company run makes 100 connector calls. Use summary or chunked for a digest.
dependencies:
- rule: "no field is required"
on_violation: "an empty input returns an arbitrary first page of the register - always pass a filter"
- rule: "size is clamped to 100 in code, and to 5 on free Apify plans"
note: "the schema maximum and the code cap agree at 100"
- rule: "there is no company_number input"
on_violation: "agents looking up one company by number must use company_name_includes or the register's own /company/{number} endpoint"
- rule: "empty persons_with_significant_control does not prove there are no PSCs"
on_violation: "reporting 'no beneficial owners' when the PSC request actually failed"
- rule: "natures_of_control is present only on corporate / legal-person PSC records"
on_violation: "a KYC pipeline keyed on natures_of_control silently drops every individual owner"
- rule: "an invalid api_key exits with a status message, not a failed run"
on_violation: "an agent that only checks run status reads a key failure as an empty result"
- rule: "a non-200 search response ends the run with zero items and a logged error"
on_violation: "same failure mode - read the log and the item count, not just the status"
- rule: "one run costs 1 + N upstream Companies House requests against a 600 / 5 min / key budget"
on_violation: "429 Too Many Requests; the Actor rotates keys, then returns partial or empty PSC data"
- rule: "delivery requires mcpConnector AND mcpTool"
on_violation: "delivery step is skipped with a warning; the dataset is still written in full"
- rule: "mcpArguments must reference {message} for the rendered template to appear anywhere"
on_violation: "message body is empty; the tool is still called"
- rule: "mcpConnector only resolves when the Actor runs on the Apify platform"
on_violation: "local runs log 'APIFY_MCP_PROXY_URL is not set' and skip delivery; the dataset is unaffected"
authentication:
actor_input: "optional - your own Companies House API key (api_key, stored as a secret) for the cheaper basic rate"
platform: "Apify API token required for API / SDK / MCP invocation"
target_site: "official Companies House API; built-in keys are used when you supply none"

📥 Input Contract

.actor/input_schema.json is authoritative — if any table on this page disagrees with the schema files, the schema files win.

Parameters

FieldTypeRequiredDefaultAllowed Values / FormatExample
api_keystring (secret)⬜ No"" → built-in keysYour own Companies House API key — switches billing to the basic rate"a1b2c3…"
company_name_includesstring⬜ NoFree text matched inside the company name"Intelligence"
company_name_excludesstring⬜ NoFree text excluded from the company name"Holdings"
company_statusarray⬜ No11 values — see below["active"]
company_typearray⬜ No27 values — see below["ltd","plc"]
company_subtypearray⬜ Nocommunity-interest-company, private-fund-limited-partnership["community-interest-company"]
nature_of_businessarray⬜ No730 SIC codes, searchable multi-select["62012"]
locationstring⬜ NoRegistered office locality / town"London"
incorporated_fromstring⬜ NoYYYY-MM-DD"2020-01-01"
incorporated_tostring⬜ NoYYYY-MM-DD"2024-12-31"
dissolved_fromstring⬜ NoYYYY-MM-DD"2022-01-01"
dissolved_tostring⬜ NoYYYY-MM-DD"2024-12-31"
sizeinteger⬜ No1001100; free plans capped at 550
start_indexinteger⬜ No0≥ 0 — offset for pagination100

Empty strings and null values are dropped before the request, so an unused filter costs nothing.

company_status — all 11 values

ValueMeaning
activeTrading / on the register
dissolvedStruck off and dissolved
liquidationIn liquidation
administrationIn administration
receivershipIn receivership
insolvency-proceedingsInsolvency proceedings under way
voluntary-arrangementCompany voluntary arrangement
openOpen (used for some entity types)
closedClosed (used for some entity types)
converted-closedConverted or closed
removedRemoved from the register

company_type — all 27 values

ValueMeaning
ltdPrivate Limited Company
plcPublic Limited Company
llpLimited Liability Partnership
limited-partnershipLimited Partnership
private-unlimitedPrivate Unlimited Company
private-unlimited-nscPrivate Unlimited Company without Share Capital
private-limited-guarant-nscPrivate Limited by Guarantee without Share Capital
private-limited-guarant-nsc-limited-exemption…with 'Limited' exemption
private-limited-shares-section-30-exemptionPrivate Limited, s.30 'Limited' exemption
old-public-companyOld Public Company
overseas-companyOverseas Company
registered-overseas-entityOverseas Entity (UK property ownership register)
uk-establishmentUK Establishment Company
unregistered-companyUnregistered Company
charitable-incorporated-organisationCharitable Incorporated Organisation
scottish-charitable-incorporated-organisationScottish CIO
registered-societyRegistered Society
industrial-and-provident-societyIndustrial and Provident Society
assurance-companyAssurance Company
investment-company-with-variable-capitalICVC
protected-cell-companyProtected Cell Company
european-public-limited-liability-company-seEuropean Public Limited Liability Company (SE)
eeigEuropean Economic Interest Grouping
further-education-or-sixth-form-college-corporationFE / Sixth Form College Corporation
royal-charterRoyal Charter Company
scottish-qualifying-partnershipScottish Qualifying Partnership
converted-or-closedConverted or Closed

SIC codes (nature_of_business)

730 codes are selectable, each labelled code – description in the Console dropdown. Frequently used ones:

SICSector
62012Business and domestic software development
62020Information technology consultancy activities
62090Other information technology service activities
63110Data processing, hosting and related activities
64999Financial intermediation not elsewhere classified
68209Other letting and operating of own or leased real estate
70229Management consultancy activities other than financial management
73110Advertising agencies
41100Development of building projects
47910Retail sale via mail order houses or via Internet
86900Other human health activities
56101Licenced restaurants

Pass several codes to OR them together.

Examples

KYB / due diligence — verify one company and its owners

{
"company_name_includes": "Techforce Global",
"company_status": ["active"],
"size": 10,
"deliveryMode": "none"
}

B2B prospecting — active London software companies incorporated since 2020

{
"company_status": ["active"],
"company_type": ["ltd"],
"nature_of_business": ["62012", "62020"],
"location": "London",
"incorporated_from": "2020-01-01",
"size": 100,
"deliveryMode": "none"
}

Insolvency research — financial firms dissolved 2022–2024

{
"company_status": ["dissolved"],
"nature_of_business": ["64999"],
"dissolved_from": "2022-01-01",
"dissolved_to": "2024-12-31",
"size": 100,
"deliveryMode": "none"
}

Distress monitoring — companies currently in liquidation or administration

{
"company_status": ["liquidation", "administration", "receivership"],
"location": "Manchester",
"size": 100,
"deliveryMode": "none"
}

Overseas Entities holding UK property

{
"company_type": ["registered-overseas-entity"],
"company_status": ["active"],
"size": 100,
"deliveryMode": "none"
}

Page 3 of a large result set, on your own API key (cheaper basic rate)

{
"api_key": "<your-companies-house-api-key>",
"company_status": ["active"],
"nature_of_business": ["41100"],
"size": 100,
"start_index": 200,
"deliveryMode": "none"
}

MCP Delivery Configuration (Optional)

Delivery pushes company records into your own tools. It never contacts a company or a person.

ParameterTypeDefaultDescription
mcpConnectorstring""Authorized MCP connector on your Apify account (Slack, Notion, Airtable, Sheets, Jira, Linear, HubSpot, …). Leave empty for dataset-only runs.
deliveryModeenumperCompanyperCompany (one call per company) · chunked (split large sets across calls) · summary (one call with everything) · none.
mcpToolstring""Tool name on the connector: create_page, send_message, create_record, create_issue. Run once with a connector selected — the log lists the connector's available tools.
mcpArgumentsobject{}Arguments passed to the tool. String leaves support {placeholders}.
mcpMessageTemplatestring""Template rendered and exposed to mcpArguments as {message}.

Per-company placeholders: {companyName}, {companyNumber}, {companyStatus}, {companyType}, {companySubtype}, {dateOfCreation}, {dateOfCessation}, {address}, {sicCodes}, {profileUrl} (the browsable Companies House URL), {pscCount}, {pscNames}, {pscs} (a bulleted list with control and nationality), {company} (a formatted multi-line block), {message}.

Summary / chunked placeholders: {companyCount}, {pscTotal}, {filters} (a readable summary of the filters used), {companies}, {part}, {partCount}, {message}.

One Airtable record per company, ready for a compliance review:

{
"company_status": ["active"],
"nature_of_business": ["64999"],
"size": 100,
"mcpConnector": "<your-authorized-airtable-connector>",
"deliveryMode": "perCompany",
"mcpTool": "create_record",
"mcpArguments": {
"fields": {
"Company": "{companyName}",
"Number": "{companyNumber}",
"Status": "{companyStatus}",
"Incorporated": "{dateOfCreation}",
"Registered office": "{address}",
"SIC": "{sicCodes}",
"PSC count": "{pscCount}",
"Beneficial owners": "{pscNames}",
"Register": "{profileUrl}"
}
}
}

One Slack digest per run:

{
"company_status": ["liquidation", "administration"],
"location": "Manchester",
"size": 100,
"mcpConnector": "<your-authorized-slack-connector>",
"deliveryMode": "summary",
"mcpTool": "send_message",
"mcpArguments": { "channel": "#uk-credit-risk", "text": "{message}" },
"mcpMessageTemplate": "⚠️ {companyCount} UK companies in distress ({filters}) — {pscTotal} PSCs on file:\n\n{companies}"
}

One Notion page per company, with the ownership block inline:

{
"company_name_includes": "Techforce",
"size": 50,
"mcpConnector": "<your-authorized-notion-connector>",
"deliveryMode": "perCompany",
"mcpTool": "notion-create-pages",
"mcpArguments": {
"parent": { "page_id": "<your-page-id>" },
"pages": [
{
"properties": { "title": "{companyName} ({companyNumber})" },
"content": "Status: {companyStatus} · Incorporated {dateOfCreation}\n{address}\n{profileUrl}\n\nPersons with Significant Control ({pscCount}):\n{pscs}"
}
]
}
}

A long result set split across Notion sub-pages instead of one oversized call:

{
"company_status": ["active"],
"nature_of_business": ["41100"],
"size": 100,
"mcpConnector": "<your-authorized-notion-connector>",
"deliveryMode": "chunked",
"mcpTool": "notion-create-pages",
"mcpArguments": {
"parent": { "page_id": "<your-page-id>" },
"pages": [
{
"properties": { "title": "UK construction companies — part {part}/{partCount}" },
"content": "{companies}"
}
]
}
}

📤 Output Contract & Data Structure

Storage: Apify Dataset — one JSON object per company, with its PSCs nested. Pagination: limit & offset on the dataset items endpoint (separate from the input's start_index, which pages the register). Duplicates: one record per company per run. Across paged runs, dedupe on company_number.

Company record

FieldTypeNullable / optionalMeaning
company_namestringnoRegistered company name, as held on the register
company_numberstringnoCompanies House number — the canonical dedupe key (letters are meaningful: SC… Scotland, NI… Northern Ireland, OC… LLP, OE… Overseas Entity)
company_statusstringnoactive, dissolved, liquidation, administration, …
company_typestringnoltd, plc, llp, registered-overseas-entity, …
company_subtypestring⚠️ often absentcommunity-interest-company / private-fund-limited-partnership where applicable
kindstringnoAlways search-results#company — a register artifact, not useful data
linksobjectno{ "company_profile": "/company/12118284" } — a relative path
date_of_creationstringnoIncorporation date, YYYY-MM-DD
date_of_cessationstring⚠️ only when dissolvedDissolution date, YYYY-MM-DD
registered_office_addressstringnoNine register sub-fields joined with ", "not an object
sic_codesarray of string⚠️ may be absentSIC codes on the register for this company
persons_with_significant_controlarray of objectnever null, often []PSC records — see below, and rule 5 above

PSC record — individuals

FieldTypeMeaning
namestringFull name of the person
nationalitystringDeclared nationality
country_of_residencestringDeclared country of residence
date_of_birthobject{ "month": 3, "year": 2000 }month and year only, as the register publishes it
addressstringCorrespondence address, joined into one string
linksobject{ "self": "/company/…/persons-with-significant-control/individual/…" }

⚠️ Individual PSC records do not carry natures_of_control or notified_on. Those fields are kept only on corporate and legal-person records. A KYC pipeline that keys on natures_of_control will silently skip every human owner — read the count and names instead, and follow links.self on the register if you need the exact control thresholds for a person.

FieldTypeMeaning
namestringRegistered name of the controlling entity
kindstringcorporate-entity-person-with-significant-control / legal-person-…
identificationobjectlegal_form, legal_authority, country_registered, place_registered, registration_numberuse registration_number to hop up the ownership chain
natures_of_controlarray of stringe.g. ownership-of-shares-75-to-100-percent, voting-rights-25-to-50-percent, right-to-appoint-and-remove-directors
notified_onstringDate the PSC was notified to the register
ceased / ceased_onboolean / stringWhether control has ceased, and when
addressstringRegistered address, joined into one string
linksobjectRegister link to the PSC record

A super-secure-person-with-significant-control record (protected individuals) carries a name placeholder only — no personal details are published.

Example dataset item

{
"company_name": "AMERICAN EXPRESS LIMITED",
"company_number": "12118284",
"company_status": "dissolved",
"company_type": "ltd",
"kind": "search-results#company",
"links": { "company_profile": "/company/12118284" },
"date_of_cessation": "2019-11-05",
"date_of_creation": "2019-07-23",
"registered_office_address": "Dsf 4133 Redwood Avenue, Unit 1021, Los Angeles, 90066, United Kingdom",
"sic_codes": ["01110"],
"persons_with_significant_control": [
{
"name": "Florian Haftman",
"nationality": "British",
"country_of_residence": "United States",
"date_of_birth": { "month": 3, "year": 2000 },
"address": "Dsf, 4133 Redwood Avenue, Unit 1021, Los Angeles, 90066, United Kingdom",
"links": {
"self": "/company/12118284/persons-with-significant-control/individual/RznLYZ9hwosE-cOdZnvhD1_1Gh4"
}
}
]
}

links.company_profile is relative. Prefix it:

url = "https://find-and-update.company-information.service.gov.uk" + item["links"]["company_profile"]

The connector delivery does this for you and exposes it as {profileUrl}.

What a successful run looks like

{
"status": "SUCCEEDED",
"defaultDatasetId": "<datasetId>",
"stats": { "itemCount": 100 }
}

itemCount: 0 with SUCCEEDED is a valid empty result — and also what you get from an invalid api_key or a non-200 from the register. Distinguish them from the run's status message and log:

Log / status messageMeaning
No companies found matching the criteriaGenuinely nothing matched — loosen the filters
Please enter a valid API key (status message)Your api_key was rejected by the register
Failed to fetch companies. Status: 4xx/5xxThe register rejected or failed the search (often a malformed date)
429 Too Many Requests with key …Rate limit hit; the Actor rotated to another key
Failed to fetch PSCs for <number>. Status: …That company's PSC list is empty because of a failure, not because it has none
Free plan detected — capping results to 5 companies per run.Free-plan cap applied

▶️ Invocation & Integration

Lifecycle: Discover → Understand → Configure → Execute → Retrieve → Validate. Authenticate every call with Authorization: Bearer <APIFY_TOKEN>.

Apify Console

Open the Actor → Input tab → set at least one filter (name, status, type, SIC, location or a date range) → set Size(optional) paste your own Companies House API Key for the cheaper rate → (optional) pick an MCP connector, tool and template → Start → export from the Dataset tab (JSON, CSV, Excel, XML).

Model Context Protocol (MCP)

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=techforce.global/gov-uk-business-scraper"

Python (apify-client)

import os
from apify_client import ApifyClient
client = ApifyClient(os.getenv("APIFY_TOKEN"))
PROFILE_BASE = "https://find-and-update.company-information.service.gov.uk"
run = client.actor("techforce.global/gov-uk-business-scraper").call(run_input={
"company_status": ["active"],
"company_type": ["ltd"],
"nature_of_business": ["62012", "62020"], # software development + IT consultancy
"location": "London",
"incorporated_from": "2020-01-01",
"size": 100, # ceiling; free plans stop at 5
"deliveryMode": "none",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(f"{len(items)} companies")
for company in items:
pscs = company.get("persons_with_significant_control") or []
# [] can also mean the PSC request failed - check the run log before concluding.
owners = ", ".join(p.get("name", "") for p in pscs) or "(none on file)"
print(
f'{company["company_number"]} {company["company_name"]}\n'
f' incorporated {company["date_of_creation"]} · {company["company_status"]}\n'
f' {PROFILE_BASE}{company["links"]["company_profile"]}\n'
f' PSCs ({len(pscs)}): {owners}'
)

Paginating past 100 — the register is paged with start_index, not the dataset:

all_items, start = [], 0
while True:
run = client.actor("techforce.global/gov-uk-business-scraper").call(run_input={
"company_status": ["active"],
"nature_of_business": ["41100"],
"size": 100,
"start_index": start,
"deliveryMode": "none",
})
page = client.dataset(run["defaultDatasetId"]).list_items().items
all_items.extend(page)
if len(page) < 100: # short page = last page; there is no total count to check
break
start += 100
# Each page costs 101 upstream Companies House calls against 600 / 5 min / key.

JavaScript / TypeScript (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('techforce.global/gov-uk-business-scraper').call({
company_status: ['dissolved'],
nature_of_business: ['64999'],
dissolved_from: '2022-01-01',
dissolved_to: '2024-12-31',
size: 100,
deliveryMode: 'none',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// Corporate PSCs expose natures_of_control; individuals do not.
const corporateOwners = items.flatMap((c) =>
(c.persons_with_significant_control ?? [])
.filter((p) => p.natures_of_control)
.map((p) => ({
company: c.company_name,
owner: p.name,
control: p.natures_of_control,
ownerCompanyNumber: p.identification?.registration_number,
})),
);
console.log(`${corporateOwners.length} corporate control relationships`);

cURL — synchronous run (returns items directly; 300s limit)

curl -X POST \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{"company_status":["active"],"location":"London","nature_of_business":["62012"],"size":50,"deliveryMode":"none"}' \
'https://api.apify.com/v2/acts/techforce.global~gov-uk-business-scraper/run-sync-get-dataset-items'
# 1. Start execution with a hard spend limit
curl -X POST -H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{"company_status":["active"],"nature_of_business":["41100"],"size":100,"deliveryMode":"none"}' \
'https://api.apify.com/v2/acts/techforce.global~gov-uk-business-scraper/runs?maxTotalChargeUsd=1.00'
# 2. Poll
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
'https://api.apify.com/v2/actor-runs/<runId>'
# 3. Retrieve when SUCCEEDED
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
'https://api.apify.com/v2/datasets/<DATASET_ID>/items?clean=true&format=json'

Workflow tools

n8n (HTTP Request node), Make, Zapier and webhooks all work through the standard Apify API endpoints above — or skip the glue entirely and let the Actor deliver into your tool with mcpConnector.


⚠️ Autonomous Agent Error Handling & Resolution Matrix

Error CodeDetection ConditionUnderlying CauseDeterministic Agent Action
AUTH_INVALIDHTTP 401 from ApifyMissing or malformed APIFY_TOKENAbort & Prompt User: request a valid Apify API token.
RATE_LIMITEDHTTP 429 from ApifyApify API rate / concurrency limitsRetry: exponential backoff (2s, 4s, 8s).
SYNC_TIMEOUTHTTP 408 on the sync endpointRun exceeded the 300s synchronous ceilingReconfigure: use async POST /runs + polling.
CH_KEY_INVALIDSUCCEEDED, 0 items, status message Please enter a valid API keyThe api_key you supplied was rejected by Companies HouseModify Input: fix or remove api_key (removing it falls back to built-in keys at the premium rate).
NO_FILTERS100 seemingly unrelated companiesEvery field is optional; nothing was filteredModify Input: pass at least one filter.
EMPTY_RESULTSSUCCEEDED, 0 items, log No companies found matching the criteriaFilters genuinely match nothingModify Input: loosen filters — drop location, widen the date range, remove a SIC code.
CONTRADICTORY_FILTERS0 items with several filters sete.g. company_status: ["active"] combined with dissolved_fromModify Input: remove the incompatible filter.
CH_SEARCH_FAILEDSUCCEEDED, 0 items, log Failed to fetch companies. Status: 4xx/5xxThe register rejected the query (often a malformed YYYY-MM-DD date) or was unavailableModify Input / Retry: validate the date format, then retry.
CH_RATE_LIMITEDLog 429 Too Many Requests with key …600 req / 5 min / key exhausted — a size:100 run costs 101Wait & Retry: pause ≥ 5 minutes, lower size, or supply your own api_key.
PSC_FETCH_FAILEDLog Failed to fetch PSCs for <number>That company's PSC call failed; the field is [] because of the failureDo not conclude "no owners". Re-run for those company numbers.
PSC_EMPTY_AMBIGUOUSpersons_with_significant_control: [], no warning in the logCompany genuinely has no PSCs on file (exempt, or super-secure)Accept, and record it as "none on file", not "none exist".
PSC_NO_CONTROL_FIELDnatures_of_control missing on a PSCIndividual PSC records don't carry it — only corporate / legal-person ones doFix Expectation: use links.self on the register for a person's control detail.
FREE_PLAN_CAPitemCount stops at 5, log shows the upgrade bannerFree Apify plan caps the run at 5 companiesPrompt User: upgrade for full-volume runs.
SIZE_CLAMPEDFewer items than requested with size > 100size is hard-capped at 100Modify Input: request ≤ 100 and paginate with start_index.
NO_TOTAL_COUNTAgent wants to know how many matchedThe register's total is not exposed in the outputFix Expectation: page until a short page returns.
WRONG_GRANULARITY_SINGLEUser wanted one company by numberThis is a search endpoint with no company_number inputRe-route: filter on company_name_includes, or call the register's /company/{number} directly.
WRONG_ENTITY_OFFICERSUser wanted directors / officersPSC is beneficial ownership, not the boardRe-route: Companies House officers endpoint, or LinkedIn Decision Makers for named leadership.
NO_CONTACT_DATANo email / phone / website in any itemThe register does not publish themRe-route: Google Maps Business Leads.
NO_FILINGS_OR_ACCOUNTSNo filing history, accounts or chargesNot part of Advanced Search or the PSC endpointFix Expectation: use the register's filing-history endpoints.
NON_UK_QUERYUser asked about a non-UK companyUK register onlyAbort & Prompt User: UK entities only (incl. Overseas Entities that own UK property).
ADDRESS_NOT_OBJECTCode does address.locality and gets undefinedregistered_office_address is a single joined stringFix Code: parse the string, or take the whole line.
RELATIVE_LINKA saved URL 404slinks.company_profile is a relative pathFix Code: prefix https://find-and-update.company-information.service.gov.uk.
DELIVERY_SKIPPEDLog no tool name was providedmcpConnector set but mcpTool emptyModify Input: set mcpTool; the dataset is already saved.
DELIVERY_TOOL_UNKNOWNLog Tool 'x' is not available on this connectorWrong tool name for that connectorModify Input: pick a name from the Available tools: list in the same log line.
DELIVERY_EMPTYConnector called, body emptymcpArguments omitted the {message} placeholderModify Input: map {message} inside mcpArguments.
DELIVERY_FLOODUp to 100 connector calls per rundeliveryMode defaults to perCompanyReconfigure: use summary or chunked.
MCP_PROXY_MISSINGLog APIFY_MCP_PROXY_URL is not setRunning locally instead of on the platformReconfigure: apify push and run on the platform.
CHARGE_LIMITRun aborted before size reachedmaxTotalChargeUsd spend threshold reachedPrompt User: confirm a higher spend cap.

⚠️ Verify before publishing: the Apify HTTP status rows (401, 408, 429) reflect standard platform behavior. Every Companies-House-side and field-level row is taken from this Actor's source and from real run output. Re-confirm the platform rows if you depend on them for automated retry logic.


🗣️ Natural Language → Actor Mapping

User saysIntentConstructed Actor input
"Who really owns Acme Trading Ltd?"UBO / KYB{"company_name_includes":"Acme Trading","company_status":["active"],"size":10}
"Is this UK company still active?"Verification{"company_name_includes":"<name>","size":10} → read company_status
"Run KYC on this list of UK suppliers"Batch KYBone run per name on company_name_includes, then read persons_with_significant_control
"Find active London software companies started since 2020"Prospecting{"company_status":["active"],"nature_of_business":["62012","62020"],"location":"London","incorporated_from":"2020-01-01","size":100}
"Newly incorporated fintech companies this year"Investor research{"company_status":["active"],"nature_of_business":["64999"],"incorporated_from":"<Jan 1>","size":100}
"Which construction firms went under in 2023?"Insolvency research{"company_status":["dissolved"],"nature_of_business":["41100"],"dissolved_from":"2023-01-01","dissolved_to":"2023-12-31","size":100}
"Any companies in administration near Manchester?"Distress monitoring{"company_status":["administration","liquidation"],"location":"Manchester","size":100}
"Show me UK charities, not regular companies"Entity-type filter{"company_type":["charitable-incorporated-organisation","scottish-charitable-incorporated-organisation"],"size":100}
"Which foreign entities own UK property?"Overseas Entities{"company_type":["registered-overseas-entity"],"company_status":["active"],"size":100}
"Find LLPs in Edinburgh"Type + location{"company_type":["llp"],"location":"Edinburgh","size":100}
"Companies with 'holdings' in the name but not 'property'"Name filtering{"company_name_includes":"holdings","company_name_excludes":"property","size":100}
"Give me the next 100 results"Paginationrepeat the input with start_index advanced by 100
"Push each company into Airtable for compliance review"CRM delivery{"mcpConnector":"airtable","deliveryMode":"perCompany","mcpTool":"create_record"}
"Alert the risk channel about distressed companies"Digest delivery{"mcpConnector":"slack","deliveryMode":"summary","mcpTool":"send_message"}
"Who are the directors of this company?"Officers⚠️ Not PSC — use the register's officers endpoint, or LinkedIn Decision Makers
"Get me their email and phone number"Contact data➡️ Route to Google Maps Business Leads
"Pull their latest accounts"Filings❌ Out of scope — filing-history endpoints
"Look up company 12118284"Single lookup⚠️ No company_number input — search by name, or call /company/12118284 directly
"Do the same for a German company"Non-UK❌ UK register only

Should NOT route here: a single company fetched by its company number · directors, officers or secretaries · filing history, accounts, charges or mortgages · emails, phones or websites · shareholder lists and cap tables · non-UK registries · whole-register bulk downloads · more than 100 companies in one run.


🧭 Agent Execution & Routing Logic

[Input User Query]
1. Is the subject a UK-registered entity? NO → Abort. UK register only
│ YES
2. What is actually wanted?
├── existence / status / age / SIC / registered office → stay here
├── beneficial ownership (who OWNS or CONTROLS it) → stay here (PSC)
├── directors / officers / the board → Route: CH officers endpoint
├── filings / accounts / charges → Route: CH filing-history endpoints
└── emails / phones / websites → Route: Google Maps Business Leads
3. One company, or a filtered list?
├── ONE, and you have its number → the register's /company/{number} is the direct route
├── ONE, by name → company_name_includes + company_status, size 10, match the number in output
└── a LIST → continue
4. Build the filter set — NEVER run with none:
status? type/subtype? SIC (nature_of_business)? location? incorporated_* ? dissolved_* ?
(values OR within a field, AND across fields)
5. Sanity-check for contradictions
└── dissolved_from/to with status "active" → returns nothing. Drop one
6. Set size (≤ 100; free plans get 5). Need more? plan start_index pages: 0, 100, 200 …
│ Each page = 1 + size upstream calls against 600 / 5 min / key.
│ Large jobs: supply your own api_key, or space the pages out.
7. Own Companies House key available?
├── YES → pass api_key (billed at the cheaper `basic` rate, uses YOUR quota)
└── NO → leave blank (built-in keys, `premium` rate, shared quota)
8. Deliver to a connector? YES → mcpConnector + mcpTool + {message}
│ perCompany (≤100 calls) / chunked / summary
│ NO → set deliveryMode "none" (it defaults to perCompany)
[Execute]
├──► SUCCEEDED, items > 0 ──► for each company:
│ pscs == [] ? → check the log for "Failed to fetch PSCs" before reporting "no owners"
│ need control detail on a PERSON? → natures_of_control is corporate-only; use links.self
│ dedupe on company_number; prefix links.company_profile to make it browsable
└──► SUCCEEDED, items == 0 ──► READ THE STATUS MESSAGE AND LOG, they differ:
"Please enter a valid API key" → fix or drop api_key
"Failed to fetch companies. Status" → bad date format / register error → retry
"No companies found matching..." → loosen the filters

💰 Cost Control & Pricing Transparency

Pay-per-event, charged once per company returned. No monthly subscription. There are two rates, and which one applies depends entirely on whether you bring your own Companies House API key:

EventFires whenWhat it means for you
basicYou supply your own api_keyThe cheaper rate. Requests run against your Companies House quota (600 req / 5 min), and your key is validated before the run starts.
premiumYou leave api_key blankThe convenience rate — no registration, no key management. Requests run on the Actor's built-in keys, whose quota is shared across users.

Exact per-event rates are on the Actor's Pricing tab in the Apify Store. Getting your own key is free at the Companies House developer hub and takes a few minutes — if you plan to run this at volume, it's the cheaper and faster path on both counts.

⚠️ Verify before publishing: this repo contains no .actor/pay_per_event.json, so the basic and premium rates are configured only on the Store listing. Confirm the live event configuration — and that both event names match the ones the Actor charges — before publishing.

What you are charged for: one event per company pushed to the dataset. A run that returns 40 companies charges 40 events, whichever rate applies. PSC enrichment is included in that — you are not charged separately per beneficial owner.

Free Apify plans are capped at 5 companies per run, so you can validate a filter set for the cost of five events before committing to a full sweep.

Autonomous spend caps: pass maxTotalChargeUsd as a query parameter on the run endpoint for a hard per-execution ceiling.

Cost and quota levers:

  • Bring your own key — cheaper rate, dedicated quota, no contention with other users.
  • Validate filters at size: 5 first. A filter typo on a size: 100 run costs 100 events for data you throw away.
  • Set size to what you'll actually use. The default is 100, i.e. the maximum.
  • Remember the 1 + N upstream cost. Every company costs one extra Companies House request for its PSC list. That's what the register's rate limit sees, and it's why back-to-back size: 100 runs hit 429.
  • Cap the spend with maxTotalChargeUsd on any agent-driven run.

Apify platform usage (compute units, storage) is billed on top at your plan's rates. This Actor is HTTP-only — no browser — so compute is modest; the wall-clock time is dominated by the register's own response times.


🔍 Companion machine-readable files

FilePurpose
.actor/actor.jsonIdentity, version, build tag, and the dataset-schema reference
.actor/input_schema.jsonAuthoritative typed input contract — all 14 search fields (incl. the 730-code SIC enum and the 27 company types) plus the 5 delivery fields
.actor/dataset_schema.jsonConsole Output tab view — company name, number, status, type, incorporation and dissolution dates, registered office, SIC codes, PSCs
.actor/output_schema.jsonDeclares where results are stored
src/main.pyInput mapping, API key validation and rotation, Advanced Search request, concurrent PSC enrichment, PSC field filtering, charging, free-plan cap
src/delivery.pyMCP delivery: placeholder flattening, company/PSC block rendering, chunk grouping, per-mode dispatch
src/connector.pyMCP connector session handling through the Apify MCP Proxy
sic_list.txt + update_schema.pySource list and generator for the 730-entry SIC multi-select in the input schema

Note: this Actor has no pay_per_event.json — the basic and premium rates are configured on the Store listing.

If any table on this page disagrees with the schema files, the schema files win.


🛠️ Troubleshooting

#Symptom you seeMost likely causeFix
1100 companies with nothing in commonNo filter was set — every field is optionalPass at least one filter.
2SUCCEEDED with 0 itemsCould be three different thingsRead the status message and log — see the table in Output Contract.
3Status message Please enter a valid API keyCompanies House rejected your api_keyFix the key, or clear the field to use the built-in keys.
4Log Failed to fetch companies. Status: 400Usually a malformed dateUse YYYY-MM-DD exactly.
5Exactly 5 companies every runFree Apify plan capUpgrade the plan; the log prints the upgrade banner.
6Asked for 500, got 100size is hard-capped at 100Paginate with start_index in steps of 100.
7persons_with_significant_control: [] everywhereGenuine (exempt / super-secure) or failed PSC callsSearch the log for Failed to fetch PSCs. If present, re-run those company numbers.
8Log full of 429 Too Many Requests600 req / 5 min / key exhausted — one size:100 run costs 101Wait 5 minutes, lower size, or supply your own api_key.
9A person's PSC record has no natures_of_controlIndividual records don't carry it — only corporate / legal-person ones doFollow the PSC links.self on the register for a person's control detail.
10address.locality is undefined in your coderegistered_office_address is a joined stringParse the string, or use the whole line.
11A saved company URL 404slinks.company_profile is a relative pathPrefix https://find-and-update.company-information.service.gov.uk.
12sic_codes missing on some recordsNot every company has SIC codes on the registerTreat the key as optional.
13date_of_cessation missingOnly dissolved companies have oneExpected on active companies.
14No emails, phones or websitesThe register doesn't publish themPair with Google Maps Business Leads.
15No directors or officersPSC is ownership, not managementUse the register's officers endpoint, or LinkedIn Decision Makers.
16dissolved_from returned nothingCombined with company_status: ["active"]Use a dissolved-type status, or drop the date filter.
17location results look wrongIt matches the registered office — often an agent's addressExpected. Registered office ≠ trading address.
18Up to 100 connector calls per rundeliveryMode defaults to perCompanySwitch to summary or chunked.
19Slack / Notion / Airtable received nothingDelivery needs both mcpConnector and mcpToolSet both. The dataset is still written in full.
20Connector fired but the message body is emptymcpArguments did not reference {message}Map {message} in mcpArguments and populate mcpMessageTemplate.
21Notion call timed out on a big result setOne payload with 100 companies is too largeUse deliveryMode: "chunked".
22Log APIFY_MCP_PROXY_URL is not setYou ran locally; connectors only resolve on the platformDeploy with apify push and run on the platform.
23HTTP 408 on run-sync-get-dataset-itemsThe synchronous endpoint has a hard 300-second ceilingUse async POST /runs → poll → fetch.
24HTTP 401 / 403 from ApifyMissing, expired or malformed APIFY_TOKENRegenerate in Apify Console → Settings → API & Integrations.
25HTTP 429 from ApifyApify account concurrency / rate limitsRetry with exponential backoff (2s → 4s → 8s).

Diagnostic checklist before opening an issue

  1. Baseline run. {"company_status":["active"],"location":"London","size":5,"deliveryMode":"none"} — a filter set that must return something.
  2. Items returned? If yes, the pipeline is fine and your earlier filter set was too narrow or self-contradictory.
  3. Still zero? Read the status message, then the log. Those three failure modes (bad key / register error / genuine no-match) look identical from the run status alone.
  4. PSCs all empty? Search the log for Failed to fetch PSCs. A clean log means the companies genuinely have none on file.
  5. Seeing 429? Wait five minutes and retry with size: 10. If that works, you were rate-limited, not broken.

If the issue survives all five steps, open an Issues ticket on the Actor page (or email support) with the run ID and the exact input JSON.

❓ FAQ

Setup & access

Do I need a Companies House API key?

No. The Actor ships with built-in keys and works out of the box at the premium rate. Supplying your own key (free from the developer hub) switches you to the cheaper basic rate and gives you your own rate-limit quota — worth doing for any volume of work.

Is this scraping the Companies House website?

No. It calls the official government API — /advanced-search/companies for the search and /company/{number}/persons-with-significant-control for ownership. The field names and values are the register's own.

Is the data official and up to date?

It is exactly what the register serves at request time. Companies House data depends on companies filing correctly and on time, so it is authoritative about what has been filed, not about what is true — a common gap on PSC declarations in particular.

Can I plug it into Claude, Cursor, or a LangChain agent?

Yes — it is a native MCP tool:

claude mcp add --transport http apify "https://mcp.apify.com?tools=techforce.global/gov-uk-business-scraper"

Search behaviour

Can I look up one company by its company number?

Not directly — there is no company_number input, because this wraps a search endpoint. Filter on company_name_includes and match the number in the output, or call the register's /company/{number} endpoint yourself for a single profile.

How do I get more than 100 companies?

Paginate: keep the filters identical and advance start_index by size each run. There is no total-match count, so page until a run returns fewer items than size.

How do multi-value filters combine?

OR inside a field, AND across fields. company_status: ["liquidation","administration"] + location: "Leeds" means "in either of those states, registered in Leeds".

Does location mean where the business operates?

No — it matches the registered office, which for many small companies is their accountant's or formation agent's address.

Can I find Overseas Entities that own UK property?

Yes: company_type: ["registered-overseas-entity"].

PSC / ownership

What exactly is a PSC?

A Person with Significant Control: someone holding more than 25% of shares or voting rights, the right to appoint or remove a majority of directors, or otherwise exercising significant influence or control. It is an ownership concept — PSCs are often not the directors.

Why is persons_with_significant_control empty?

Either the company genuinely has none on file — some entity types are exempt, and super-secure individuals are withheld — or that company's PSC request failed. The two look identical in the data; the run log distinguishes them.

Why does a person's PSC record have no nature of control?

Individual records keep name, nationality, country_of_residence, date_of_birth, address and links; natures_of_control and notified_on are kept only on corporate and legal-person records. For a person's exact control thresholds, follow their links.self on the register.

Can I trace an ownership chain up to the ultimate owner?

Partly, and only in the UK. A corporate PSC's identification.registration_number is a UK company number when the owner is a UK company — feed it back in as company_name_includes or via the register's /company/{number} endpoint to get its PSCs. Chains that leave the UK stop there.

Do I get shareholders or a cap table?

No. PSC only covers controllers above the statutory thresholds.

Output & scope

Can I get emails, phone numbers or websites?

No — the register doesn't publish them. Pair with Google Maps Business Leads & Sales Intelligence for contact data.

Can I get directors, filings or accounts?

Not from this Actor. PSC ≠ officers, and filing history is a separate set of register endpoints.

Why is the address one long string?

The register splits it into nine sub-fields; the Actor joins them with ", " so it drops straight into a spreadsheet or CRM field. Parse the string if you need the parts back.

Pricing

How is this billed?

Pay-per-event, one event per company returned — at the basic rate when you supply your own Companies House key, or the premium rate when you use the built-in ones. Exact figures are on the Actor's Pricing tab. Apify platform usage is billed separately.

Am I charged extra for PSC data?

No. Ownership enrichment is included in the per-company event, however many PSCs a company has.

How do I guarantee an agent never overspends?

Pass maxTotalChargeUsd as a query parameter on the run endpoint — a hard per-execution ceiling — and validate filters at size: 5 before a full sweep.


The verification layer of the pipeline

Most lead Actors tell you a business exists and how to reach it. This one tells you whether it is real, how old it is, and who owns it — the step that turns a lead list into something you can act on commercially or defend to a compliance team.

ActorAnchored onReturnsPair with this Actor to…
This ActorUK register filtersCompany facts + PSC / beneficial ownership
Google Maps Business Leads & Sales IntelligenceA place + queryEmails, phones, websites, website gradeAdd the contact details the register never publishes
LinkedIn Decision MakersOne company nameFounders, C-suite, VPs, directorsPut names and faces next to the ownership record (management vs. ownership)
LinkedIn Employee ScraperOne company nameStaff, with department and seniorityGauge real headcount and team shape behind a registered entity
Advanced Website Crawling ActorA domainFull site contentCheck what the company claims about itself against what it has filed

Vertical UK lead sources worth verifying here

ActorFeeds this Actor with
Construction Lead ScraperContractor and developer names — check status and ownership before subcontracting
Finance Lead ScraperFinancial firm names — a natural KYB pairing
Healthcare Lead ScraperPractice and group names — resolve the operating company behind a clinic
Hospitality Lead ScraperVenue and group names — identify the entity behind a trading name
DesignRush Agency Scraper · TopDevelopers ScraperAgency names — confirm a UK agency is a real, active company before signing

Suggested pipeline patterns

🛡️ KYB / onboarding check Company name → this Actor (company_status, PSC) → deliveryMode: "perCompany" into Airtable or Notion → a human reviews status, age and beneficial owners before approval.

🎯 Verified UK prospect list This Actor by SIC + location + incorporated_fromGoogle Maps Business Leads for contact data → LinkedIn Decision Makers for named buyers. Every lead is a confirmed active company before anyone spends outreach time on it.

📉 Distress / credit monitoring Schedule daily: company_status: ["liquidation","administration","receivership"] + your target locations → deliveryMode: "summary" into a Slack risk channel.

🧬 Ownership chain walk Run once → for each corporate PSC, take identification.registration_number → run again on that number → repeat until the chain leaves the UK or terminates in individuals.

💰 Investor sector scan incorporated_from = start of quarter + sector SIC codes → chunked delivery into Notion → a quarterly view of new UK company formation in your thesis area.

Browse all Actors by Techforce Global at apify.com/techforce.global.


🔐 Compliance & Data Privacy

This Actor reads official UK public registers through the Companies House public API. Company-level data — name, number, status, type, incorporation and dissolution dates, registered office, SIC codes — is public information published by statute, and reusing it is expressly permitted.

PSC data is different: it is personal data about identifiable individuals. For each individual beneficial owner the output can include their name, nationality, country of residence, month and year of birth, and a correspondence address. Four things follow:

  • You become a data controller the moment you store it. UK GDPR and (for EU-resident individuals) GDPR apply. Have a lawful basis, record it, set a retention period, and be ready to honour access, objection and erasure requests. Public availability is not a lawful basis on its own.
  • Purpose limitation is the real constraint. The PSC register exists for corporate transparency, AML and due diligence. Repurposing beneficial-owner personal data as a marketing list is a different purpose from the one it was published for and is very hard to defend — company-level fields are the right basis for prospecting, not PSC records.
  • Treat filed data as filed, not verified. PSC declarations are self-reported and Companies House does not verify most of them. Do not present ownership as established fact in a report that affects someone's access to credit, contracts or services without corroboration, and remember that an absent PSC record is not evidence of absent ownership.
  • Protected individuals exist for a reason. super-secure-person-with-significant-control records are withheld from publication because the person is at risk of violence or intimidation. Do not attempt to identify them from other fields.

Companies House data is published under the Open Government Licence; attribute it accordingly when you republish. You remain responsible for complying with the Companies House API terms of use, your own rate-limit obligations, and all applicable data-protection, AML and marketing law (UK GDPR, GDPR, PECR, CAN-SPAM, CASL) in the jurisdictions you operate in.

This Actor is an independent tool. It is not affiliated with, endorsed by, or sponsored by Companies House, GOV.UK, or the UK government.


🆘 Support & Custom Pipeline Engineering

Need scheduled register monitoring, an ownership-chain walker, bulk KYB across thousands of entities, or a compliance pipeline that writes straight into your case-management system?


Made with ❤️ by Techforce Global Specialists in High-Performance B2B Contact Data Extraction and AI Automation.


🏷️ Structured data for search & AI discovery

{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "UK Companies House Scraper — Advanced Company Search + PSC / Beneficial Ownership Enrichment",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Cloud (Apify platform)",
"description": "Queries the official UK Companies House register through its Advanced Search API — filtering by company name, status, type, subtype, registered office location, incorporation and dissolution date ranges, and 730 selectable SIC codes — and attaches Persons with Significant Control (PSC / beneficial ownership) to every company automatically. No Companies House API key required; bring your own for a cheaper rate. Results are saved to a dataset and can be delivered into Slack, Notion, Airtable, Google Sheets, Jira or any authorized MCP connector.",
"url": "https://apify.com/techforce.global/gov-uk-business-scraper",
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"description": "Pay-per-event, charged once per company returned: the basic rate when you supply your own Companies House API key, the premium rate when you use the built-in keys. Exact rates are listed on the Actor's Pricing tab."
}
}