Generator · Finnish data
Finnish henkilötunnus
Endpoint GET /v1/fi/henkilotunnus
What it covers
Returns a valid Finnish henkilötunnus (HETU, personal identity code) with a correct check character. Constrain with `sex` and age/birth-date filters (the full birth date and sex are encoded). Contradictory combinations are rejected with a 400. Set `invalid=true` for a deliberately wrong check character.
How it’s calculated
The Finnish henkilotunnus (HETU) check character is the 9-digit DDMMYYNNN value taken modulo 31 and indexed into the 31-character control alphabet "0123456789ABCDEFHJKLMNPRSTUVWXY".
Algorithm
- Form the 9-digit payload string DDMMYYNNN: two-digit day, two-digit month, two-digit year (year mod 100), then the three-digit individual number NNN. The century sign (+, -, A) is NOT part of this payload — it is dropped.
- Interpret the 9-digit string as a base-10 integer. (Leading zeros simply make the integer smaller; e.g. "010190123" is the integer 10190123.)
- Compute remainder = integer mod 31.
- Index the remainder (0-30) into the fixed control alphabet CHECK_ALPHABET = "0123456789ABCDEFHJKLMNPRSTUVWXY" (positions 0..30). The alphabet omits G, I, O, Q, Z to avoid confusion with digits/similar letters.
- The character at that position is the check character — the final (11th) character of the full HETU. The canonical HETU is DDMMYY + centurySign + NNN + checkCharacter, e.g. 131052-308T.
Worked example
Born 1 January 1990, individual number 123 → HETU 010190-123? (check character = ?)
Payload DDMMYYNNN = day 01, month 01, year 1990 mod 100 = 90, individual number 123 → "010190123".
As an integer this is 10190123 (the leading zero is not significant in the numeric value).
10190123 mod 31: 31 × 328713 = 10190103, and 10190123 − 10190103 = 20, so remainder = 20.
Index 20 into "0123456789ABCDEFHJKLMNPRSTUVWXY": positions 0-9 are digits 0-9, then 10=A, 11=B, 12=C, 13=D, 14=E, 15=F, 16=H, 17=J, 18=K, 19=L, 20=M.
Position 20 = 'M'.The check character is M, giving the full HETU 010190-123M.
Edge cases
- The century sign (7th character: '+' for 1800s, '-' for 1900s, 'A' for 2000s) is deliberately excluded from the checksum payload — the same DDMMYYNNN yields the same check character regardless of century.
- The individual number NNN encodes sex by parity: odd = male ('m'), even = female ('f'). This generator draws NNN in [2, 899] with the parity matching the requested sex.
- Every remainder 0-30 maps to a valid character, so the check-character step can never fail (the source treats an undefined lookup as unreachable).
Gotchas
- The control alphabet skips G, I, O, Q, and Z; it is exactly 31 characters (10 digits + 21 letters), matching the modulus 31.
- Individual numbers 000-001 and 900-999 are reserved (not issued to natural persons); this generator only emits 002-899.
- Because the payload is read as a plain integer, leading zeros in the date head do not change the numeric value — parse the 9 characters as one base-10 number rather than treating them as separate fields.
Parameters
| Parameter | Type | Description |
|---|---|---|
| atAge | integer | Exact age in years at request time. |
| bornAfter | stringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$ | Born after this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD). |
| bornBefore | stringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$ | Born before this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD). |
| bornOn | stringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$ | Born on a date or within a fragment: YYYY, YYYY-MM, or YYYY-MM-DD. |
| count | integer1–1000 | Number of records to return, 1–1000 (your plan may lower this). Omitted returns a single record; set it for a batch. |
| edge | boolean | Restrict output to edge-case values. |
| extreme | boolean | Return a correct value wrapped in a hostile encoding (untrimmed whitespace, invisible/zero-width characters, BOM, or bidi/combining marks). Homoglyphs are excluded so the value stays machine-parseable; it still validates after normalisation. |
| invalid | boolean | Return a HETU with a deliberately wrong check character; date/sex stay valid. |
| olderThan | integer | Minimum age in years at request time. |
| seed | integer | Integer seed for reproducible output: the same seed always yields the same record. |
| sex | "m" | "f" | Encoded sex: "m" or "f". |
| youngerThan | integer | Maximum age in years at request time. |
Response fields
| Field | Type | Description |
|---|---|---|
| value | string | The canonical 11-character HETU, e.g. `131052-308T`. |
| digits | string | The 9-digit `DDMMYYNNN` the check character is computed from. |
| birthDate | string | The encoded birth date, ISO `YYYY-MM-DD`. |
| sex | "m" | "f" | Encoded sex: `m` (odd) or `f` (even) individual number. |
Other generators for Finland
Finnish companyFinnish company nameFinnish email addressFinnish IBANFinnish personFinnish person nameFinnish product or service offeringFinnish vehicle registration plateFinnish Y-tunnus
See all generators for Finland →The same kind of identifier elsewhere
Austrian data · Austrian SVNRBelgian data · Belgian RijksregisternummerBulgarian data · Bulgarian EGNCroatian data · Croatian JMBGCroatian data · Croatian OIBCypriot data · Cyprus TICCzech data · Czech rodné čísloDanish data · Danish CPRDutch data · Dutch BSNEstonian data · Estonian isikukoodFrench data · French NIRGerman data · German Steuer-IdNrGreek data · Greek AFMGreek data · Greek AMKAHungarian data · Hungarian adóazonosító jelHungarian data · Hungarian személyi azonosítóHungarian data · Hungarian TAJIrish data · Irish PPSNItalian data · Italian Codice FiscaleLatvian data · Latvian personas kodsLithuanian data · Lithuanian asmens kodasLuxembourg data · Luxembourg matriculePolish data · Polish PESELPortuguese data · Portuguese NIFRomanian data · Romanian CNPSlovak data · Slovak rodné čísloSlovenian data · Slovenian davčna številkaSlovenian data · Slovenian EMŠOSpanish data · Spanish DNISpanish data · Spanish NIESwedish data · Swedish personnummer
Try it