DL/ID#

Overview#

The parser supports all versions of the AAMVA Driver License/Identification specification (2000, 2003, 2005, 2009, 2010, 2011, 2012, 2013, 2016) used in the USA and in Canada. Pre-specification codes (before 2000) are currently not supported. Encrypted codes issued in Georgia before 2012 are also currently not supported.

The encoding of card holder information has changed significantly between revisions of the DL/ID specification (most notably between 2000 codes and later codes) and the same piece of information is encoded differently, depending on the version. We provide a subset of the information as part of the :ref:unified-label, which exposes the fields in a version-agnostic way.

In addition, the implementations of the specification vary strongly between jurisdictions, as many of them don’t implement the specifications correctly. If you are experiencing trouble when scanning certain DL/ID cards, we suggest to contact the Scandit team to resolve the issues.

Example#

Parsing the following code (without quotes, with encoded ASCII characters ‘\n’=0x0A, ‘\r’=0x0D and ‘\x1e’=0x1E, source: 2016 AAMVA DL/ID Card Design Standard, http://www.aamva.org/):

"@\n\x1e\rANSI 636000090002DL00410278ZV03190008DLDAQT64235789\nDCSSAMPLE\nDDEN\nDACMICHAEL\nDDFN\nDADJOHN\nDDGN\nDCUJR\nDCAD\nDCBK\nDCDPH\nDBD06062016\nDBB06061986\nDBA12102024\nDBC1\nDAU068 in\nDAYBRO\nDAG2300 WEST BROAD STREET\nDAIRICHMOND\nDAJVA\nDAK232690000  \nDCF2424244747474786102204\nDCGUSA\nDCK123456789\nDDAF\nDDB06062008\nDDC06062009\nDDD1\rZVZVA01\r"

will result in following JSON output:

[
   {
          "name" : "header",
          "parsed" : {
                 "AAMVAVersion" : 9,
                 "IIN" : "636000",
                 "issuer" : "VA",
                 "jurisdictionVersion" : 0
          },
          "rawString" : ""
   },
   {
          "name" : "DAQ",
          "parsed" : "T64235789",
          "rawString" : "T64235789"
   },
   {
          "name" : "DCS",
          "parsed" : "SAMPLE",
          "rawString" : "SAMPLE"
   },
   {
          "name" : "DDE",
          "parsed" : "N",
          "rawString" : "N"
   },
   {
          "name" : "DAC",
          "parsed" : "MICHAEL",
          "rawString" : "MICHAEL"
   },
   {
          "name" : "DDF",
          "parsed" : "N",
          "rawString" : "N"
   },
   {
          "name" : "DAD",
          "parsed" : "JOHN",
          "rawString" : "JOHN"
   },
   {
          "name" : "DDG",
          "parsed" : "N",
          "rawString" : "N"
   },
   {
          "name" : "DCU",
          "parsed" : "JR",
          "rawString" : "JR"
   },
   {
          "name" : "DCA",
          "parsed" : "D",
          "rawString" : "D"
   },
   {
          "name" : "DCB",
          "parsed" : "K",
          "rawString" : "K"
   },
   {
          "name" : "DCD",
          "parsed" : "PH",
          "rawString" : "PH"
   },
   {
          "name" : "DBD",
          "parsed" : {
                 "day" : 6,
                 "month" : 6,
                 "year" : 2016
          },
          "rawString" : "06062016"
   },
   {
          "name" : "DBB",
          "parsed" : {
                 "day" : 6,
                 "month" : 6,
                 "year" : 1986
          },
          "rawString" : "06061986"
   },
   {
          "name" : "DBA",
          "parsed" : {
                 "day" : 10,
                 "month" : 12,
                 "year" : 2024
          },
          "rawString" : "12102024"
   },
   {
          "name" : "DBC",
          "parsed" : 1,
          "rawString" : "1"
   },
   {
          "name" : "DAU",
          "parsed" : {
                 "cm" : 173,
                 "inch" : 68
          },
          "rawString" : "068 in"
   },
   {
          "name" : "DAY",
          "parsed" : "Brown",
          "rawString" : "BRO"
   },
   {
          "name" : "DAG",
          "parsed" : "2300 WEST BROAD STREET",
          "rawString" : "2300 WEST BROAD STREET"
   },
   {
          "name" : "DAI",
          "parsed" : "RICHMOND",
          "rawString" : "RICHMOND"
   },
   {
          "name" : "DAJ",
          "parsed" : "VA",
          "rawString" : "VA"
   },
   {
          "name" : "DAK",
          "parsed" : "232690000",
          "rawString" : "232690000  "
   },
   {
          "name" : "DCF",
          "parsed" : "2424244747474786102204",
          "rawString" : "2424244747474786102204"
   },
   {
          "name" : "DCG",
          "parsed" : "USA",
          "rawString" : "USA"
   },
   {
          "name" : "DCK",
          "parsed" : "123456789",
          "rawString" : "123456789"
   },
   {
          "name" : "DDA",
          "parsed" : "F",
          "rawString" : "F"
   },
   {
          "name" : "DDB",
          "parsed" : {
                 "day" : 6,
                 "month" : 6,
                 "year" : 2008
          },
          "rawString" : "06062008"
   },
   {
          "name" : "DDC",
          "parsed" : {
                 "day" : 6,
                 "month" : 6,
                 "year" : 2009
          },
          "rawString" : "06062009"
   },
   {
          "name" : "DDD",
          "parsed" : 1,
          "rawString" : "1"
   },
   {
          "name" : "ZVA",
          "parsed" : "01",
          "rawString" : "01"
   },
   {
          "name" : "unified",
          "parsed" : {
          "dateOfBirth" : {
             "day" : 6,
             "month" : 6,
             "year" : 1986
          },
          "expirationDate" : {
             "day" : 10,
             "month" : 12,
             "year" : 2024
          },
          "isExpired" : false,
          "fullAddress" : "2300 WEST BROAD STREET, RICHMOND, VA, 232690000",
          "gender" : "male",
          "height" : {
             "cm" : 173,
             "inch" : 68
          },
          "name" : "MICHAEL JOHN SAMPLE",
          "firstNames" : ["MICHAEL", "JOHN"],
          "lastNames" : ["SAMPLE"],
          "weightRange" : -1
          },
          "rawString" : ""
   }
 ]

Exposed Fields#

The data in DL/ID codes is encoded into data elements. A data element is uniquely identified by its data element ID. Some data elements are mandatory (present on every code) while others are optional. Fields, including mandatory ones, vary between specification versions. It is thus required to handle these versions differently.

Further information about the data elements can be found in the DL/ID specifications on the AAMVA Web page.

The first field is the header field. Its raw content is empty. Its parsed content is a dictionary with following key/value pairs:

  • “AAMVAVersion” : integer (0-99)

  • “jurisdictionVersion” : integer (0-99)

  • “IIN” : 6 digit numeric string

  • “issuer” : string

AAMVAVersion corresponds to the version of the specifications that is implemented in the code: 0=pre-specification, 1=2000, 2=2003, 3=2005, 4=2009, 5=2010, 6=2011, 7=2012, 8=2013, 9=2016. jurisdictionVersion is a jurisdiction specific version number of the implementation. IIN is the Issuer Identification Number which uniquely identifies the issuing jurisdiction. issuer is the ISO code of the issuing state. If state ISO code can not be recognized, the field value points to the same value as the IIN field. If the AAMVAVersion is < 2, then the jurisdiction Version is always 0, as this information is not available in the code.

The specification got a major overhaul between the 2000 and 2003 specifications and many data fields got reworked. After 2003 only minor changes were made to the standard. Due to the large differences between the 2000 and later revisions of the specification, we will list them separately in the following. Some of the common fields (name, date of birth, etc…) are encoded differently across different specification versions. Such information is collected in the “unified” field field, the idea being to allow quick access to commonly used information, without the hassle of having to check the specification version. If you require more complex information that is encoded differently between versions or is only present in a few versions, there is no way around handling the different cases for the different versions.

Note that the parsed content can be null for all fields except the unified field and the header field. This is very rarely the case, as it usually only happens if the code contains bogus content.

“unified” field#

The “unified” field is always present. The idea behind the unified field is to facilitate the access to data that might be encoded differently depending on the version of the standard by mapping the data in a standardized way. The raw content of “unified” is an empty string, all information is encoded in the parsed content, which is a dictionary containing following key-value pairs:

  • “name” : full name of cardholder (string)

  • “firstNames” : [first names, e.g., first name, second name or titles]. Null if it is not provided.

  • “lastNames” : [last names, e.g., surname]. null if it is not provided.

  • “gender” : gender of the cardholder (string, can be ‘male’, ‘female’, ‘unspecified’ or ‘invalid’)

  • “fullAddress” : full address of the cardholder (string)

  • “expirationDate” : expiration date of the card (in the same format as “DBA”, see below, can be null for some versions that do not provide the expiration date)

  • “isExpired” : true if the license is expired.

  • “dateOfBirth” : date of birth of the cardholder (in the same format as “DBB”, see below, may be null)

  • “height” : height of cardholder (in the same format as “DAU”, is set to 0 if unspecified)

  • “weightRange” : weight of cardholder (integer), can be:

    • -1 = unspecified

    • 0 = up to 31 kg (up to 70 lbs)

    • 1 = 32 – 45 kg (71 – 100 lbs)

    • 2 = 46 - 59 kg (101 – 130 lbs)

    • 3 = 60 - 70 kg (131 – 160 lbs)

    • 4 = 71 - 86 kg (161 – 190 lbs)

    • 5 = 87 - 100 kg (191 – 220 lbs)

    • 6 = 101 - 113 kg (221 – 250 lbs)

    • 7 = 114 - 127 kg (251 – 280 lbs)

    • 8 = 128 – 145 kg (281 – 320 lbs)

    • 9 = 146+ kg (321+ lbs)

Mandatory Fields for spec version 1 (2000)#

Following data fields are always present in a version 1 code:

Data Element ID

Meaning

Parsed Content

DAA

Driver License Name

DAG

Driver Mailing Street Address 1

DAI

Driver Mailing City

DAJ

Driver Mailing Jurisdiction Code

DAK

Driver Mailing Postal Code

A ZIP code is parsed as a dictionary with following key/value pairs:

  • ‘5digit’ : 5-digit postal address (ZIP)

  • ‘9digit’ : 9-digit postal address (ZIP+4)

Note that only certain jurisdictions encode the full 9-digit ZIP codes. Therefore the ‘9digit’ field is often empty or contains the padded 5-digit codes. Generally you will want to use the 5-digit code as it is reliably present. Both fields may be empty.

DAQ

Driver License/ID Number

DAR

Driver License Classification Code

DAS

Driver License Restriction Code

DAT

Driver License Endorsements Code

DBA

Driver License Expiration Date

A date is parsed as a dictionary with following key/value pairs:

  • ‘day’ : DD

  • ‘month’ : MM

  • ‘year’ : YY

where DD, MM and YYYY are two-digit, respectively four-digit integers. Can be null because some versions do not follow the AAMVA specification and do not provide this field.

DBB

Date of Birth

the same as ‘DBA’

DBC

Driver Sex (‘F’ or ‘M’)

DBD

Driver License or ID Document Issue Date

the same as ‘DBA’

Optional Fields for spec version 1 (2000)#

Following data fields are sometimes present in a version 1 code:

Data Element ID

Meaning

Parsed Content

DAU

Height (in feet and inches)

A dictionary with following key/value pairs:

  • ‘in’ : X

  • ‘cm’ : Y

where X is the heigth in inches and Y is the height in cm.

DAW

Weight (in pounds)

Integer

DAY

Eye Color

DAZ

Hair Color

DBK

Social Security Number

PAA

Driver Permit Classification Code

PAB

Driver Permit Expiration Date

see ‘DBA’

PAC

Permit Identifier

PAD

Driver Permit Issue Date

see ‘DBA’

PAE

Driver Permit Restriction Code

PAF

Driver Permit Endorsement Code

DAB

Driver Last Name

DAC

Driver First Name

DAD

Driver Middle Name or Initial

DAE

Driver Name Suffix

DAF

Driver Name Prefix

DAH

Driver Mailing Street Address 2

DAL

Driver Residence Street Address 1

DAM

Driver Residence Street Address 2

DAN

Driver Residence City

DAO

Driver Residence Jurisdiction Code

DAP

Driver Residence Postal Code

see ‘DAK’

DAV

Height (in cm, format state-dependent)

see ‘DAU’

DAX

Weight (in kg)

DBE

Issue Timestamp

DBF

Number of Duplicates

Integer

DBG

Medical Indicator/Codes

DBH

Organ Donor

DBI

Non-Resident Indicator

DBJ

Unique Customer Identifier

DBL

Driver ‘AKA’ Date Of Birth

see ‘DBA’

DBM

Driver ‘AKA’ Social Security Number

DBN

Driver ‘AKA’ Name

DBO

Driver ‘AKA’ Last Name

DBP

Driver ‘AKA’ First Name

DBQ

Driver ‘AKA’ Middle Name

DBR

Driver ‘AKA’ Suffix

DBS

Driver ‘AKA’ Prefix

Mandatory Fields for spec version 2 and later (2003+)#

Following data fields are sometimes present in a version >=2 code:

Data Element ID

Meaning

Present in Versions

Parsed Content

DCA

Jurisdiction-specific vehicle class/group code

>=2

DCB

Jurisdiction-specific codes that represent restrictions to driving privileges

>=2

DCD

Jurisdiction-specific codes that represent additional privileges granted to the cardholder beyond the vehicle class

>=2

DBA

Expiration Date

>=2

A date is parsed as a dictionary with following key/value pairs:

  • ‘day’ : DD

  • ‘month’ : MM

  • ‘year’ : YY

where DD, MM and YYYY are two-digit, respectively four-digit integers. Can be null because some versions do not follow the AAMVA specification and do not provide this field.

DCS

Family name

>=2

DCT

Given name (all names other than the family name)

2 and 3

DAC

First name

>=4

DAD

Middle Name(s), separated by a comma

>=4

DBD

Date on which the document was issued.

>=2

see ‘DBA’

DBB

Date of Birth Date

>=2

see ‘DBA’

DBC

Gender of the cardholder

>=2

String. One of the following:

  • ‘male’

  • ‘female’

  • ‘unspecified’

DAY

ANSI D-20 eye color code (3 letters)

>=2

String of the D-20 color. One of the following:

  • ‘blue’

  • ‘brown’

  • ‘dichromatic’

  • ‘gray’

  • ‘green’

  • ‘hazel’

  • ‘maroon’

  • ‘pink’

  • ‘unknown’

DAU

Height of cardholder.

>=2

A dictionary with following key/value pairs:

  • ‘in’ : X

  • ‘cm’ : Y

where X is the heigth in inches and Y is the height in cm.

DAG

Street portion of the cardholder address.

>=2

DAI

City portion of the cardholder address.

>=2

DAJ

State portion of the cardholder address.

>=2

DAK

Postal code portion of the cardholder address.

>=2

A ZIP code is parsed as a dictionary with following key/value pairs:

  • ‘5digit’ : 5-digit postal address (ZIP)

  • ‘9digit’ : 9-digit postal address (ZIP+4)

Note that only certain jurisdictions encode the full 9-digit ZIP codes. Therefore the ‘9digit’ field is often empty or contains the padded 5-digit codes. Generally you will want to use the 5-digit code as it is reliably present. Both fields may be empty.

DAQ

Customer ID

>=2

DCF

Document Discriminator Number

>=2

DCG

Country (‘USA’ or ‘CAN’)

>=2

DCH

Federal Commercial Vehicle Codes

2 and 3

DDE

Family name truncation. A code that indicates whether a field has been truncated (‘T’), has not been truncated (‘N’), or unknown whether truncated (‘U’).

>=4

DDF

First name truncation. A code that indicates whether a field has been truncated (‘T’), has not been truncated (‘N’), or unknown whether truncated (‘U’).

>=4

DDG

Middle name truncation. A code that indicates whether a field has been truncated (‘T’), has not been truncated (‘N’), or unknown whether truncated (‘U’).

>=4

Optional Fields for spec version 2 and later (2003+)#

Following data fields are sometimes present in a version >=2 code:

Data Element ID

Meaning

Parsed Content

DAH

Second line of street portion of the cardholder address.

DAZ

Hair color. Can be written out or ANSI D-20 hair color code

DCI

Place of birth

DCJ

Audit information

DCK

Inventory control number

DBN

Alias/AKA Family Name

DBG

Alias/AKA Given Name

DBS

Alias/AKA Suffix Name

DCU

Name Suffix (can be ‘JR’, ‘SR’, ‘1ST’, ‘2ND’, ‘3RD’, ‘4TH’, ‘5TH’, ‘6TH’, ‘7TH’, ‘8TH’, ‘9TH’, ‘I’, ‘II’, ‘III’, ‘IV’, ‘V’, ‘VI’, ‘VII’, ‘VIII’ or ‘IX’)

DCE

Weight Range

  • 0 = up to 31 kg (up to 70 lbs)

  • 1 = 32 – 45 kg (71 – 100 lbs)

  • 2 = 46 - 59 kg (101 – 130 lbs)

  • 3 = 60 - 70 kg (131 – 160 lbs)

  • 4 = 71 - 86 kg (161 – 190 lbs)

  • 5 = 87 - 100 kg (191 – 220 lbs)

  • 6 = 101 - 113 kg (221 – 250 lbs)

  • 7 = 114 - 127 kg (251 – 280 lbs)

  • 8 = 128 – 145 kg (281 – 320 lbs)

  • 9 = 146+ kg (321+ lbs)

Integer

DCL

D-20 Code for Race/Ethnicity

DCM

Standard vehicle classification

DCN

Standard endorsement code

DCO

Standard restriction code

DCP

Jurisdiction-specific vehicle classification description

DCQ

Jurisdiction-specific endorsement code description

DCR

Jurisdiction-specific restriction code description

DDA

Compliance Type, ‘F’ = fully compliant and ‘N’ = non-compliant.

DDB

Card Revision Date

see ‘DBA’

DDC

Date on which the hazardous material endorsement granted by the document is no longer valid

see ‘DBA’

DDD

Indicator that the cardholder has temporary lawful status, can be ‘true’ or ‘false’.

String

DAW

Weight in pounds

Integer

DAX

Weight in kilograms

Integer

DDH

Date on which the cardholder turns 18

see ‘DBA’

DDI

Date on which the cardholder turns 19

see ‘DBA’

DDJ

Date on which the cardholder turns 21

see ‘DBA’

DDK

Indicator that the cardholder is an organ donor, can be ‘1’ or ‘0’

Integer

DDL

Indicator that the cardholder is a veteran, can be ‘1’ or ‘0’

Integer

Jurisdiction-Specific Fields#

Different jurisdictions can include custom data elements if desired. These data element must have an id starting with the letter ‘Z’. The Scandit parsing library also exposes these fields without any parsing.

Parser Options#

The parser can be configured by providing a JSON string containing key / value pairs. The following configuration options are available:

Key

Value Type

Description

strictElementIdVerification

Boolean

The parser defaults to accepting any kind of (three character) entry ID. Enabling this option only allows custom entry IDs beginning with ‘Z’.

ignoreCutOffElementId

Boolean

The parser returns an error if the last element ID is cut off. Enabling this option tells the parser to ignore these cases and not return any error.