# Se personnummer parse

`se-personnummer-parse` · version 1.0.0 · Identifiers & check digits · free, no key needed

Parse a Swedish personnummer/samordningsnummer: resolve its century, return birth date, sex and Luhn validity.

**Use when you need to: parse a swedish personnummer · get birth date from swedish personal identity number · validate a personnummer checksum.**

## Decide before calling

Read the [versioned contract](/v1/tools/se-personnummer-parse/versions/1.0.0) and the supported scope below. Reuse `se-personnummer-parse@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `se-personnummer-parse@1.0.0` for parse a swedish personnummer. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- parse a swedish personnummer
- get birth date from swedish personal identity number
- validate a personnummer checksum
- resolve the century of a 10 digit swedish id number
- is this a samordningsnummer coordination number
- swedish ssn sex digit
- check a svenskt personnummer med plus tecken

## Not supported

- reading the system clock to resolve the century (reference_date must be supplied for the short form)
- accepting a printed form with a space, dot, or any separator other than "-" or "+"
- looking up which real person a personnummer identifies

## Behavior

- value must be exactly 12 digits (long form, century explicit) or 6 digits + '-'/'+' + 4 digits (short form, 11 characters); any other shape throws invalid_input, no trimming.
- reference_date, when present, must be a real YYYY-MM-DD calendar date; it is required (else invalid_input, details.reason "reference_date_required") when value is the short form, because the two-digit year has no century of its own and this tool never reads the system clock; it is optional and has no effect on the result for the long form. When value is the short form, reference_date's year must also be at least 0200 (else invalid_input, details.reason "reference_date_out_of_range"), because an earlier year can make the resolved birth_year negative, which cannot be written as the 4-digit year in birth_date or normalized12; the bound does not apply to the long form.
- Century resolution (short form only): base = reference year when the separator is '-', or reference year - 100 when '+'; birth_year = base - ((base - YY) mod 100) using a true (non-negative) modulo. century_resolved is false for the short form and true for the long form (already explicit).
- is_coordination_number is true when the 2-digit day field is 61-91 (samordningsnummer: real day + 60), false when it is 01-31 (a real day); any other value (00, 32-60, 92-99) names no real day under either reading.
- birth_date is validated as a real proleptic Gregorian calendar date against the resolved birth_year; an invalid date returns birth_date: null, valid: false, reason: "invalid_date", checked before the checksum.
- The Luhn checksum is evaluated over exactly the 10 digits YY+MM+DD(as printed, with the +60 offset if any)+NNN+C -- the printed 2-digit year, never the resolved 4-digit birth_year -- using the standard Luhn algorithm (as in checkdigit-validate's luhn preset).
- sex is male when the 9th of those 10 digits (the last digit of the 3-digit serial) is odd, female when even.
- normalized12 is always the resolved 4-digit birth_year followed by the printed MM, DD (unchanged, including any +60 offset) and the 4 remaining digits (serial + given check digit, never the expected one), regardless of validity.
- Pure integer arithmetic and a fixed calendar rule; the century is resolved only from the caller-supplied reference_date, never the system clock; identical output across runs for the same input.

## Input

- `value` (string, required): min length 11; max length 12; pattern `^(\d{12}|\d{6}[-+]\d{4})$`
- `reference_date` (string, optional): min length 10; max length 10; pattern `^\d{4}-\d{2}-\d{2}$`

## Output

- `valid` (boolean, required)
- `reason` (one of null, "invalid_date", "checksum_mismatch", required)
- `birth_date` (string or null, required): pattern `^\d{4}-\d{2}-\d{2}$`
- `century_resolved` (boolean, required)
- `is_coordination_number` (boolean, required)
- `sex` (one of "male", "female", required)
- `normalized12` (string, required): pattern `^\d{12}$`

## Limits

- max value bytes: 12
- max reference date bytes: 10

## Example

Request input:

```json
{
  "value": "811218-9876",
  "reference_date": "2026-09-28"
}
```

Response:

```json
{
  "result": {
    "valid": true,
    "reason": null,
    "birth_date": "1981-12-18",
    "century_resolved": false,
    "is_coordination_number": false,
    "sex": "male",
    "normalized12": "198112189876"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "se-personnummer-parse",
  "version": "1.0.0",
  "input": {
    "value": "811218-9876",
    "reference_date": "2026-09-28"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/se-personnummer-parse/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"value":"811218-9876","reference_date":"2026-09-28"}'
```

The machine-readable contract is at [/v1/tools/se-personnummer-parse/versions/1.0.0](/v1/tools/se-personnummer-parse/versions/1.0.0).

### CLI

```sh
node cli.mjs run se-personnummer-parse 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Cn resident id parse](/tools/cn-resident-id-parse): Parse an 18-digit (or legacy 15-digit) Chinese resident ID: region code, birth date, sex and GB 11643-1999 check digit.
- [It codice fiscale parse](/tools/it-codice-fiscale-parse): Parse an Italian codice fiscale: birth date, sex, place code, check character; optionally match a surname/given name.
- [Eu vat id validate](/tools/eu-vat-id-validate): Detect the country from an EU/XI VAT id prefix and validate its format and, where defined, national checksum.
- [Checkdigit validate](/tools/checkdigit-validate): Validate a full value's trailing check digit(s) against a named algorithm (Luhn, Verhoeff, Damm, ISO 7064, GS1, mod 10).
- [Cusip validate](/tools/cusip-validate): Validate a 9-character CUSIP's Modulus 10 Double Add Double check digit and parse its issuer, issue and PPN marker.
- [Iban validate](/tools/iban-validate): Validate an IBAN's country, registry length, BBAN structure and MOD 97-10 check digits, and parse its bank/branch code.
