French SIRET Luhn check
73282932000074 passes: the Luhn check over all fourteen digits holds, and its first nine digits, the SIREN 732829320, pass their own check too, leaving 00074 as the establishment's NIC. Each check is reported separately. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Number
- 73282932000074
- Input
- 73282932000074
- Siren
- 732829320
- Nic
- 00074
- Length
- 14
A French SIRET is the fourteen-digit identifier that names a specific establishment of a company registered in France. The first nine digits are the SIREN of the legal entity; the last five form the NIC that distinguishes one site, warehouse, or office from another under the same company. Both layers embed Luhn check digits so a single mistype or swapped pair usually fails before the number is stored on an invoice, supplier master record, or onboarding form. This capability implements that local arithmetic only: it requires a pure fourteen-digit string, runs the classic Luhn algorithm over all fourteen digits, recomputes Luhn validity on the nine-digit SIREN prefix, and returns a structured verdict with the SIREN, NIC, and separate flags for each check.
How French SIRET and SIREN Luhn checks work
Under the French business register rules used for SIREN and SIRET identifiers, a SIREN is always nine decimal digits that identify a legal entity for its entire life, and a SIRET is always fourteen digits that identify one establishment: the nine-digit SIREN plus a five-digit NIC. Both numbers carry a check digit produced by the classic Luhn mod-10 algorithm so that single-digit mistakes and most adjacent swaps are caught before the number is printed on a Kbis extract, invoice header, or banking mandate.
To validate a full SIRET, take the fourteen-digit string and apply Luhn from the right: do not double the rightmost digit; double every second digit walking left; when twice a digit exceeds nine, subtract nine; sum every weighted value; the number is Luhn-valid when that sum is divisible by ten. Separately, take the first nine digits as the SIREN prefix and run the same Luhn rule over those nine digits alone. A well-formed establishment number should pass both checks: the full fourteen-digit SIRET Luhn and the embedded SIREN Luhn.
The algorithm is deterministic and local: no INSEE registry call, no clock, and no randomness. Compared with generic tax-ID format tools or card Luhn checkers, the search intent here is narrow: people who need a French SIRET Luhn validator for fourteen-digit establishment numbers, not a multi-country tax format guesser or a payment-card tool.
Where French SIRET Luhn checks fit real workflows
Accounting and e-invoicing platforms receive fourteen-digit SIRETs on supplier invoices and must reject a mistyped establishment number before a purchase order, payment, or tax archive is written. Marketplace and logistics onboarding flows collect a SIRET for each warehouse or shop and need an immediate local check so a single transposition does not create a phantom establishment and a failed bank or tax submission later.
ERP and CRM import jobs walk every SIRET column in a CSV or partner feed, call this validator, and quarantine rows where valid is false—catching both human edits and off-by-one bugs in generators that only recompute SIREN without rechecking the full fourteen-digit string.
Do not treat a passing SIRET check as proof that the establishment is currently registered and open with INSEE, that the company is solvent, or that identity has been verified; it only proves the Luhn digits are consistent under the weights used for French SIRET and SIREN numbers. Handle real SIRETs as commercial identifiers: limit access in logs, avoid shipping full numbers to third-party analytics, and prefer last-four masking in application telemetry when a full number is not required for the audit trail.
What you can do with it
Audit SIRET columns in ERP master data
Batch-validate every fourteen-digit SIRET in a supplier or customer CSV and quarantine rows whose full SIRET Luhn or SIREN prefix Luhn no longer matches, before tax or banking exports run.
FAQ
What is a French SIRET number?
It is a fourteen-digit establishment identifier: the first nine digits are the company SIREN, and the last five are the NIC for that site. Both layers use Luhn check digits so typing and scanning errors are usually caught before storage.
What is the difference between SIREN and SIRET?
SIREN is nine digits identifying the legal entity. SIRET is fourteen digits identifying one establishment: SIREN plus a five-digit NIC. This capability validates the full SIRET and separately checks the embedded SIREN prefix.
What happens with wrong length, letters, or hyphens?
Failed shape-validation tasks are not billed. A fourteen-digit string with a wrong check digit returns valid false without throwing.
Is the French SIRET Luhn check free?
The browser tool is free and runs locally.
Why does the tool run two separate checks?
A SIRET holds two layers: the company's SIREN and the establishment's NIC. Checking all fourteen digits and the nine-digit prefix separately shows whether a mistake sits in the company part or elsewhere in the number; the SIRET is valid only when both pass.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/siret-france \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"73282932000074"}'const res = await fetch("https://api.kit.forhosting.com/enc/siret-france", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"number": "73282932000074"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/siret-france",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"number": "73282932000074"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/siret-france", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"number":"73282932000074"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"number":"73282932000074"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/siret-france", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"number": "73282932000074"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.siret_france",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Non-numeric characters and wrong lengths fail with invalid_input instead of silent stripping, so you never persist a half-cleaned identifier. The same pure arithmetic runs free in the browser and at the published API price, with no network lookup of INSEE or company registries and no claim that a valid checksum means the establishment is active, open, or free of fraud.
How French SIRET and SIREN Luhn checks work
This tool reports siret_luhn and siren_valid independently, and sets valid true only when both pass, so you can see whether a failure is in the establishment string as a whole or specifically in the company prefix.
Input contract, response fields, and error behaviour
Send a number field that contains only characters zero through nine. Wrong length is an explicit error that states you need fourteen digits and reports the length you sent, so client forms can show a clear message without guessing. Empty strings, missing number, floats, negatives, and non-string objects fail before any Luhn sum runs and are not billed. Failed validation tasks that reject bad shape are not charged. Spaces, hyphens, letters, and decimal points are rejected as non-numeric input with invalid_input so a silently stripped value never reaches storage. The engine requires exactly fourteen digits: nine for the SIREN prefix and five for the NIC, including the trailing check digit of the full SIRET. The response always includes input (the normalized fourteen-digit string), valid (true only when both Luhn checks pass), siret_luhn (Luhn over all fourteen digits), siren (the first nine digits), siren_valid (Luhn over those nine digits alone), nic (the last five digits), length fourteen, and algorithm siret-france-luhn. Alias keys such as digits, siret, text, value, n, and code are accepted for the same payload field so integrations that already speak “siret” do not need a rename. Because the path is pure parse with no clock, random source, or network, the same JSON body always yields the same JSON result on the free browser tool and on the API at $0.002 per successful request. Prefer this endpoint when you gate a supplier form, invoice capture pipeline, or ERP load on a full establishment identifier from a user, partner file, or OCR step. A well-formed fourteen-digit string that simply has a wrong check digit returns valid false with siret_luhn false without throwing, so batch jobs can quarantine rows instead of aborting.
Where French SIRET Luhn checks fit real workflows
Support agents recompute siret_luhn and siren_valid when a customer reads a number over the phone or pastes it from a PDF Kbis extract, catching mistypes before a contract or mandate is issued.
Integration use cases
Validate supplier SIRETs on invoice capture
When OCR or a form submits fourteen digits from an invoice header, call this validator and block booking when valid is false, using siret_luhn and siren_valid to explain whether the establishment string or the company prefix failed.
Gate marketplace or logistics onboarding
Require a pure fourteen-digit SIRET at seller or warehouse signup, reject non-numeric and wrong-length input with invalid_input, and only create the establishment record when both Luhn checks pass.
Technical questions
How does this tool validate a SIRET?
POST a pure fourteen-digit string in number. The response reports siret_luhn over all fourteen digits, siren_valid over the first nine digits, and valid true only when both checks pass, plus siren, nic, and length.