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. Some pre-specification codes (before 2000) can also be parsed if they are not far from version 1 standard. 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 “unified” field, 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,
"documentType" : "DL"
},
"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, 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)
“documentType” : the type of the document (‘DL’ for driver licenses and ‘ID’ for identity cards)
“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:
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:
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:
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:
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:
|
DAY |
Eye color |
>=2 |
One of the following:
|
DAU |
Height of cardholder. |
>=2 |
A dictionary with following key/value pairs:
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:
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 |
|
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
|
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. |