US Driver License PDF417 API

Decode the PDF417 barcode on the back of a US driver license or State ID and receive normalized AAMVA fields as JSON. The service uses deterministic barcode decoding and protocol parsing instead of asking a generative model to guess unreadable identity data.


Endpoint

POSThttps://api.structocr.com/v1/driver-license-pdf417

Price: 2 credits for a successful decode. Processing failures are automatically refunded.

Request Parameters

Send one JPG, PNG, or WebP image using Base64 JSON or multipart form data. Keep the full barcode visible, in focus, and free from glare.

ParameterInRequiredDescription
x-api-keyHeaderRequiredYour StructOCR API key.
Content-TypeHeaderRequiredapplication/json or multipart/form-data.
img / imageJSON bodyJSON onlyRaw Base64 or a Base64 data URI.
file / imgForm fieldMultipart onlyOne image file. Maximum decoded size: 4.5 MB.

Response Schema

Required identity fields are always present on success. Optional AAMVA fields return null when absent.

FieldDescription
typestring — Response schema type; always drivers_license for this endpoint, including State ID cards. Use document_kind to tell them apart.
document_kindstring — driver_license or id_card, from the AAMVA subfile type. Enhanced cards without a license class are reported as id_card.
sourcestring — Extraction source; always pdf417 for this endpoint.
country_codestring | null — Country code encoded in the AAMVA record, commonly USA.
regionstring | null — Issuing US state or jurisdiction code, such as CA or NY.
document_numberstring — Driver license or State ID number.
surnamestring — Cardholder family name.
given_namesstring — Combined first and middle names.
first_namestring | null — Cardholder first name.
middle_namestring | null — Cardholder middle name.
name_suffixstring | null — Name suffix when encoded.
sexstring | null — Normalized M or F when explicitly encoded.
date_of_birthstring — Birth date normalized to YYYY-MM-DD.
date_of_issuestring | null — Issue date normalized to YYYY-MM-DD.
date_of_expirystring | null — Expiration date normalized to YYYY-MM-DD.
addressstring | null — Combined street address lines.
citystring | null — Mailing city.
postal_codestring | null — Normalized postal code.
vehicle_classstring | null — Jurisdiction-defined license class.
restrictionsstring | null — License restrictions encoded in the record.
endorsementsstring | null — License endorsements encoded in the record.
heightstring | null — Encoded cardholder height.
eye_colorstring | null — Encoded eye color.
document_discriminatorstring | null — AAMVA document discriminator (DCF).
issuer_identification_numberstring — Six-digit issuer identification number from the ANSI header.
aamva_versionnumber — AAMVA version from the ANSI header.
jurisdiction_versionnumber | null — Jurisdiction version from the ANSI header; null for legacy version 01 headers that omit it.

Code Examples

Request Implementation

curl -X POST https://api.structocr.com/v1/driver-license-pdf417 \
  -H "x-api-key: YOUR_API_KEY" \
  -F "file=@license-back.jpg"

Success Response (200 OK)

JSON EXAMPLE
{
  "success": true,
  "data": {
    "type": "drivers_license",
    "document_kind": "driver_license",
    "source": "pdf417",
    "country_code": "USA",
    "region": "CA",
    "document_number": "TEST123456",
    "surname": "SAMPLE",
    "given_names": "ALEX MORGAN",
    "first_name": "ALEX",
    "middle_name": "MORGAN",
    "name_suffix": null,
    "sex": "F",
    "date_of_birth": "1990-01-15",
    "date_of_issue": "2025-01-15",
    "date_of_expiry": "2030-01-15",
    "address": "100 EXAMPLE AVE",
    "city": "SAMPLE CITY",
    "postal_code": "90001",
    "vehicle_class": "C",
    "restrictions": "NONE",
    "endorsements": "NONE",
    "height": "066 IN",
    "eye_color": "BRO",
    "document_discriminator": "TEST-DISCRIMINATOR",
    "issuer_identification_number": "636000",
    "aamva_version": 10,
    "jurisdiction_version": 0
  }
}

Live API Test

Use the request examples above with a back-side image containing a PDF417 barcode. For front-side or international license OCR, use the Driver License OCR API.

Error Responses

400 Bad Request - Invalid Input

{
  "success": false,
  "error": "INVALID_IMAGE",
  "message": "The uploaded image could not be decoded."
}

402 Payment Required - Insufficient Credits

{
  "success": false,
  "error": "INSUFFICIENT_CREDITS",
  "message": "Your account balance is insufficient to complete this operation. Top up at https://structocr.com/dashboard/billing",
  "top_up_url": "https://structocr.com/dashboard/billing"
}

413 Payload Too Large

{
  "success": false,
  "error": "FILE_TOO_LARGE",
  "message": "The image exceeds the 4.5MB limit."
}

415 Unsupported Media Type

{
  "success": false,
  "error": "UNSUPPORTED_FILE_FORMAT",
  "message": "Supported formats are JPG, PNG and WebP."
}

422 Unprocessable Entity - PDF417 Not Detected

{
  "success": false,
  "error": "PDF417_NOT_DETECTED",
  "message": "No PDF417 barcode was detected in this image. Retake the photo.\nPhotograph the barcode on the back of the license, not the whole card:\n1. Move close so the entire barcode fills most of the frame, leaving a small clear margin on all four sides. Do not crop any edges.\n2. Hold the phone steady, face the barcode straight-on, and tap on the barcode to focus until the bars look sharp.\n3. Avoid glare and shadows over the barcode.\n4. Upload the original camera photo, not a screenshot or a copy compressed by a chat app.\nIf this is the front of the license, read it with Driver License OCR instead: API /v1/driver-license, or the web tool at structocr.com/tools/driver-license-scanner.",
  "capture_issue": "unknown"
}

422 Unprocessable Entity - PDF417 Not Decoded (blurry barcode)

{
  "success": false,
  "error": "PDF417_NOT_DECODED",
  "message": "The PDF417 barcode area is too blurry to read. Retake the photo focused on the barcode.\nPhotograph the barcode on the back of the license, not the whole card:\n1. Move close so the entire barcode fills most of the frame, leaving a small clear margin on all four sides. Do not crop any edges.\n2. Hold the phone steady, face the barcode straight-on, and tap on the barcode to focus until the bars look sharp.\n3. Avoid glare and shadows over the barcode.\n4. Upload the original camera photo, not a screenshot or a copy compressed by a chat app.",
  "capture_issue": "out_of_focus"
}

422 Unprocessable Entity - Invalid AAMVA

{
  "success": false,
  "error": "AAMVA_NOT_VALID",
  "message": "The barcode was decoded, but its data could not be validated as a supported AAMVA driver license record."
}

502 Bad Gateway - Decoder Error

{
  "success": false,
  "error": "PDF417_UPSTREAM_ERROR",
  "message": "The PDF417 decoder could not process the request. Please try again."
}

502 Bad Gateway - Invalid Decoder Response

{
  "success": false,
  "error": "PDF417_INVALID_RESPONSE",
  "message": "The PDF417 decoder returned an invalid response. Please try again."
}

503 Service Unavailable

{
  "success": false,
  "error": "PDF417_SERVICE_UNAVAILABLE",
  "message": "The PDF417 decoder is temporarily unavailable. Please try again later."
}

Status Code Definitions

CodeError CodeDescription
200SUCCESSPDF417 checksum and required AAMVA identity fields were validated.
400INVALID_JSON / NO_IMAGE_DATA / INVALID_IMAGEThe request body or decoded image is invalid.
401AUTH_FAILEDThe x-api-key header is missing.
402INSUFFICIENT_CREDITSThe account does not have the 2 credits required to run the request.
403INVALID_KEY / KEY_SUSPENDEDThe API key is invalid, inactive, or revoked.
413FILE_TOO_LARGEThe decoded image exceeds 4.5 MB.
415UNSUPPORTED_FILE_FORMATOnly JPG, PNG, and WebP images are accepted.
422PDF417_NOT_DETECTEDNo PDF417 symbol was detected in this attempt. The request is refunded.
422PDF417_NOT_DECODEDA possible symbol was detected, but no reliable payload could be recovered. The request is refunded.
422AAMVA_NOT_VALIDThe barcode is not a usable AAMVA driver-license record. The request is refunded.
502PDF417_UPSTREAM_ERRORThe decoder returned an upstream error. Retry with backoff.
502PDF417_INVALID_RESPONSEThe decoder returned an invalid response. Retry with backoff.
503PDF417_SERVICE_UNAVAILABLEThe decoder is temporarily unavailable. Retry with backoff.

Capture Issue Hints

PDF417_NOT_DETECTED and PDF417_NOT_DECODED responses may include an optional capture_issue field. It is an advisory hint for your retake prompt, not a guarantee, and new values may be added later, so treat unrecognized values as unknown.

capture_issueMeaning and suggested prompt
image_too_smallThe image is 500 px or smaller on its long edge. Ask the user for the original camera photo or a closer retake.
out_of_focusA barcode-like area was found but is too blurry to read. Ask the user to retake the photo close to the barcode and tap on it to focus.
unknownNo specific cause was identified. Show the general retake guidance.

Most failed requests are whole-card phone photos where the camera focused on the card face and the barcode came out soft. Show capture guidance in your app before the user takes the photo:

Photograph the barcode on the back of the license, not the whole card:
1. Move close so the entire barcode fills most of the frame, leaving a small clear margin on all four sides. Do not crop any edges.
2. Hold the phone steady, face the barcode straight-on, and tap on the barcode to focus until the bars look sharp.
3. Avoid glare and shadows over the barcode.
4. Upload the original camera photo, not a screenshot or a copy compressed by a chat app.