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

  1. 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.
  2. Interpret the 9-digit string as a base-10 integer. (Leading zeros simply make the integer smaller; e.g. "010190123" is the integer 10190123.)
  3. Compute remainder = integer mod 31.
  4. 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.
  5. 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

ParameterTypeDescription
atAgeintegerExact age in years at request time.
bornAfterstringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born after this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD).
bornBeforestringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born before this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD).
bornOnstringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born on a date or within a fragment: YYYY, YYYY-MM, or YYYY-MM-DD.
countinteger1–1000Number of records to return, 1–1000 (your plan may lower this). Omitted returns a single record; set it for a batch.
edgebooleanRestrict output to edge-case values.
extremebooleanReturn 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.
invalidbooleanReturn a HETU with a deliberately wrong check character; date/sex stay valid.
olderThanintegerMinimum age in years at request time.
seedintegerInteger seed for reproducible output: the same seed always yields the same record.
sex"m" | "f"Encoded sex: "m" or "f".
youngerThanintegerMaximum age in years at request time.

Response fields

FieldTypeDescription
valuestringThe canonical 11-character HETU, e.g. `131052-308T`.
digitsstringThe 9-digit `DDMMYYNNN` the check character is computed from.
birthDatestringThe encoded birth date, ISO `YYYY-MM-DD`.
sex"m" | "f"Encoded sex: `m` (odd) or `f` (even) individual number.

Other generators for Finland

See all generators for Finland →

The same kind of identifier elsewhere

Try it

Generate a live example below — every response is valid by format and entirely synthetic.