Mentions Legales Scraper - French SIREN, RCS, TVA & Contacts avatar

Mentions Legales Scraper - French SIREN, RCS, TVA & Contacts

Pricing

$4.00 / 1,000 per legal-notice lead returneds

Go to Apify Store
Mentions Legales Scraper - French SIREN, RCS, TVA & Contacts

Mentions Legales Scraper - French SIREN, RCS, TVA & Contacts

Turn French business domains into registry-grade B2B leads from each site's legally-mandated mentions legales page: SIREN, SIRET, RCS + greffe, TVA, capital social, APE, directeur de la publication, hebergeur, email, phone and address. No login, no API key.

Pricing

$4.00 / 1,000 per legal-notice lead returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

🇫🇷 Mentions Légales Scraper — French company leads with a Luhn-checked SIREN

Paste a list of French business domains (or point this Actor at another Actor's dataset) and get back one clean B2B/KYB lead per domain, read off each site's statutory mentions légales page: the legal entity name and form, the SIREN checked against the Luhn algorithm, the SIRET, the RCS entry + greffe, the TVA intracommunautaire number, the capital social, the APE/NAF code, the directeur de la publication, the hébergeur, and a contact email, phone and postal address — for $4 per 1,000 leads.

Why a legal notice and not a directory? Because LCEN art. 6-III (loi n° 2004-575) obliges every commercial French website to publish one. The corpus is therefore the whole French commercial web — not one directory's member list — and every field is a public disclosure the company published about itself, by law.


✅ What does the Mentions Légales Scraper do?

For each domain you give it, two plain HTTP hops. No browser, no login, no API key.

  1. Discovery. Fetch the homepage and rank every <a href> on both its href and its anchor text — exact "Mentions légales" (100) beats a text match (90) beats an href match (85) beats "Informations légales" (80) beats "Legal notice" (70), with CGV / CGU / cookies / privacy links demoted to 30 so a combined footer link can still be a last resort without outranking the real thing. If nothing is linked, fall through to the XML sitemap, the WordPress REST page index, then 15 conventional paths.
  2. Resolution. Fetch the winning candidate, gate it on a statutory content marker — a bare HTTP 200 is not enough — then read the fields out of the page text with anchored, case-sensitive patterns.
  • 🎯 Guessing /mentions-legales is not the job. On the recon corpus a naive path guess hit 2 of 10 domains. Ranked footer anchors won 73 of the 76 leads in the benchmark below; guessed paths won 2 and the sitemap won 1. The engineering is in the ranking, not the guessing.
  • 🧮 It derives the SIREN from the TVA number, then Luhn-checks it. A French TVA number is FR + a 2-digit key + the SIREN, so it is an exact algebraic container for the registry id. On delitaly.fr a plain RCS regex pulled a 9-digit window out of the TVA string and emitted SIREN 624223821 for a company whose real SIREN is 422382184. This Actor prefers TVA → labelled SIREN → SIRET → RCS, records the disagreement in sirenConflict, and emits sirenValid so you can see the checksum result rather than trust it silently.
  • 📍 The postcode comes from the parsed address, never from the page. A page-wide \d{5} scan once emitted Beverly Hills' 90210 for a company in Toulouse (31100). postalCode and city are only ever read out of an address block that also carried a street.
  • 🏛 An RCS number that disagrees with the SIREN is dropped, not published. By French law the RCS registration number is the company's SIREN. When they differ, the RCS statement on the page belongs to another entity — usually the web agency that built the site — so publishing it as this company's register entry would be wrong. The greffe city is kept, the mismatched number is moved to rcsConflict.

📊 Measured, from real runs

Everything below is from actual runs, not estimates.

End-to-end over 150 real French SME domains

Sourced from OpenStreetMap (shop / office / craft entries carrying a website tag) across Paris, Toulouse, Bordeaux, Nantes, Strasbourg, Marseille and Lille — a realistic buyer list, not a hand-picked one. Apify datacenter proxy, concurrency 12, default settings.

OutcomeDomainsShareBilled?
ok — a parsed, billable lead7651 %yes
🔁 duplicate — same SIREN as a row already delivered32 %no
no_legal_page — the site publishes none5336 %no
💀 unreachable — dead host (NXDOMAIN / TLS / refused)1510 %no
🔴 blocked by an anti-bot wall21 %no

134 of the 149 domains were reachable; 79 of those 134 (59 %) published a findable legal notice, and 76 became billable leads after the SIREN-level dedupe. One duplicated input line was collapsed before it cost a request. A second run of the same list a few hours earlier returned 81 leads — expect a few points of run-to-run variance from transient host failures.

A tighter, curated 76-domain recon corpus scored higher — 46 of 62 reachable domains = 74 %. Both numbers are real; which one you see depends on how clean your list is. Budget somewhere between them.

Per-field fill, over the 76 delivered leads

FieldFillFieldFill
companyName97 %socialLinks72 %
addressLine92 %legalForm63 %
postalCode92 %shareCapital58 %
city92 %publicationDirector50 %
email76 %hostingProviderAddress46 %
phone76 %privacyPolicyUrl45 %
siren71 %siret41 %
hostingProvider71 %rcsNumber38 %
vatNumber34 %cgvUrl30 %
rcsCity29 %apeCode24 %
legalRepresentative20 %dpoContact11 %

Any registry id (SIREN, SIRET or TVA): 71 % · any contact (email or phone): 92 % · postal address: 92 %. Median row carries 11 of the 17 value fields (p90 = 14, best = 15).

The SIREN was derived from the TVA number on 26 rows, from the SIRET on 15, from the RCS entry on 7 and from an explicit label on 6. 53 of the 54 SIRENs passed the Luhn checksum; the one failure is flagged sirenValid: false rather than dropped. The cross-field guards fired for real: 1 sirenConflict and 5 rcsConflict rows would have shipped another company's register entry without them.

Transport

Sustained-load tested on the winning transport (got-scraping over the Apify datacenter proxy, ~350 sequential calls in 4 independent batches): 61 of 62 reachable domains usable = 98.4 %, with zero 403s, zero CAPTCHAs and zero challenge interstitials across the SME corpus. Residential exit nodes changed nothing there, so datacenter is the default and residential is a per-block escalation, not the norm. Chromium is never launched. 512 MB, 847 requests for 149 domains ≈ 5.7 requests per domain; 20 blocks escalated to residential, 2 recovered.

Per-domain latency on delivered rows: p50 4.5 s, p90 13.5 s, max 36.3 s — which is why perDomainTimeoutSecs exists.


⚠️ Honest limits — read these before you buy

  • Roughly a third of reachable French SME sites publish no legal notice at all. That is not a parser gap: those domains were re-probed through the sitemap (287- and 500-URL sitemaps read), the WordPress REST index, 15 guessed paths and /, /contact, /cgv, /conditions-generales-de-vente, /a-propos. They carry no SIREN, SIRET, TVA, RCS, capital or directeur de la publication anywhere on the site. They are LCEN-non-compliant micro-businesses. You are never charged for them.
  • Stale lists have dead hosts. 15 of 149 domains (10 %) did not resolve at all — verified identical from a home IP, a datacenter IP and a residential-FR IP, so these are stale directory entries, not blocks. Never charged.
  • A CDN-fronted enterprise tail is genuinely walled. Of 10 large French brands probed, datacenter cleared 6 and residential-FR cleared 7; leroymerlin.fr, fnac.com, decathlon.fr and boulanger.com refused both. This Actor is built for the SME long tail, which is unaffected. Escalate to residential on block is on by default and is what recovers the middle of that band.
  • This Actor does not confirm the SIREN against INSEE/Sirene. It reports what the company published, plus a checksum. A registry cross-check is a different data source and a different job.
  • legalRepresentative (gérant / président) fills on ~20 % of pages — French legal notices name the directeur de la publication far more often than the company officer.

🧾 Output

One row per domain. flattenOutput (default on) gives you flat columns for Sheets / Clay; turn it off for nested registry{} / people{} / contact{} / hosting{} / policies{} objects.

FieldDescription
domainRegistrable domain (eTLD+1, www-stripped) — the fallback stable id.
mentionsLegalesUrlThe exact page the data came from.
discoveryChannelanchor · sitemap · wpjson · guess · input — how the page was found.
companyNameThe legal entity name.
legalFormSAS · SASU · SARL · EURL · SA · SNC · SCI · SELARL · SCOP · EI · association loi 1901 · micro-entreprise. Matched case-sensitively, longest form first (SAS is never read as SA).
sirenThe 9-digit registry id.
sirenValidLuhn checksum result. false means the page carries a typo — the row is flagged, never silently dropped.
sirenSourcevat · label · siret · rcs — which statement the SIREN came from.
sirenConflictA second, disagreeing SIREN found on the page (the cross-field trap, surfaced instead of hidden).
siretThe 14-digit establishment id.
vatNumberTVA intracommunautaire, normalised (FR 62 422 382 184FR62422382184).
rcsCity / rcsNumberGreffe (register court) and the RCS registration number, cross-checked against the SIREN.
rcsConflictAn RCS number that disagreed with the SIREN — kept visible, not published as the company's.
shareCapital / shareCapitalCurrencyCapital social as a number ("2.500 €"2500, EUR).
apeCodeAPE / NAF activity code (7733Z).
publicationDirectorDirecteur / directrice de la publication.
legalRepresentativeGérant · président · représentant légal · dirigeant.
hostingProvider / hostingProviderAddressThe hébergeur — OVH, Scaleway, Ionos, o2switch, Gandi, Infomaniak, Hostinger, Wix, Shopify, Cloudflare, AWS… A resellable technographic signal.
dpoContactDélégué à la protection des données (GDPR/KYB buyers).
addressLine / postalCode / cityRegistered address, parsed as a block.
email / emails[]Contact addresses, mailto: preferred, obfuscated (at) forms decoded.
phone / phones[]Normalised to E.164 (01 23 45 67 89+33123456789).
socialLinks[]LinkedIn / Facebook / Instagram / X / YouTube / TikTok / Vimeo profiles on the page.
cgvUrl / privacyPolicyUrlThe site's CGV and politique de confidentialité.
stableIdThe Luhn-valid SIREN when present, else the registrable domain. The dedupe key.
fieldCount · status · missReason · fetchedAt · elapsedMsRow quality, outcome and provenance.

Example row (share-wood.fr, real output):

{
"domain": "share-wood.fr",
"mentionsLegalesUrl": "https://share-wood.fr/mentions-legales/",
"discoveryChannel": "anchor",
"companyName": "SHARE-WOOD",
"legalForm": "SAS",
"siren": "433115904", "sirenValid": true, "sirenSource": "vat",
"vatNumber": "FR35433115904",
"rcsCity": "Paris", "rcsNumber": "433115904",
"shareCapital": 214410.5, "shareCapitalCurrency": "EUR",
"apeCode": "7733Z",
"publicationDirector": "Romain ABBÜHL",
"hostingProvider": "SCALEWAY",
"hostingProviderAddress": "8 RUE DE LA VILLE L EVEQUE, 75008 PARIS",
"addressLine": "47, Boulevard Burel, 13014 Marseille",
"postalCode": "13014", "city": "Marseille",
"email": "contact@share-wood.fr", "phone": "+33465430300",
"stableId": "433115904", "status": "ok"
}

⌨️ Input

Five ways to hand over a list, because agencies do not all work the same way.

FieldWhat it is
domainsOne entry per company. A bare domain (donatek.fr), a homepage URL, or a direct mentions-légales URL — a direct URL skips the homepage hop entirely and costs one request.
startUrlsThe standard Apify request-list editor, so Make / Zapier / Google Sheets can hand over a URL list natively.
sourceDatasetId + domainFieldNameRead the domain list straight out of another Actor's dataset — the real agency workflow: enrich the output of a Maps or directory scrape.
domainsFileUrlA CSV / TXT / JSON / JSONL file at a URL, for lists too big to paste. The column is found by header name or by looking like a domain.
skipDomains + previousDatasetIdSuppression. Point previousDatasetId at last month's run and this month's re-run never re-buys a lead you already paid for.

Then the knobs that matter:

FieldDefaultWhat it does
maxItems1000Hard cap on rows delivered and billed. 0 = unlimited.
maxDomains0Cap on domains attempted — a different number, because yield is ~51-74 %.
discoveryChannelsall 4A real cost lever: anchors alone cost ~2 requests/domain, the full cascade up to 14.
maxDiscoveryRequestsPerDomain12Hard ceiling on the guessed-path channel.
perDomainTimeoutSecs60Per-domain deadline, so one slow host cannot stall the run (recon saw 130 s and 152 s outliers).
requestConcurrency101–30.
proxyConfigurationApify datacenterThe measured winner. Bring your own proxies if you prefer.
proxyCountrynoneFR / BE / CH / LU / MC / CA. Note: Apify datacenter proxies cannot be country-pinned (they answer HTTP 407), so choosing a country switches the run to residential exit nodes.
escalateToResidentialOnBlocktrueOne residential-FR retry on a real 403 or challenge — never on a dead host, never on a 404.
requireRegistryId / requireContact / minFieldsRequiredoffQuality floors. A row filtered out here is never billed.
emailPolicyallrole-only (contact@, info@…) or exclude-role (named mailboxes only).
dedupeBySIREN, else domainOr domain, siren, or none.
includeMissRowsfalseEmit an unbilled row with status + missReason for every dead / walled / notice-less domain, for coverage accounting.
includeRawText / includeRawHtmlfalseAttach the source for audit or your own LLM re-parse.
flattenOutputtrueFlat columns vs nested objects.
respectRobotsTxtfalseExposed as a switch. Measured: 0 of 10 French sites disallow the legal-notice path.
customUserAgent / extraHttpHeadersBring your own fingerprint.

Example input:

{
"domains": ["donatek.fr", "sapio-arts.fr", "https://pao-ceramique.fr/mentions-legales"],
"maxItems": 1000,
"requireRegistryId": false,
"includeMissRows": false
}

💰 Pricing

Pay per event — one event, mentions-legales-scraped, at $0.004 per delivered lead ($4 per 1,000).

Rows are delivered and billed atomically through the same call, so if you hit a charge cap you never keep a row you were not billed for, and never pay for a row you did not receive.

You are not charged for:

  • a domain whose host is dead,
  • a domain blocked by an anti-bot wall,
  • a domain that publishes no legal notice,
  • a duplicate collapsed by dedupeBy,
  • a row filtered out by requireRegistryId / requireContact / minFieldsRequired,
  • any includeMissRows coverage row.
Price per row
Generic EU imprint extractors$0.0025
Domain → SIREN lookups$0.0045 – $0.006
This Actor$0.004
Our own DACH Impressum scraper$0.015

At 51–74 % yield, a 1,000-domain list costs roughly $2.00 – $3.00 in event fees.


❓ FAQ

What is a "mentions légales" page? The legal notice every commercial French website must publish under LCEN art. 6-III / art. 19 (loi n° 2004-575 pour la confiance dans l'économie numérique). It identifies the publisher: company name, legal form, share capital, registered address, SIREN/RCS, TVA number, the directeur de la publication and the site's host.

Is this legal to scrape? These pages are statutory public disclosures that exist precisely to be read, and they are meant to be indexed — 0 of 10 French sites we checked disallow the path in robots.txt. You remain responsible for each site's Terms of Service, and for handling any personal data in the output (a named directeur de la publication, a personal email) under the GDPR. See the legal note below.

Why is siren only ~71 % and not 100 %? Because ~29 % of legal notices name a company and an address but no registry id — commonly auto-entrepreneurs and associations. Turn on requireRegistryId and those rows are neither delivered nor billed.

Can I run it on Belgian, Swiss or Canadian French-language sites? Yes — set proxyCountry and, if you want, tldFilter. The registry patterns (SIREN/SIRET/RCS/TVA FR) are French, so a .be or .ch site will return contact and address data but usually no French registry id.

How is a duplicate handled? Two ways. A repeated input line is collapsed at queue time, before it costs a single request. Two different domains that turn out to share one SIREN are collapsed at delivery time, before pushData — so a duplicate can never double-charge.

Can I get only rows with an email? Set requireContact: true. Rows without an email or phone are then neither delivered nor billed.

How do I re-run monthly without paying twice? Put the previous run's dataset id in previousDatasetId. Every stableId, domain and siren it contains is suppressed.

Does it need a browser or a residential proxy? No. Datacenter HTTP measured 98.4 % usable on the French SME corpus with zero CAPTCHAs. Residential is a per-block escalation for the CDN-fronted enterprise tail only.

Does it use the INSEE/Sirene API? No. It reports what the company itself published, plus an offline Luhn checksum. No external API calls, no keys, no rate limits.

What happens if my list is entirely dead domains? The run exits cleanly with zero billed rows and a status message telling you why. It only fails loudly when the transport itself is broken — 80 %+ of domains refused with a challenge — because that is a proxy problem, not an empty market.

Can I export to Google Sheets / Clay / HubSpot? Yes. Leave flattenOutput on and use Apify's CSV / Excel / JSON export or the dataset API.


This Actor reads statutory public disclosures that French law requires websites to publish, over ordinary HTTP requests to ordinary public pages. It does not log in, does not bypass any anti-abuse control, does not solve CAPTCHAs, and does not forge authentication. robots.txt compliance is available as an input switch (measured: 0 of 10 French sites disallow the legal-notice path).

Output may contain personal data — a named directeur de la publication, a named gérant, a personal email address. Under the GDPR you are the controller of what you do with it: have a lawful basis, honour erasure requests, and respect each site's Terms of Service. Scraping and using this data is your responsibility, not Apify's and not this Actor's.