Generator · Polish data

Polish ID card number

Endpoint GET /v1/pl/id-card

What it covers

Returns a valid Polish ID card number (numer dowodu osobistego) with a correct checksum and an expiration date (a random day less than ten years ahead). Use `format` to choose between compact (`ABA300000`) and spaced (`ABA 300000`) rendering. Set `invalid=true` to get a number with a deliberately wrong check digit, and `expired=true` to get a past expiration date — both for testing validators.

How it’s calculated

The Polish ID-card (dowód osobisty) number carries a single mod-10 check digit sitting at the fourth position, computed from a weighted sum of the three series letters and five trailing digits using the fixed weights 7,3,1,7,3,1,7,3.

Algorithm

  1. A Polish ID-card number has nine positions: three uppercase series letters (indices 0-2), one check digit (index 3), and five trailing digits (indices 4-8). Rendered compact it reads as SERIES + CHECK + TRAILING, e.g. `ABA` `3` `00000` = `ABA300000`.
  2. Assign each character a value: a digit '0'-'9' maps to its face value 0-9; an uppercase letter maps to its position in the alphabet plus 10, so A=10, B=11, C=12, ..., Z=35 (formula: codePoint('A') subtracted from codePoint(letter), plus 10).
  3. Lay the eight non-check characters over the fixed positional weights [7, 3, 1, (check slot - skipped), 7, 3, 1, 7, 3]. The weight at index 3 is null because that slot is the check digit itself and contributes nothing to its own sum.
  4. Multiply each character's value by the weight at its index and add them up: sum = 7*value(series[0]) + 3*value(series[1]) + 1*value(series[2]) + 7*value(trailing[0]) + 3*value(trailing[1]) + 1*value(trailing[2]) + 7*value(trailing[3]) + 3*value(trailing[4]).
  5. The check digit is that weighted sum taken modulo 10. No complement, no subtraction from the modulus, no overflow handling — the residue itself IS the check digit (0-9).
  6. Insert the check digit at index 3, immediately before the five trailing digits, to form the complete number.

Worked example

Series ABA, trailing digits 12345 → ABA?12345

Character values: A=10, B=11, A=10; trailing 1=1, 2=2, 3=3, 4=4, 5=5.
Apply weights 7,3,1 to the series: 7*10 = 70, 3*11 = 33, 1*10 = 10.
Skip index 3 (the check slot carries weight null).
Apply weights 7,3,1,7,3 to the five trailing digits: 7*1 = 7, 3*2 = 6, 1*3 = 3, 7*4 = 28, 3*5 = 15.
Weighted sum = 70 + 33 + 10 + 7 + 6 + 3 + 28 + 15 = 172.
Check digit = 172 mod 10 = 2.
Insert at index 3: full number = ABA212345 (compact), or ABA 212345 with a space.

The check digit is 2, giving the complete ID-card number ABA212345.

Edge cases

  • The three series characters are always letters A-Z in this generator, so they always contribute values in the range 10-35 (never a bare digit) — the letter-to-number mapping (A=10 … Z=35) is essential; treating a series letter as a face-value digit would produce a wrong check digit.
  • The check digit occupies index 3 — it is the FIRST of the six digits in the number part, not the last. A reader who appends the check digit to the end would place it wrong.
  • Every combination of series letters and trailing digits yields exactly one valid check digit (0-9); the generator has no rejection/retry loop because mod-10 always resolves to a single digit.

Gotchas

  • The weight at index 3 (the check slot) is null and skipped; in the source the placeholder character inserted there is a literal '0', but it never enters the sum because its weight is null — do not accidentally give it weight 7.
  • This is a plain modulo, not a mod-10 complement (10 - (sum mod 10)) and not Luhn. The residue itself is the answer, so a sum ending in 0 gives check digit 0.
  • Character values above 9 (letters) are used raw in the weighted sum — there is no digit-splitting or casting-out as in Luhn; A contributes its full value 10 times the weight.

Parameters

ParameterTypeDescription
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 cards from the rare corners of the format.
expiredbooleanReturn a card whose expiration date is in the past.
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"compact" | "with-space"Number rendering: compact or with a space. Default compact.
invalidbooleanReturn a number with a deliberately wrong check digit.
seedintegerInteger seed for reproducible output: the same seed always yields the same record.

Response fields

FieldTypeDescription
valuestringThe ID card number in the requested format.
seriesstringThe three uppercase series letters, e.g. "ABA".
numberstringThe six digits including the leading check digit, e.g. "300000".
expirationDatestringThe card expiration date, ISO `YYYY-MM-DD`. Past when `expired=true`.

Other generators for Poland

See all generators for Poland →

The same kind of identifier elsewhere

Try it

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