SIREN / SIRET / French VAT validator
Check French business identifiers in bulk. The tool tells a SIREN (the company) from a SIRET (one of its sites) and checks that a TVA number's key matches its SIREN.
Nothing yet. Paste numbers or a page on the left, or load the sample.
Runs entirely in your browser. A passing check means the number is well-formed, not that it is registered or active. Categories are inferred from the number format.
What gets checked
- SIREN: 9 digits, Luhn checksum. Identifies the legal entity.
- SIRET: SIREN + 5-digit NIC, Luhn over all 14 digits (La Poste establishments use a sum-of-digits rule instead).
- TVA intracommunautaire: FR + 2-character key + SIREN; the numeric key is (12 + 3 × (SIREN mod 97)) mod 97.
- The legal form (SAS, SARL…) is not encoded in these numbers; the Sirene register holds it.
To confirm a number is registered and active, use INSEE Sirene. The government's Annuaire des Entreprises (INSEE Sirene data) shows status, legal form and NAF activity code for free.
Which number is which
| 9 digits | SIREN: the company |
| 14 digits | SIRET: one establishment of that company |
| FR + key + SIREN | EU VAT number |
| RCS + city + SIREN | Trade register entry (same SIREN) |
Run the same checks in your own code
def luhn(s: str) -> bool:
total = 0
for i, d in enumerate(map(int, reversed(s))):
if i % 2:
d *= 2
d = d - 9 if d > 9 else d
total += d
return total % 10 == 0
def siret_ok(s: str) -> bool:
s = s.replace(" ", "")
if len(s) != 14 or not s.isdigit():
return False
if s.startswith("356000000"): # La Poste
return sum(map(int, s)) % 5 == 0
return luhn(s)
def fr_vat_key(siren: str) -> str:
return f"{(12 + 3 * (int(siren) % 97)) % 97:02d}"
print(siret_ok("732 829 320 00074"), "FR" + fr_vat_key("732829320") + "732829320")Collect the numbers from company websites
A browser can't fetch other sites for you. Irmu fetches the page, handles rendering and blocking, and ai_query (+5 credits) returns the fields you ask for.
# Fetch a company's legal page with Irmu and let ai_query pull the IDs out,
# then validate them locally with the functions above.
import os, requests
resp = requests.get(
"https://app.irmu.com/api/crawl",
headers={"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"},
params={
"url": "https://example.com/legal",
"js": "true",
"ai_query": "Find the company name, legal form, SIREN or SIRET, RCS city and TVA number in the mentions légales on this page. Return JSON.",
},
timeout=120,
)
resp.raise_for_status()
print(resp.json()["data"])Build a verified company database
Fetch legal pages at scale with one API. 200 free credits every month, no card required.