German PID Reference for Relying Parties
This page provides a practical reference for Relying Parties integrating with the German Personal Identification Data (PID) credential. It summarizes the key technical details from the German PID Rulebook (PID-DE) that you need to understand in order to successfully request, receive, and verify a PID.
Overview
The German PID is issued by a single, nationally designated PID Provider. It is based on the German eID card (Personalausweis), electronic Residence Permit, or eID Card for Union Citizens. The PID is available in two credential formats:
- SD-JWT VC
- ISO mDoc (ISO/IEC 18013-5)
Both formats carry the same underlying identity data.
All string values in the German PID are stored in UPPERCASE, following ICAO Doc 9303. Special characters such as Ö are represented in their ISO/IEC 8859-1 form and are not transliterated (e.g., Ö is not replaced with OE).
Credential Identifiers
When matching a received credential against the expected type, use the following identifiers:
| Format | Identifier |
|---|---|
| SD-JWT VC | vct: urn:eudi:pid:de:1 |
| mDoc | docType: eu.europa.ec.eudi.pid.1 |
German-specific extension attributes in the mDoc format are in the namespace eu.europa.ec.eudi.pid.de.1.
PID Attributes
Mandatory Attributes (CIR 2026/1731)
These attributes are always present in a German PID.
| SD-JWT VC claim | mDoc identifier | Description | Example value |
|---|---|---|---|
family_name | family_name | Holder's surname | MUSTERMANN |
given_name | given_name | Holder's given name(s) | ERIKA |
birthdate | birth_date | Date of birth (YYYY-MM-DD). If the source eID has an unknown day or month (00), it is converted to the maximum possible value (e.g., unknown day → last day of the month, unknown month → 12) | 1983-08-12 |
place_of_birth | place_of_birth | JSON object / CBOR map with at least locality. If no place is recorded, no_place_info: true is set | {"locality": "BERLIN"} |
nationalities | nationality | Array of ISO 3166-1 alpha-2 codes. If eID was issued before Nov. 2019, automatically set to ["DE"] | ["DE"] |
Optional Attributes (CIR 2026/1731)
These attributes are included when available from the holder's eID. Note that resident_address and resident_house_number are not available in the German PID.
| SD-JWT VC claim | mDoc identifier | Description | Example value |
|---|---|---|---|
address.country | resident_country | ISO 3166-1 alpha-2 country code of residence | DE |
address.region | resident_state | Federal state or region of residence | NORDRHEIN-WESTFALEN |
address.locality | resident_city | City of residence | KÖLN |
address.postal_code | resident_postal_code | Postal code | 51147 |
address.street_address | resident_street | Street name and house number combined | HEIDESTRASSE 17 |
Residential address fields are only present if the eID returns a StructuredPlace. They may be absent even when a holder has a registered address.
Mandatory Metadata (CIR 2026/1731)
| SD-JWT VC claim | mDoc identifier | Description | Example value |
|---|---|---|---|
issuing_authority | issuing_authority | Set to the issuing country code (no separate authority available in German eID) | DE |
issuing_country | issuing_country | ISO 3166-1 alpha-2 country code, always DE for German IDs | DE |
expiry_date AttributeThe CIR's expiry_date/date_of_expiry metadata field is not included in the German PID. That field describes administrative validity (the validity of the underlying eID document), which is distinct from the PID's technical validity. Technical validity is instead expressed through credential-format-specific claims: nbf/exp for SD-JWT VC, and validFrom/validUntil (in the mdoc's MSO validityInfo) for mDoc.
Germany-Specific Additional Attributes
These attributes are defined by the German PID Rulebook and extend the base EU specification. In mDoc, they are found in the eu.europa.ec.eudi.pid.de.1 namespace.
| SD-JWT VC claim | mDoc identifier | Description | Example value |
|---|---|---|---|
source_document_type | source_document_type | Type of source document. ID = German eID card, AR/AS/AF = Residence Permit | ID |
age_equal_or_over (object) | age_over_NN (individual fields) | Boolean age thresholds. SD-JWT groups these under one object; mDoc has individual claims per threshold | See below |
birth_name | birth_name | Birth name (may include both given and family name at birth); may be empty | GABLER |
raw_eid_birth_date | raw_eid_birth_date | Original, unconverted birth date as returned by the eID (yyyy-mm-dd), which may contain literal 00 values for an unknown day or month. Lets an RP detect whether the interoperable birthdate/birth_date claim was adjusted from the source value | 1983-08-00 |
also_known_as | also_known_as | Artistic or stage name | (optional) |
academic_title | academic_title | Academic title | (optional) |
Age Verification Thresholds
The PID supports age verification without revealing the holder's exact date of birth. Available thresholds are 12, 14, 16, 18, 21, and 65.
In SD-JWT VC, these are grouped under the age_equal_or_over object:
"age_equal_or_over": {
"12": true,
"14": true,
"16": true,
"18": true,
"21": true,
"65": false
}
In mDoc, each threshold is an individual claim (e.g., age_over_18) in the eu.europa.ec.eudi.pid.de.1 namespace.
When implementing an age-gate (e.g., 18+ access), you should request only the relevant threshold rather than the holder's birthdate, in line with the principle of data minimization.
Revocation Status Attribute
| SD-JWT VC claim | mDoc identifier | Description |
|---|---|---|
status | status | Reference to a Token Status List (IETF OAuth Status List draft) for revocation checking |
"status": {
"status_list": {
"idx": 0,
"uri": "https://example.com/statuslists/1"
}
}
Complete Example PIDs
SD-JWT VC Example
The decoded payload of a German PID issued as SD-JWT VC looks as follows. In practice the credential is delivered as a compact serialized SD-JWT, with selectively disclosable claims hidden until disclosed by the holder.
{
"vct": "urn:eudi:pid:de:1",
"iat": 1754989200,
"nbf": 1754989200,
"exp": 1786525200,
"family_name": "MUSTERMANN",
"given_name": "ERIKA",
"birthdate": "1983-08-12",
"place_of_birth": {
"locality": "BERLIN"
},
"nationalities": ["DE"],
"address": {
"country": "DE",
"region": "NORDRHEIN-WESTFALEN",
"locality": "KÖLN",
"postal_code": "51147",
"street_address": "HEIDESTRASSE 17"
},
"birth_name": "GABLER",
"raw_eid_birth_date": "1983-08-12",
"issuing_authority": "DE",
"issuing_country": "DE",
"source_document_type": "ID",
"age_equal_or_over": {
"12": true,
"14": true,
"16": true,
"18": true,
"21": true,
"65": false
},
"status": {
"status_list": {
"idx": 0,
"uri": "https://example.com/statuslists/1"
}
},
"cnf": {
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "52aDI_ur05n1f_p3jiYGUU82oKZr3m4LsAErM536crQ",
"y": "ckhZ-KQ5aXNL91R8Eufg1aOf8Z5pZJnIvuCzNGfdnzo"
}
}
}
Key points for SD-JWT VC:
- The
vctclaim identifies this credential as a German PID. Always validate this before trusting any claims. - Claims
vct,vct#integrity,cnf, andmetadatacannot be selectively disclosed — they are always present in the header. nbfandexpdefine the technical validity period of the individual PID token. There is nodate_of_expiry/expiry_dateclaim — do not confuse technical validity with the (unexposed) administrative validity of the underlying eID.birthdatereflects the eID's date of birth with unknown day/month components converted to their maximum value;raw_eid_birth_datepreserves the original value (which may contain literal00) so you can detect when this conversion happened.nationalitiesis always an array, even when only one nationality is present.
mDoc Example
The following is the decoded logical structure of a German PID in mDoc format (ISO/IEC 18013-5). In practice the data is CBOR-encoded and the attributes are individually integrity-protected using digest IDs and random salts to enable selective disclosure.
{
"docType": "eu.europa.ec.eudi.pid.1",
"issuerSigned": {
"nameSpaces": {
"eu.europa.ec.eudi.pid.1": {
"family_name": "MUSTERMANN",
"given_name": "ERIKA",
"birth_date": "1983-08-12",
"place_of_birth": {
"locality": "BERLIN"
},
"nationality": ["DE"],
"resident_country": "DE",
"resident_state": "NORDRHEIN-WESTFALEN",
"resident_city": "KÖLN",
"resident_postal_code": "51147",
"resident_street": "HEIDESTRASSE 17",
"issuing_authority": "DE",
"issuing_country": "DE"
},
"eu.europa.ec.eudi.pid.de.1": {
"source_document_type": "ID",
"birth_name": "GABLER",
"raw_eid_birth_date": "1983-08-12",
"age_over_12": true,
"age_over_14": true,
"age_over_16": true,
"age_over_18": true,
"age_over_21": true,
"age_over_65": false,
"status": {
"status_list": {
"idx": 0,
"uri": "https://example.com/statuslists/1"
}
}
}
},
// MSO validityInfo carries technical validity, not a namespace claim
"issuerAuth": {
"validityInfo": {
"signed": "2026-08-12T00:00:00Z",
"validFrom": "2026-08-12T00:00:00Z",
"validUntil": "2027-08-12T00:00:00Z"
},
"...": "..."
}
},
"deviceSigned": { ... }
}
Key points for mDoc:
- The
docTypeeu.europa.ec.eudi.pid.1identifies this as a PID. Always verify this before processing. - Core attributes are in the
eu.europa.ec.eudi.pid.1namespace; German-specific extensions are ineu.europa.ec.eudi.pid.de.1. - Each attribute is individually salted and hashed, allowing the holder to selectively disclose only the claims you have requested.
birth_dateuses the formatYYYY-MM-DDwith unknown day/month components converted to their maximum value;raw_eid_birth_date(in thepid.de.1namespace) preserves the original value, which may contain literal00.place_of_birthis a CBOR map with alocalitykey. This differs from the ISO mDL standard, wherebirth_placeis a plain string.nationalityis always an array of alpha-2 country codes.- There is no
expiry_dateclaim in thepid.1namespace — technical validity is carried in the MSO'svalidityInfo(validFrom/validUntil), not as a per-namespace attribute.
Attribute Mapping Reference
The same underlying data is labeled differently across formats. Use this table when writing queries or parsing responses across both credential types.
| CIR 2026/1731 identifier | SD-JWT VC claim | mDoc identifier (namespace) |
|---|---|---|
family_name | family_name | family_name (pid.1) |
given_name | given_name | given_name (pid.1) |
birth_date | birthdate | birth_date (pid.1) |
birth_place | place_of_birth | place_of_birth (pid.1) |
nationality | nationalities | nationality (pid.1) |
resident_country | address.country | resident_country (pid.1) |
resident_state | address.region | resident_state (pid.1) |
resident_city | address.locality | resident_city (pid.1) |
resident_postal_code | address.postal_code | resident_postal_code (pid.1) |
resident_street | address.street_address | resident_street (pid.1) |
issuing_authority | issuing_authority | issuing_authority (pid.1) |
issuing_country | issuing_country | issuing_country (pid.1) |
| (German extension) | age_equal_or_over.NN | age_over_NN (pid.de.1) |
| (German extension) | source_document_type | source_document_type (pid.de.1) |
| (German extension) | birth_name | birth_name (pid.de.1) |
| (German extension) | raw_eid_birth_date | raw_eid_birth_date (pid.de.1) |
expiry_date (CIR 2026/1731) has no equivalent claim in the German PID — see the "No expiry_date Attribute" note under Mandatory Metadata above.
What Is and Is Not Available
Several attributes defined in the EU specification are not available in the German PID due to limitations of the source eID document. Plan your integration accordingly and do not assume these fields will be present.
| Attribute | Available? | Notes |
|---|---|---|
family_name | ✅ Always | |
given_name | ✅ Always | |
birthdate | ✅ Always | Unknown day/month converted to its maximum value; see raw_eid_birth_date for the original |
place_of_birth | ✅ Always | Only locality populated |
nationalities | ✅ Always | Defaults to ["DE"] for pre-Nov 2019 cards |
issuing_country | ✅ Always | Always DE |
issuing_authority | ✅ Always | Populated with DE (no separate authority field exists) |
source_document_type | ✅ Always | German extension |
| Residential address fields | ⚠️ Conditional | Only present if eID returns a structured address |
birth_name | ⚠️ Conditional | May be empty |
raw_eid_birth_date | ⚠️ Conditional | German extension; only differs from birthdate/birth_date when day/month was unknown at the eID |
age_equal_or_over / age_over_NN | ⚠️ Conditional | Present when requested; reflects thresholds supported by the PID Provider |
academic_title, also_known_as | ⚠️ Conditional | Optional German extensions |
expiry_date/date_of_expiry | ❌ Not available | Use nbf/exp (SD-JWT VC) or validFrom/validUntil (mDoc) for technical validity instead |
resident_address (combined) | ❌ Not available | |
resident_house_number | ❌ Not available | House number is part of resident_street |
portrait | ❌ Not available | |
document_number | ❌ Not available | |
sex | ❌ Not available | Set to 9 (other) in Residence Permit PIDs only |
email_address | ❌ Not available | |
mobile_phone_number | ❌ Not available | |
personal_administrative_number | ❌ Not available | |
family_name_birth / given_name_birth | ❌ Not available | The base EU claims aren't used; the German extension birth_name carries a combined value instead |