VIN OCR

Extract a 17-character VIN from a photo of a windshield etching, dashboard plate, door jamb sticker, or registration document

POST Request
~2-10s response
1 credit per request

Endpoint

POST https://api.carapi.dev/v1/extract-vin

Request Body (JSON)

FieldTypeRequiredDescription
imagestringRequiredBase64-encoded image. May start with the data-URL prefixdata:image/<fmt>;base64,...- it is stripped automatically.
tokenstringRequiredAPI authentication token (query parameter)

Request Examples

cURL

curl -X POST \
  "https://api.carapi.dev/v1/extract-vin?token=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"image":"<base64-encoded image>"}'

JavaScript

// Convert a File to base64 and call the endpoint
async function extractVin(file) {
  const dataUrl = await new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(file);
  });

  const response = await fetch(
    'https://api.carapi.dev/v1/extract-vin?token=YOUR_API_KEY',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ image: dataUrl })
    }
  );

  return response.json();
}

Python

import base64
import requests

with open("vin.jpg", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode("ascii")

response = requests.post(
    "https://api.carapi.dev/v1/extract-vin",
    params={"token": "YOUR_API_KEY"},
    json={"image": image_b64},
    timeout=65,
)
print(response.json())

Response Examples

VIN found (200)

{
  "vin": "WBAVA31070NL12345",
  "confidence": 0.92
}

No VIN found (200)

{
  "vin": null,
  "confidence": null
}

Error Response (400)

{
  "error": "Missing \"image\" (base64 string) in request body"
}

Response Fields

FieldTypeDescription
vinstring | null17-character uppercase VIN, or null when no VIN was found in the image
confidencenumber | nullSelf-reported confidence in [0, 1]; null when no VIN was found

Error Codes

400

Bad Request

Missing or invalid image field, or invalid base64 payload

403

Forbidden

Invalid or missing API token

413

Payload Too Large

Body exceeds the 15 MB JSON limit

500

Internal Server Error

Server encountered an error processing the request

Important Notes

  • A 200 response with vin: null means the OCR pipeline ran successfully but did not find a valid VIN. Do not retry.
  • Returned VINs are exactly 17 characters, contain only A-Z and 0-9 (never I, O, or Q), and pass internal VIN validation.
  • Body limit is 15 MB. Downscale phone photos to ~1080p / JPEG quality 0.8 before sending - OCR accuracy does not improve at higher resolutions.
  • Configure your HTTP client with a timeout of at least 65 seconds. OCR can be slow on larger images.
  • OCR results are not cached server-side. Sending the same image twice consumes 2 credits.
  • Each request consumes 1 API credit from your monthly allowance.