Guide

How to Parse an AAMVA Driver's License Barcode (PDF417)

The PDF417 on a US/Canadian driver's license encodes identity data in AAMVA format. Learn the structure, the parsing gotchas, and how to extract and validate it — or skip the spec with one API call.

How to Parse an AAMVA Driver's License Barcode (PDF417)

The barcode on the back of a US or Canadian driver's license is a PDF417 that encodes the holder's identity data in the AAMVA format. Reading it sounds simple — it's just text — but the spec has enough quirks that "parse the license barcode" eats days of developer time. This guide explains the format, the traps, and how to extract and validate it reliably.

This is about reading existing licenses for legitimate verification (age-gating, KYC, account matching). It is not about creating or altering credentials.

What's actually in the barcode

After you decode the PDF417 to text, you get an AAMVA record with three parts:

  1. A compliance header — starts with @, control characters, then ANSI followed by the Issuer Identification Number (6 digits), the AAMVA version, the jurisdiction version, and the number of subfiles.
  2. Subfile designatorsDL (driver license) or ID, with offsets/lengths.
  3. Data elements — three-letter codes, each followed by its value, newline-separated.

The fields you usually want:

| Code | Field | Code | Field | |---|---|---|---| | DCS | family name | DBB | date of birth | | DAC | first name | DBA | expiration date | | DAD | middle name | DBD | issue date | | DAQ | license number | DBC | sex | | DAG | street address | DAU | height | | DAI | city | DAJ | state | | DAK | postal code | DCG | country |

The gotchas that cost you a day

  • Date formats differ by country. US jurisdictions use MMDDYYYY; Canadian ones use YYYYMMDD. Parse the wrong order and a January DOB becomes a day-of-month.
  • Subfile prefixes leak into elements. The first element line is often DLDAQ1234567 — the DL designator glued to DAQ. Strip it or you'll mis-key the field.
  • Control characters. The payload contains @, line feed (LF), record separator (RS, 0x1E), and segment terminator (CR) — splitting naively breaks the header.
  • Version drift. Element availability and truncation flags (DDE/DDF/DDG) vary across AAMVA versions; older cards use DCT instead of DAC for first name.
  • Validation. A real parser should confirm the ANSI header, a numeric IIN, and the presence of required elements before trusting the data.

The privacy-first move: derive, don't store

If your actual question is "is this person 21?", you do not need to keep their name, DOB, or address — you need a boolean. The compliant pattern is to parse the barcode, derive is21Plus / isExpired from the dates, and discard the PII. That turns an ID scanner (a breach liability) into an age check (almost none).

Do it with one API call

POST /api/aamva/parse handles the header, the subfile prefixes, the date formats, and the validation, and returns clean JSON. Set redactPII: true to get the derived signals with the personal fields masked:

bash curl -X POST https://YOUR-DOMAIN/api/aamva/parse \ -H "Content-Type: application/json" -H "X-API-Key: pdf417_live_…" \ -d '{ "imageBase64": "<DL barcode image>", "redactPII": true }'

json { "compliant": true, "parsed": { "familyName": "[REDACTED]", "dateOfBirth": "[REDACTED]", "addressState": "VA" }, "validation": { "errors": [], "warnings": [] }, "derived": { "ageYears": 33, "is21Plus": true, "isExpired": false } }

See the API docs for the decoded-text input, full field list, and limits.

FAQ

  • US and Canada? Yes — both MMDDYYYY and YYYYMMDD dates are handled.
  • Can I check expiry? Yes — derived.isExpired compares the expiration date to today.
  • Do you store the data? No. Payloads are parsed to produce the response and not retained.
  • Is this legal? Reading a license you're authorized to verify is a routine, lawful operation. This tool parses and validates; it does not generate or modify credentials.

Stop fighting the spec

Read the API docs → and parse a license barcode in one request — header, subfiles, dates, and validation handled.