UK Trading Disclosure Scraper - Company No, VAT & Contact avatar

UK Trading Disclosure Scraper - Company No, VAT & Contact

Pricing

$6.00 / 1,000 per trading disclosure returneds

Go to Apify Store
UK Trading Disclosure Scraper - Company No, VAT & Contact

UK Trading Disclosure Scraper - Company No, VAT & Contact

Turn UK company domains into registry-grade B2B leads from each site's statutory trading disclosure (Companies Act 2006 s.82): registered name, Companies House number, jurisdiction, registered office, mod-97-checked VAT number, charity and ICO numbers, regulator, email, phone. $0.006 per disclosure.

Pricing

$6.00 / 1,000 per trading disclosure returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Share

🇬🇧 UK Trading Disclosure Scraper — Company Number, VAT, Registered Office & Contacts

Turn a plain list of UK company domains into registry-grade B2B leads, read straight from the statutory trading disclosure every UK company is legally required to publish on its own website.

Paste domains. Get back the registered name, the Companies House number, the part of the UK it is registered in, the registered office address, a checksum-validated VAT number, plus email, phone, charity number, ICO registration and regulator — one flat row per company.


⚖️ Why this data exists, and why it is clean

Companies Act 2006 s.82 and The Company, Limited Liability Partnership and Business (Names and Trading Disclosures) Regulations 2015 (SI 2015/17), reg. 25 require every UK company and LLP to disclose, on its websites:

  • its registered name
  • the part of the United Kingdom in which it is registered
  • its registered number
  • the address of its registered office

Regulations 24–25 extend the name and address-for-service disclosure to unincorporated businesses trading under a name that is not the proprietor's own.

So this is not scraped inference and it is not a private profile. It is a statement the business is legally obliged to publish about itself, in public, on its own site. That is what makes it the cleanest UK B2B starting point there is — and the same shape that already works in Germany (Impressum), France (mentions légales) and Spain (aviso legal).

The corpus is the whole UK commercial web, not one directory with a member list. If a UK company has a website, it is in scope.


🔍 What it does, per domain

  1. Fetches the homepage and reads its footer. On the UK corpus the disclosure is often right there — measured over 598 real domains, the homepage footer carried it for 53.4% of all delivered rows (14.9% homepage-only, 38.5% homepage plus a second page). That is the opposite of the German/French pattern, where the legal notice is always its own page.
  2. If fields are still missing, ranks the site's own links and fetches the best ones — terms & conditions > legal > company information > privacy policy > about > contact — then merges field by field, because UK sites routinely split the disclosure across a terms page (company number, registered office) and a contact page (email, phone).
  3. Falls back to the XML sitemap, the WordPress REST page index and a list of conventional paths when a site publishes no footer link at all.
  4. Validates what it found: the GB VAT number against the published mod-97 checksum (both variants), the company number against the Companies House format and prefix table, and derives the jurisdiction from the prefix.

No browser. Plain HTTP + cheerio, on the Apify datacenter proxy, with a residential retry only when a host actually refuses us.


📦 What you get — every field

One flat row per company. null means the company did not publish it; nothing is ever invented.

Identity

FieldWhat it holds
registeredNameThe registered company name as the disclosure states it (Arrow Fresh Ltd)
tradingNameThe "trading as" / t/a name where one is declared
companyNameBest available name — the registered name, else JSON-LD legalName, else the site name
legalFormPrivate limited company, PLC, LLP, CIC, CIO, Company limited by guarantee, Limited partnership, Registered society, Sole trader
entityKindWhat the number's prefix implies: LLP, Limited partnership, Overseas company, Registered society, Charitable incorporated organisation, Royal charter…

Registry

FieldWhat it holds
companyNumberThe Companies House number, normalised to its canonical 8-character form — 00032762, SC216217, OC301234, R1234567
companyNumberRawExactly as the page printed it (SC 216217), for audit
companyNumberSourceWhich statement shape it came from: label-alt, jurisdiction, jurisdiction-label, label, bare
companyNumberFormatValidFormat + known-prefix check. Companies House numbers carry no checksum — see Honest limits
companyNumberSchemeGB-COH
jurisdictionEngland and Wales, Scotland, Northern Ireland or Overseas, from the prefix and the wording
jurisdictionStatedThe words the page actually used, verbatim
registerUrlA direct deep link into the public Companies House register for that number
registeredOfficeThe registered office address line
registeredOfficePostcode / registeredOfficeCityParsed out of that address block, never by a page-wide postcode scan
vatNumberNormalised VAT id (GB372138852), including the 12-digit branch form and the checksum-free GBGD### / GBHA### government forms
vatNumberValidThe mod-97 checksum result, true / false / null
vatChecksumVariantWhich published algorithm it satisfied: mod-97, mod-97-55, government-department, health-authority, or non-GB (no GB checksum applies)
vatCountry / vatBranchCountry code and the 3-digit branch identifier when present
charityNumberRegistered charity number, in its own field — a Scottish charity number looks exactly like a Scottish company number
icoRegistrationICO data-protection registration (ZA######) where published
regulator / regulatorNumberFCA, SRA, RICS, GDC, GMC, CQC, GPhC, Ofsted, Gambling Commission, ATOL, Gas Safe, NICEIC, ICAEW, ACCA and others, plus the reference number where published

Contact

FieldWhat it holds
email / emailsContact addresses, including Cloudflare-obfuscated ones (see below). The company's own domain wins the primary slot
emailConflictSet when the primary email is on somebody else's domain and is not a free mailbox — flagged, never silently dropped
phone / phonesNormalised to E.164 (+441312431453). Ofcom's reserved drama range and placeholder runs are rejected
addressLine / postcode / cityThe trading/contact address, which is often not the registered office (an accountant's address is a very common registered office)
officerName / officerRoleA named director / proprietor / company secretary where the page labels one
socialLinksLinkedIn, Facebook, Instagram, X, YouTube, TikTok
termsUrl / privacyPolicyUrlThe policy pages linked from the site

Provenance & accounting

FieldWhat it holds
disclosureUrlThe page the disclosure was read from
disclosureSourcehomepage, legal-page or merged
discoveryChannelhomepage, anchor, sitemap, wpjson, guess, jsassets, input
pagesParsed / pagesCheckedHow many pages were parsed, and how many URLs were tried
fieldSourcesOptional: the exact URL each individual field came from
fieldCountHow many of the 19 value fields are populated
stableIdThe company number when well-formed, else the registrable domain
status / missReasonok, or why nothing was returned
elapsedMs / fetchedAtPer-row timing and timestamp

📊 Measured results — real numbers, not claims

Everything below is from one real run on the Apify platform over 598 UK business domains, sourced from OpenStreetMap across 18 UK cities (London, Manchester, Birmingham, Leeds, Glasgow, Edinburgh, Bristol, Cardiff, Belfast, Newcastle, Liverpool, Sheffield, Nottingham, Brighton, Aberdeen, Norwich, Reading, Southampton) and picked without any reference to whether they publish a disclosure. Run wRVb4PWXuKSdMv4sL, 1,085 s, SUCCEEDED.

598 domains attempted
148 billed rows 24.7% of all domains · 32.7% of the 453 REACHABLE domains
303 publish no disclosure never charged
96 dead hosts (stale website entries) never charged
49 refused / challenged never charged
2 duplicates collapsed before a request never charged

Delivered rows == chargedEventCounts exactly: 148 and 148.

Per-field fill, measured on the 148 billed rows:

FieldFillFieldFill
email88.5%registeredOfficePostcode66.9%
companyNumber85.8%addressLine / postcode62.2%
jurisdiction85.8%registeredOfficeCity61.5%
registeredName75.0%city57.4%
legalForm75.0%vatNumber38.5%
registeredOffice71.6%regulator20.3%
phone70.3%charityNumber / tradingName10.8%
regulatorNumber7.4%icoRegistration5.4% · officerName 2.0%

VAT checksum: 57 VAT numbers found, 55 pass the GB mod-97 check — 96.5%. That is the number to look at. A parser that grabs the wrong nine digits produces checksum failures, so a high pass rate is evidence the extraction is right, not merely that a column is populated.

Where the disclosure was found: the homepage footer carried it for 79 of 148 rows (53.4%) — 22 homepage-only, 57 homepage plus a second page — and a dedicated legal/terms page was needed for the other 69 (46.6%). By discovery channel: ranked footer links 74, homepage footer 71, XML sitemap 2, guessed paths 1.

Transport: 3,822 requests for 598 domains = 6.4 per domain; 2,022 OK, 769 fast 404s on the guessed-path channel, 187 refusals, 105 dead hosts, 104 parked stubs. Residential escalation fired 128 times and recovered 26. Peak memory 691 MB in a 1,024 MB container.

Speed: 598 domains in 18 minutes at concurrency 12. The six-domain demo run finishes in 9–20 seconds.

Second run, country-wide corpus

A confirmation run on a different corpus and the current build: 400 domains drawn country-wide from OpenStreetMap (office + shop + craft, no high-street amenity bias), run TbGcBtEMY848MicQk, 687 s, SUCCEEDED.

400 domains -> 110 billed 27.5% of all · 36.7% of the 300 reachable
delivered == charged: 110 and 110
NOT charged: 190 publish no disclosure · 71 dead hosts · 29 refused
fill: email 88.2 · jurisdiction 88.2 · companyNumber 87.3 · phone 80.9 · registeredName 71.8
legalForm 70.9 · addressLine/postcode 65.5 · registeredOffice 61.8 · vatNumber 41.8
VAT: 46 found, 45 pass mod-97 = 97.8%

The numbers hold across two independent corpora, and vatNumber fill rose from 38.5% to 41.8% after the under-collection fix described in the FAQ below.

Which lists convert — yield by business type

The same 598-domain run, split by the OpenStreetMap key each domain came from. This is the single most useful number for planning a job, and it varies by more than 2x:

Domains came fromAttemptedBilledYield of reachable
office (agencies, professional services, B2B)873553.8%
shop (retail)1674032.8%
tourism29733.3%
craft (trades)14325.0%
amenity (cafés, pubs, restaurants, banks)2835625.3%
all59814832.7%

A café is usually a sole trader or a partnership trading under the owner's own name, and reg. 25's company disclosure does not bind one — there is no company number for it to publish. A professional services firm is almost always a limited company or an LLP. Feed this Actor a B2B list and the hit rate roughly doubles.

A real row, from that run

Not a mock-up — rox.co.uk, exactly as delivered (long arrays trimmed):

{
"domain": "rox.co.uk",
"resolvedUrl": "https://www.rox.co.uk/",
"disclosureUrl": "https://www.rox.co.uk/contactus",
"disclosureSource": "legal-page",
"discoveryChannel": "anchor",
"pagesParsed": 2,
"pagesChecked": 3,
"registeredName": "ROX (UK) LTD",
"registeredNameSource": "suffix",
"companyName": "ROX (UK) Ltd",
"legalForm": "Private limited company",
"companyNumber": "SC216217",
"companyNumberRaw": "SC 216217",
"companyNumberSource": "jurisdiction",
"companyNumberFormatValid": true,
"companyNumberScheme": "GB-COH",
"jurisdiction": "Scotland",
"jurisdictionStated": "Scotland",
"registerUrl": "https://find-and-update.company-information.service.gov.uk/company/SC216217",
"registeredOffice": "ROX (UK) LTD, 42-43 Argyll Arcade, Glasgow, G2 8BG",
"registeredOfficePostcode": "G2 8BG",
"registeredOfficeCity": "Glasgow",
"email": "help@rox.co.uk",
"emails": ["help@rox.co.uk", "marketing@rox.co.uk"],
"phone": "+448081646448",
"socialLinks": ["https://www.instagram.com/ROXJewellery", "https://www.tiktok.com/@roxjewellery"],
"country": "United Kingdom",
"status": "ok",
"fieldCount": 12,
"elapsedMs": 4455
}

Note companyNumberRaw: "SC 216217" — the page prints the prefix with a space, and the canonical SC216217 is what goes to Companies House. That is the kind of detail a digits-only regex loses.


🧰 Every input

InputWhat it does
UK domainsBare domains, homepage URLs or direct legal-page URLs. Any TLD
Start URLsThe same list as requestListSources, so Make / Zapier / Clay / Sheets can pass it natively
Enrich an existing datasetDataset ID of a previous run — the real agency workflow
Domain list file URLA CSV / TXT / JSON / JSONL file, for lists too big to paste
Suppression list / previous datasetNever re-deliver, and never re-charge for, a company you already bought
Max results (billed rows)Hard cap on rows delivered AND billed
Max domains attemptedSample a big list cheaply
Max discovery requests / pages parsed per domainThe two cost levers
Discovery channelsTurn off sitemap / wp-json / path-guess to make a big run much cheaper
Proxy, proxy country, residential escalation, Unblocker escalationThe full transport ladder
TLD filterOff by default, deliberately — see below
Only rows with a registry ID / valid VAT / a contactQuality gates. Filtered rows are never charged
JurisdictionsKeep only England & Wales, Scotland, Northern Ireland or overseas-registered companies
Minimum populated fieldsA hard quality floor
Email policyKeep all, role addresses only (info@, enquiries@), or named mailboxes only
Deduplicate byCompany number, else domain (recommended) — two domains owned by one company collapse to one billed row
Field extraction togglesVAT checksum, regulator, ICO, charity, officer, socials, policy URLs
Include unbilled miss rowsCoverage accounting: every domain that produced nothing, with the reason
Include per-field provenanceWhich URL each field came from
Flat columnsFlat CSV-ready row, or grouped company{} registry{} contact{} people{} policies{}

Example:

{
"domains": ["rox.co.uk", "batchd.co.uk", "nq64.co.uk", "alzscot.org"],
"maxItems": 1000,
"requireRegistryId": true,
"dedupeBy": "company-number-then-domain"
}

💷 Pricing

Pay per result — $0.006 per trading disclosure returned.

You are chargedYou are NOT charged
Each UK company whose disclosure was found and parsed into a lead carrying at least one registry identifierA host that does not resolve
A host that refused us (403 / challenge)
A domain that publishes no trading disclosure
A duplicate collapsed by your dedupe key
A row your own filters removed
An unbilled coverage row (includeMissRows)

Delivery and billing are atomic (Actor.pushData(record, 'disclosure-scraped')), so if you hit a charge cap you can never keep a row you were not billed for, or be billed for a row you did not get. On the 598-domain run above, delivered rows and chargedEventCounts matched exactly: 148 and 148. There is no start fee and there are no stacked auto-events — one event, one price.

For context, measured: 148 billed rows from 598 cold UK domains, so a 1,000-domain list typically costs around $1.50, not $6.


❓ FAQ

Is this legal to collect? The fields come from a disclosure the company is legally required by the Companies Act to publish on its own website. That is about as public as company data gets. You are still responsible for the target site's Terms of Service and for how you use the output — see Legal, below.

Does it work on .com domains? Yes, and this matters more than it sounds. Measured on a country-wide OpenStreetMap pull of every UK office, shop and craft with a website — 46,863 unique business hosts — only 66.3% are .uk of any kind. 13,491 are .com, plus .org, .net, .co, .scot, .london and more. Filtering the corpus to .uk would silently discard about a third of it, skewed toward the larger companies. There is no TLD filter by default; it is an opt-in input.

Does it handle Scottish, Northern Irish and LLP numbers? Yes. SC (Scotland), NI (Northern Ireland), OC / SO / NC (LLPs), LP / SL / NL (limited partnerships), FC / SF / NF (overseas), R + 7 digits (pre-partition Northern Ireland), plus the society, assurance, protected-cell, CIO, Royal-charter and government ranges — and bare 8-digit England & Wales numbers. A digits-only regex under-collects badly: several disclosures in the first sample were SC-prefixed, and one real company publishes a five-digit number (32762, Companies House 00032762) which a \d{6,8} regex drops entirely.

Is the VAT number actually checked, or just extracted? Checked. Every GB VAT number is run through the published mod-97 checksum, in both the standard and the "97-55" variant, and the result and the variant are in the row. The 12-digit branch form validates on its first nine digits; the GBGD### and GBHA### government forms have no checksum and are validated on their published ranges instead.

Why isn't the company number checksum-validated too? Because Companies House numbers do not have a checksum. companyNumberFormatValid is a format and known-prefix check and the field is named accordingly. Any actor claiming to "validate" a UK company number without a register call is claiming something that does not exist.

Does it find emails hidden behind Cloudflare? Yes. Cloudflare rewrites mailto: links on proxied pages into /cdn-cgi/l/email-protection#<hex> and renders the literal text [email protected]. This Actor decodes them. Without that, a large slice of UK SME sites ship with email: null while the address sits right there in the bytes.

What about the charity number — Scottish charity numbers look like company numbers? They do, and that is a real trap: alzscot.org is company SC149069 and Scottish charity SC022315, one line apart. They are parsed into separate fields with a nearest-label rule, so the charity number never ends up in companyNumber.

Why do so many domains return nothing? Three different reasons, kept apart in RUN_SUMMARY and none of them charged. On the 598-domain run: 96 dead hosts (16% — any OSM-sourced list carries stale website tags), 49 refused, and 303 that publish no disclosure. That last group is the biggest and it is mostly genuine: sole traders and partnerships trading under the owner's own name have no company number to publish, and a long tail of micro-businesses is simply non-compliant with reg. 25.

How do you know the "publishes no disclosure" ones really publish nothing? Because they were re-probed. 60 of those 303 were run again through a deliberately extravagant cascade — 30 requests, 10 pages, 26 guessed paths, sitemap, WordPress index, JS bundles and the Unblocker escalation switched on. 4 of the 60 (6.7%) changed their mind; the other 56 genuinely publish nothing findable. So the default settings leave roughly 7% of that bucket on the table, on purpose, because recovering it costs about four times the requests. If you want them, raise Max discovery requests per domain and Max pages parsed, and switch on the Unblocker escalation — the levers are all inputs, and the rows you do not get are not charged either way.

Can I get only the companies with a VAT number / only Scottish companies / only ones with an email? Yes — requireValidVat, jurisdictionFilter and requireContact. Filtered rows are never charged, so these are cost controls as well as quality controls.

Can I run it monthly without paying twice for the same company? Yes. Pass the previous run's dataset ID as previousDatasetId; every id it already delivered is suppressed before a single request is made.

How do you know the parser is not just missing fields that are there? Because it was tested in the negative direction, which ordinary testing cannot do. 144 of the delivered pages were re-fetched and re-scanned with a separately written implementation of the GB mod-97 checksum — a 9-weight dot product, where the parser uses a 7-weight sum compared against the check digits, so the two cannot share a bug. Results: 0 disagreements on every VAT number emitted, 0 non-deterministic re-parses, and 4 values the parser had missed out of 144 pages. Three of the four were the same fixable bug (the VAT label separated from its number by a clause — "The VAT number of 200 Degrees is: 284361686"); that is fixed, and those three strings are now regression assertions. The sweep was then repeated on a fresh 400-domain run with the fix in place: 108 pages re-read, 0 VAT numbers missed, 0 company numbers missed, 0 checksum disagreements, 0 non-deterministic re-parses.

The same sweep measured conditional fill — of the pages that actually carry a company-number label, how many yielded a number:

JurisdictionPages with a labelNumber emittedConditional yield
England and Wales102102100.0%
Scotland1515100.0%
Northern Ireland11100.0%

That is the number that tells you whether a parser works. The headline companyNumber fill of 85.8% is not a parser gap: where a company number is published, it is read, in every jurisdiction. The rest of the rows qualified on a VAT or charity number instead, because their page carries no company number at all.

How do I audit a field I do not trust? Turn on Include per-field provenance. Every field then carries the exact URL it was read from, so you can open the page and check it. disclosureUrl, companyNumberRaw and jurisdictionStated are there for the same reason.

Does it respect robots.txt? There is a toggle, off by default. Measured on a UK sample: of the domains that served a parseable robots.txt at all, 0 disallowed any of /, /terms, /terms-and-conditions, /legal, /privacy-policy, /about-us, /contact — these are pages sites want indexed. Turn it on if your own compliance policy requires it; it costs one extra request per domain.

Will it break on Cloudflare-protected sites? Some. The Actor retries a genuine refusal once on a residential GB IP — measured on the 598-domain run: 128 escalations, 26 recovered. There is an opt-in second escalation to Apify Unblocker, which recovered 4 of the 5 hardest refusals in ladder testing, where both the datacenter and the residential IP got a Cloudflare managed 403 (those same hosts also serve a plain home broadband IP a 202 + 170-byte JS challenge, so the wall is real and is not the Apify proxy). Blocked hosts are reported as blocked with the reason, and are never charged.

What if I already have a domain list in a Google Sheet / Clay / a previous Actor? Use startUrls (requestListSources), domainsFileUrl (a CSV/TXT/JSON URL) or sourceDatasetId (another Actor's output). They all merge and deduplicate.


⚠️ Honest limits

  • This is an enrichment tool, not a discovery tool. It does not find UK companies for you; it turns the domain list you supply into company records.
  • It reads what the site publishes, nothing more. It does not call the Companies House API, so it cannot tell you whether a company is still active, who its directors are, or whether the number the site prints is genuinely theirs. registerUrl is provided so you can check in one click.
  • Companies House numbers have no checksum (repeated because it matters): companyNumberFormatValid is a format and prefix check.
  • A named officer is rare — about 1.4% fill. UK trading-disclosure rules, unlike the German Impressum, do not require naming a director on the website. The field is extracted where a page labels one and is honestly empty the rest of the time.
  • ICO registration is rare too — about 4.5%. Kept because when it is there it is unambiguous.
  • registeredOffice is often an accountant's address. That is what the company filed; it is the registered office, not necessarily where they work. addressLine is the trading address when the site publishes a different one.
  • About 1 domain in 4 on a cold list yields a row (148 of 598 measured; 32.7% of the domains that were actually reachable). The three kinds of nothing are itemised in RUN_SUMMARY and none are charged. If you need a higher hit rate, feed it a list of limited companies rather than a general business list — sole traders have no company number to publish.
  • A .com in a UK list is sometimes not a UK entity. One sampled site was a Netherlands operator with a KvK number and an NL VAT id; the row records vatCountry: "NL" honestly rather than forcing it into a GB field.

This Actor reads statutory public disclosures — the trading-disclosure statement that Companies Act 2006 s.82 and the Names and Trading Disclosures Regulations 2015 reg. 25 require UK companies to publish on their own websites, together with the contact details published alongside them.

  • You are responsible for complying with each target site's Terms of Service.
  • Output may contain personal data (a named director, a personal email address). Handling it is your responsibility under UK GDPR / the Data Protection Act 2018, and any outreach is yours to make compliant with PECR and the Privacy and Electronic Communications Regulations.
  • This is not a credit, risk or due-diligence product. It reports what a company published; it does not assess that company.
  • No login, no paywall and no credential is used or required at any point.

Part of a family of statutory-disclosure scrapers: DACH Impressum, French mentions légales, Spanish aviso legal — and now the UK.