Generator · Latvian data

Latvian personas kods

Endpoint GET /v1/lv/personas-kods

What it covers

Returns a valid Latvian personas kods with a correct check digit. Latvia does not encode sex. Use `standard` for the `legacy` (date-encoded) or `modern` (non-semantic, default) code; the age/birth-date filters apply to `legacy` only. Contradictory combinations are rejected with a 400. Set `invalid=true` for a deliberately wrong check digit.

How it’s calculated

The 11th digit of a Latvian personas kods is a weighted mod-11 check digit whose remainder is offset by 1 and then folded through mod 10 so it always lands on a single digit 0-9.

Algorithm

  1. Take the first ten digits of the personas kods (positions 1-10). For a legacy code this is DDMMYY (6 digits) + century digit (1 digit) + a 3-digit serial; for a modern code it is any 10 digits starting with 3. The 11th digit is the check digit being computed.
  2. Convert the ten-digit string to numeric digit values d[0]..d[9] (left to right).
  3. Apply the fixed position weights W = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9], pairing W[i] with d[i].
  4. Compute the weighted sum S = 10*d[0] + 5*d[1] + 8*d[2] + 4*d[3] + 2*d[4] + 1*d[5] + 6*d[6] + 3*d[7] + 7*d[8] + 9*d[9].
  5. Add 1 to the sum: T = 1 + S.
  6. Take T modulo 11 to get an intermediate value in 0..10.
  7. Take that result modulo 10. This folds the awkward residue 10 down to 0, guaranteeing a single digit 0-9. That value is the check digit.
  8. Append the check digit as the 11th digit to form the full personas kods.

Worked example

Legacy personas kods, birth date 31-12-1997 (century digit 1), serial 123: 3112971123?

First ten digits: 311297 (DDMMYY) + 1 (century, 1900s) + 123 (serial) = 3112971123
Digit values: d = [3, 1, 1, 2, 9, 7, 1, 1, 2, 3]
Weights:      W = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9]
Products: 3*10=30, 1*5=5, 1*8=8, 2*4=8, 9*2=18, 7*1=7, 1*6=6, 1*3=3, 2*7=14, 3*9=27
Weighted sum S = 30+5+8+8+18+7+6+3+14+27 = 126
T = 1 + 126 = 127
127 mod 11 = 127 - 121 = 6
6 mod 10 = 6

The check digit is 6, giving the full personas kods 31129711236.

Edge cases

  • Because the final step is (…mod 11) mod 10, the residue 10 collapses to 0 rather than being unissued — so, unlike many mod-11 identifiers (e.g. PL NIP), no ten-digit prefix is ever 'dead'. The check digit is always a valid 0-9.
  • Legacy codes carry a semantic 7th digit that marks the birth century: 0 → 1800s, 1 → 1900s, 2 → 2000s (see century.ts). The check-digit weight rule is identical regardless of century.
  • Modern (post-2017) codes are non-semantic: they start with 3, encode no birth date, yet use the exact same weights and formula for the check digit.

Gotchas

  • The formula is inline in the generator, NOT the shared mod11CheckDigit helper: it is (1 + weightedSum) % 11 % 10. The extra '+1' offset before the modulo is easy to miss and changes every result.
  • The weights [10, 5, 8, 4, 2, 1, 6, 3, 7, 9] are position-fixed left-to-right over the first ten digits; they are the same for both legacy and modern standards.
  • Digit strings must be handled as strings (leading zeros are significant, e.g. a DDMMYY head like 010100…); converting through Number would corrupt the payload.

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.
format"plain" | "with-hyphen"Rendering: bare 11 digits (default) or `DDMMYY-XNNNZ` with a hyphen.
invalidbooleanReturn a personas kods with a deliberately wrong check digit.
olderThanintegerMinimum age in years at request time.
seedintegerInteger seed for reproducible output: the same seed always yields the same record.
standard"legacy" | "modern" | "both"Standard: `legacy` (date-encoded), `modern` (non-semantic, default), or `both` (random per record).
youngerThanintegerMaximum age in years at request time.

Response fields

FieldTypeDescription
valuestringThe personas kods in the requested format.
digitsstringThe canonical 11-digit personas kods.
birthDate?stringThe encoded birth date, ISO `YYYY-MM-DD`; present only for `legacy` codes.

Other generators for Latvia

See all generators for Latvia →

The same kind of identifier elsewhere

Try it

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