Skip to main content

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.

Special Characters

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:

FormatIdentifier
SD-JWT VCvct: urn:eudi:pid:de:1
mDocdocType: 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 claimmDoc identifierDescriptionExample value
family_namefamily_nameHolder's surnameMUSTERMANN
given_namegiven_nameHolder's given name(s)ERIKA
birthdatebirth_dateDate 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_birthplace_of_birthJSON object / CBOR map with at least locality. If no place is recorded, no_place_info: true is set{"locality": "BERLIN"}
nationalitiesnationalityArray 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 claimmDoc identifierDescriptionExample value
address.countryresident_countryISO 3166-1 alpha-2 country code of residenceDE
address.regionresident_stateFederal state or region of residenceNORDRHEIN-WESTFALEN
address.localityresident_cityCity of residenceKÖLN
address.postal_coderesident_postal_codePostal code51147
address.street_addressresident_streetStreet name and house number combinedHEIDESTRASSE 17
note

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 claimmDoc identifierDescriptionExample value
issuing_authorityissuing_authoritySet to the issuing country code (no separate authority available in German eID)DE
issuing_countryissuing_countryISO 3166-1 alpha-2 country code, always DE for German IDsDE
No expiry_date Attribute

The 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 claimmDoc identifierDescriptionExample value
source_document_typesource_document_typeType of source document. ID = German eID card, AR/AS/AF = Residence PermitID
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 thresholdSee below
birth_namebirth_nameBirth name (may include both given and family name at birth); may be emptyGABLER
raw_eid_birth_dateraw_eid_birth_dateOriginal, 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 value1983-08-00
also_known_asalso_known_asArtistic or stage name(optional)
academic_titleacademic_titleAcademic 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 claimmDoc identifierDescription
statusstatusReference 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 vct claim identifies this credential as a German PID. Always validate this before trusting any claims.
  • Claims vct, vct#integrity, cnf, and metadata cannot be selectively disclosed — they are always present in the header.
  • nbf and exp define the technical validity period of the individual PID token. There is no date_of_expiry/expiry_date claim — do not confuse technical validity with the (unexposed) administrative validity of the underlying eID.
  • birthdate reflects the eID's date of birth with unknown day/month components converted to their maximum value; raw_eid_birth_date preserves the original value (which may contain literal 00) so you can detect when this conversion happened.
  • nationalities is 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 docType eu.europa.ec.eudi.pid.1 identifies this as a PID. Always verify this before processing.
  • Core attributes are in the eu.europa.ec.eudi.pid.1 namespace; German-specific extensions are in eu.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_date uses the format YYYY-MM-DD with unknown day/month components converted to their maximum value; raw_eid_birth_date (in the pid.de.1 namespace) preserves the original value, which may contain literal 00.
  • place_of_birth is a CBOR map with a locality key. This differs from the ISO mDL standard, where birth_place is a plain string.
  • nationality is always an array of alpha-2 country codes.
  • There is no expiry_date claim in the pid.1 namespace — technical validity is carried in the MSO's validityInfo (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 identifierSD-JWT VC claimmDoc identifier (namespace)
family_namefamily_namefamily_name (pid.1)
given_namegiven_namegiven_name (pid.1)
birth_datebirthdatebirth_date (pid.1)
birth_placeplace_of_birthplace_of_birth (pid.1)
nationalitynationalitiesnationality (pid.1)
resident_countryaddress.countryresident_country (pid.1)
resident_stateaddress.regionresident_state (pid.1)
resident_cityaddress.localityresident_city (pid.1)
resident_postal_codeaddress.postal_coderesident_postal_code (pid.1)
resident_streetaddress.street_addressresident_street (pid.1)
issuing_authorityissuing_authorityissuing_authority (pid.1)
issuing_countryissuing_countryissuing_country (pid.1)
(German extension)age_equal_or_over.NNage_over_NN (pid.de.1)
(German extension)source_document_typesource_document_type (pid.de.1)
(German extension)birth_namebirth_name (pid.de.1)
(German extension)raw_eid_birth_dateraw_eid_birth_date (pid.de.1)
note

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.

AttributeAvailable?Notes
family_name✅ Always
given_name✅ Always
birthdate✅ AlwaysUnknown day/month converted to its maximum value; see raw_eid_birth_date for the original
place_of_birth✅ AlwaysOnly locality populated
nationalities✅ AlwaysDefaults to ["DE"] for pre-Nov 2019 cards
issuing_country✅ AlwaysAlways DE
issuing_authority✅ AlwaysPopulated with DE (no separate authority field exists)
source_document_type✅ AlwaysGerman extension
Residential address fields⚠️ ConditionalOnly present if eID returns a structured address
birth_name⚠️ ConditionalMay be empty
raw_eid_birth_date⚠️ ConditionalGerman extension; only differs from birthdate/birth_date when day/month was unknown at the eID
age_equal_or_over / age_over_NN⚠️ ConditionalPresent when requested; reflects thresholds supported by the PID Provider
academic_title, also_known_as⚠️ ConditionalOptional German extensions
expiry_date/date_of_expiry❌ Not availableUse nbf/exp (SD-JWT VC) or validFrom/validUntil (mDoc) for technical validity instead
resident_address (combined)❌ Not available
resident_house_number❌ Not availableHouse number is part of resident_street
portrait❌ Not available
document_number❌ Not available
sex❌ Not availableSet 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 availableThe base EU claims aren't used; the German extension birth_name carries a combined value instead