Generator · Swedish data
Swedish personnummer
Endpoint GET /v1/se/personnummer
What it covers
Returns a valid Swedish personnummer with a correct Luhn check digit. Constrain with `sex` and age/birth-date filters (the full birth date is encoded). Contradictory combinations are rejected with a 400. Use `format` for the short/long rendering and `kind` for a samordningsnummer. Set `invalid=true` for a deliberately wrong check digit.
How it’s calculated
The 10th digit of a Swedish personnummer is a Luhn (mod-10) check digit computed over the nine preceding significant digits YYMMDDNNN.
Algorithm
- Assemble the 9 significant payload digits: the 6-digit birth-date head YYMMDD (two-digit year, two-digit month, two-digit day; for a samordningsnummer add 60 to the day before writing it), followed by the 3-digit individual serial NNN. The 9th digit (last of the serial) encodes sex: even = female, odd = male.
- Treat this 9-digit string as the Luhn payload; the check digit will sit immediately to its right as the 10th digit.
- Scan the 9 payload digits from RIGHT to LEFT. Starting with the rightmost payload digit, alternate a 'doubling' flag that begins TRUE (so the rightmost digit is doubled), then FALSE, then TRUE, and so on.
- For each digit: if the doubling flag is TRUE for that position, multiply the digit by 2 and, if the product exceeds 9, subtract 9 from it. If the flag is FALSE, take the digit unchanged.
- Add all these processed values together to get a running sum.
- Compute the check digit as (10 - (sum mod 10)) mod 10. The outer mod 10 makes a remainder of 0 yield a check digit of 0.
- Append this single check digit as the 10th and final digit, giving YYMMDDNNNC.
Worked example
Personnummer for a female born 1990-05-14 with serial 123: 900514123? (find the check digit)
Significant payload digits = head 900514 + serial 123 = 900514123 (9 digits).
Scan right to left with doubling starting TRUE at the rightmost digit:
pos '3' (double): 3*2=6 -> 6
pos '2' (single): 2
pos '1' (double): 1*2=2 -> 2
pos '4' (single): 4
pos '1' (double): 1*2=2 -> 2
pos '5' (single): 5
pos '0' (double): 0*2=0 -> 0
pos '0' (single): 0
pos '9' (double): 9*2=18 -> 18-9=9
Sum = 6+2+2+4+2+5+0+0+9 = 30
Check digit = (10 - (30 mod 10)) mod 10 = (10 - 0) mod 10 = 0The check digit is 0, so the full personnummer is 9005141230.
Edge cases
- Samordningsnummer (coordination number): the day-of-month field has 60 added to it before the checksum is computed, so the same Luhn algorithm runs over the offset day (e.g. day 14 becomes 74).
- The 9th significant digit (last digit of the serial NNN) encodes sex by parity: even = female, odd = male. When a sex is forced the generator draws it as nextInt(0,4)*2 + parity to guarantee the right parity, then still runs the plain Luhn over all nine digits.
Gotchas
- Only the nine digits YYMMDDNNN feed the Luhn sum — the two-digit year is used, NOT the full four-digit year and NOT any century/separator marker; the century (+/- for age 100) lives outside the checksummed digits.
- The doubling alternation starts TRUE on the rightmost payload digit (the check-digit generation convention), so it is the 9th significant digit that gets doubled first, not left undoubled.
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. |
| format | "short" | "long" | Rendering: short `YYMMDD-NNNC` (default) or long `YYYYMMDDNNNC`. |
| invalid | boolean | Return a number with a deliberately wrong Luhn check digit; date/sex stay valid. |
| kind | "personnummer" | "samordningsnummer" | Which kind to mint: ordinary `personnummer` (default) or `samordningsnummer`. |
| 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 number in the requested format (short or long). |
| digits | string | The canonical 10-digit `YYMMDDNNNC`, no separator. |
| birthDate | string | The encoded birth date, ISO `YYYY-MM-DD` (the true day). |
| sex | "m" | "f" | Encoded sex: `m` (odd 9th digit) or `f` (even 9th digit). |
Other generators for Sweden
Swedish companySwedish company nameSwedish email addressSwedish IBANSwedish organisationsnummerSwedish personSwedish person nameSwedish product or service offeringSwedish vehicle registration plate
See all generators for Sweden →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 isikukoodFinnish data · Finnish henkilötunnusFinnish data · Finnish Y-tunnusFrench 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 NIE
Try it