License Plate OCR

Extract a license plate string from a vehicle photo with optional region-specific format validation

POST Request
~1-15s response
1 credit per request

Endpoint

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

Request Body (JSON)

FieldTypeRequiredDescription
imagestringRequiredBase64-encoded image. Optional data:image/<fmt>;base64, prefix is stripped automatically.
countrystringOptional2-letter region code (case-insensitive). When set, the result must additionally pass region-specific plate format validation. See supported list below.
tokenstringRequiredAPI authentication token (query parameter)

Supported Country Codes

skczdeatplhurobghrsirsfrgbitesptbenlsenodkfichiegrusca

Request Examples

cURL

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

JavaScript

async function extractPlate(file, country) {
  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-plate?token=YOUR_API_KEY',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ image: dataUrl, country })
    }
  );

  return response.json();
}

Python

import base64
import requests

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

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

Response Examples

Plate found (200)

{
  "plateNumber": "BA123AB",
  "confidence": 0.94
}

No plate found (200)

{
  "plateNumber": null,
  "confidence": null
}

Error Response (400)

{
  "error": "Invalid country \"xx\". Supported: sk, cz, de, at, pl, hu, ro, bg, hr, si, rs, fr, gb, it, es, pt, be, nl, se, no, dk, fi, ch, ie, gr, us, ca"
}

Response Fields

FieldTypeDescription
plateNumberstring | nullUppercase plate string with no spaces or dashes; null when no plate found
confidencenumber | nullSelf-reported confidence in [0, 1]; null when no plate was found

Error Codes

400

Bad Request

Missing image, invalid base64 payload, or unsupported country

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 plateNumber: null means OCR ran successfully but did not find a valid plate. Do not retry.
  • Plate strings are returned uppercase, with no spaces or dashes (BA123AB, not BA-123 AB).
  • 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.