Generator · Polish data
Polish PESEL
Endpoint GET /v1/pl/pesel
What it covers
Returns a valid Polish PESEL with a correct checksum. Constrain the person with `sex` and any combination of age/birth-date filters; contradictory combinations are rejected with a 400. Set `invalid=true` to get a PESEL with a deliberately wrong check digit (birth date and sex stay valid), for testing checksum validators.
A PESEL encodes a real birth date, a sex, and an ordinal serial into eleven digits, then closes with a check digit. Because the birth century is folded into the month field, the same two month digits mean different centuries — a PESEL alone tells you the full birth date without a separate century field.
How it’s calculated
The eleventh digit is a weighted mod-10 check digit over the first ten digits.
Algorithm
- Take the first ten digits d₁…d₁₀ (date + serial, century already folded into the month).
- Multiply each by the repeating weight pattern 1, 3, 7, 9, 1, 3, 7, 9, 1, 3.
- Sum the ten products.
- Take that sum modulo 10.
- The check digit is (10 − (sum mod 10)) mod 10 — the final mod 10 turns a would-be “10” back into 0.
Worked example
4405140135? (a person born 1944-05-14, serial 0135)
4×1 = 4
4×3 = 12
0×7 = 0
5×9 = 45
1×1 = 1
4×3 = 12
0×7 = 0
1×9 = 9
3×1 = 3
5×3 = 15
sum = 4+12+0+45+1+12+0+9+3+15 = 101
101 mod 10 = 1
(10 − 1) mod 10 = 9The check digit is 9, so the full PESEL is 44051401359.
Edge cases
- The century is carried in the month, not a separate field: month digits have 80 added for 1800–1899, 0 for 1900–1999, 20 for 2000–2099, 40 for 2100–2199, and 60 for 2200–2299. So a January birth reads as month 01, 21, 41, 61, or 81 depending on the century.
- The serial’s last digit sets the sex: odd → male, even → female. Constraining sex therefore constrains the tenth digit’s parity, not a separate flag.
- With invalid=true the check digit is deliberately wrong while the birth date and sex stay valid — so a validator that only checks the date passes it, but one that verifies the checksum rejects it. That’s the point: it isolates checksum-validation bugs.
Gotchas
- A PESEL is not a random 11-digit string — the first ten digits must form a real calendar date after removing the century offset, or no amount of check-digit fixing makes it valid.
- Contradictory age/birth-date constraints (e.g. atAge with a bornOn that disagrees) are rejected with a 400 rather than silently ignored.
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 PESEL whose value is wrapped in a hostile encoding (untrimmed whitespace, invisible/zero-width characters, BOM, or bidi/combining marks). The eleven digits stay recoverable after normalisation; birthDate and sex stay clean. |
| invalid | boolean | Return a PESEL with a deliberately wrong check digit; birth date and 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-digit PESEL. |
| birthDate | string | The encoded birth date, ISO `YYYY-MM-DD`. |
| sex | "m" | "f" | Encoded sex: `m` (odd) or `f` (even) tenth digit. |
Other generators for Poland
The same kind of identifier elsewhere
Try it