How the VIN Check Digit Is Calculated
Step-by-step VIN check digit calculation with transliteration values and position weights, plus Python code to validate a VIN.
Where the check digit is
In VINs used in North America, position 9 is a check digit computed from the other 16 characters. It is a number 0–9 or the letter X (representing 10).
Extracting It Automatically
When you read this data from photos, the VIN OCR API returns it as structured JSON, and you can apply the rules on this page as validation. Try it with the free scanner.
Where This Fits
- Step 1: transliterate letters: Letters are converted to numbers: A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, J=1, K=2, L=3, M=4, N=5, P=7, R=9, S=2, T=3, U=4, V=5, W=6, X=7, Y=8, Z=9. Digits keep their value.
- Step 2: apply weights: Multiply each value by its position weight: 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 for positions 1–17. Position 9 has weight 0.
- Step 3: take the remainder: Add the products and divide by 11. The remainder is the check digit; a remainder of 10 is written as X.
Python Implementation
A minimal, dependency-free implementation you can use to validate OCR output.
Prerequisite: Python 3.9+
MAP = {**{str(d): d for d in range(10)}, **dict(zip("ABCDEFGH", range(1, 9))), **dict(zip("JKLMN", range(1, 6))), "P": 7, "R": 9, **dict(zip("STUVWXYZ", range(2, 10)))}
WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2]
def vin_check_digit_ok(vin: str) -> bool:
vin = vin.upper()
if len(vin) != 17 or any(c not in MAP for c in vin):
return False
remainder = sum(MAP[c] * w for c, w in zip(vin, WEIGHTS)) % 11
return vin[8] == ("X" if remainder == 10 else str(remainder))
print(vin_check_digit_ok("1M8GDM9AXKP042788"))Technical Specs
- •Endpoint: POST https://api.structocr.com/v1/vin
- •Authentication: x-api-key request header
- •Inputs: JPG, PNG, or WebP as Base64 JSON; maximum 4.5MB
- •Price: 1 credit per successful request; failed requests are not billed
- •Free trial: 200 free credits on sign-up, no credit card required
Key Features
- •Step 1: transliterate letters: Letters are converted to numbers: A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, J=1, K=2, L=3, M=4, N=5, P=7, R=9, S=2, T=3, U=4, V=5, W=6, X=7, Y=8, Z=9. Digits keep their value.
- •Step 2: apply weights: Multiply each value by its position weight: 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 for positions 1–17. Position 9 has weight 0.
- •Step 3: take the remainder: Add the products and divide by 11. The remainder is the check digit; a remainder of 10 is written as X.
- •Validate after OCR: Apply these rules to API output before storing it.
Reference Summary
Key facts from this page in structured form, for quick lookup.
{
"Where the check digit is": "In VINs used in North America, position 9 is a check digit computed from the other 16 characters.",
"Step 1: transliterate letters": "Letters are converted to numbers: A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, J=1, K=2, L=3, M=4, N=5, P=7, R=9, S=2, T=3, U=4, V=5, W=6, X=7, Y=8, Z=9.",
"Step 2: apply weights": "Multiply each value by its position weight: 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 for positions 1–17.",
"Step 3: take the remainder": "Add the products and divide by 11."
}Frequently Asked Questions
Do European VINs use the check digit?
Not necessarily. The check digit is required in North America; many vehicles built for other markets use position 9 for other purposes, so a failed check is not always an error.
Should OCR output be rejected when the check fails?
For North American vehicles, a failed check usually means a misread character, so request a clearer image or manual review.
You May Also Like
Related tutorials, platform guides, and comparisons
Mitsubishi VIN Location and VIN OCR API
Where to find the VIN on a Mitsubishi, what its first characters mean, and how to read it from a photo with an API and decode the model year.
Chevrolet VIN Location and VIN OCR API
Where to find the VIN on a Chevrolet, what its first characters mean, and how to read it from a photo with an API and decode the model year.
Cadillac VIN Location and VIN OCR API
Where to find the VIN on a Cadillac, what its first characters mean, and how to read it from a photo with an API and decode the model year.
Tesla VIN Location and VIN OCR API
Where to find the VIN on a Tesla, what its first characters mean, and how to read it from a photo with an API and decode the model year.
Jeep VIN Location and VIN OCR API
Where to find the VIN on a Jeep, what its first characters mean, and how to read it from a photo with an API and decode the model year.
C# VIN OCR API
Upload an image for a free test! Tutorial: How to use the StructOCR C# Client to extract data from VIN (Vehicle Identification Number)s. Includes code samples and JSON schema.
Go VIN OCR API
Upload an image for a free test! Tutorial: How to use the StructOCR Go Client to extract data from VIN (Vehicle Identification Number)s. Includes code samples and JSON schema.
VIN Model Year Codes: The 10th Character Table
Decode the model year from the 10th VIN character, including the 30-year cycle and how to tell 1990s vehicles from 2020s vehicles.
Python VIN OCR API
Tutorial: How to use the StructOCR Python SDK to extract data from VIN (Vehicle Identification Number)s. Upload an image for a free test! Includes code samples and JSON schema.
Node.js VIN OCR API
Tutorial: How to use the StructOCR Node.js SDK to extract data from VINs. Upload an image for a free test! Includes code samples and JSON schema.
Technical Comparisons & Integrations
Explore platform integrations and competitive analysis
Add VIN OCR to Your v0 App in 5 Minutes
Step-by-step guide to integrating the StructOCR VIN scanner API into a v0 by Vercel app. Build automotive and fleet tools with zero backend.
VIN Barcode Scanner vs. VIN OCR API: Which is Better for Mobile Apps?
Deciding between local VIN barcode scanners and cloud-based VIN OCR API for your mobile app? Learn why OCR is the required fallback for damaged or chassis-stamped VINs.
Apple Vision Framework / ML Kit vs. StructOCR VIN API
Why generic on-device text recognition frameworks fail at decoding VINs, and when to switch to a specialized automotive API.
Add VIN OCR to Your Bolt.new App in 5 Minutes
Step-by-step guide to integrating the StructOCR VIN scanner API into a Bolt.new app. Build automotive and fleet tools right in your browser.
Add VIN OCR using Cursor in 5 Minutes
Step-by-step guide to integrating the StructOCR VIN scanner API using the Cursor AI code editor. Build automotive and fleet tools rapidly.
Add VIN OCR to Your Lovable.dev App in 5 Minutes
Step-by-step guide to integrating the StructOCR VIN scanner API into a Lovable.dev app. Build automotive and fleet tools with zero backend required.
From tutorial to production in 5 minutes.
You've seen the code. Now get your API key, grab your 200 free credits, and see it work with your own images. No credit card required.