License Plate Reader — ANPR / LPR for Photos & Video avatar

License Plate Reader — ANPR / LPR for Photos & Video

Pricing

from $2.10 / 1,000 image processeds

Go to Apify Store
License Plate Reader — ANPR / LPR for Photos & Video

License Plate Reader — ANPR / LPR for Photos & Video

Read license plates from photos and CCTV videos: plate text, confidence, plate box, vehicle make, model and color. Trained on real Brazilian road cameras (old and Mercosur plates). Video: one row per vehicle passing. No GPU, pay per image or minute.

Pricing

from $2.10 / 1,000 image processeds

Rating

0.0

(0)

Developer

Leandro Zanatta

Leandro Zanatta

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 days ago

Last modified

Categories

Share

License Plate Reader — ANPR / LPR API for Photos & Video

Read license plates from photos, camera snapshots and CCTV videos. For every plate you get the plate text, a confidence score, the plate box, and the vehicle that carries it: type, make and model and color. Videos return one row per vehicle passing, with the time it appeared and left, instead of hundreds of duplicate reads.

The models were trained on real Brazilian road and street cameras and read old Brazilian plates (ABC-1234) and Mercosur plates (ABC1D23), plus Argentina, Paraguay and Uruguay layouts. Runs on CPU, no GPU or SDK to install.

Plates read on three public photos: EUE4635 on a Fiat Uno, EPF5030 on a VW Voyage, KFG1623 on a car in the background, and KLV8465 on a plate close-up

Real output of this Actor on public photos from Wikimedia Commons (CC BY 2.0 and public domain).

Why use it

  • 🎯 Accurate on real cameras: 98% of plates read exactly right (every character) on held-out crops from Brazilian road cameras, 95.6% on a larger mixed sample. Letter/digit mix-ups (O/0, I/1, B/8) are corrected using the plate layout.
  • 🚗 More than the plate: vehicle type, make and model (over 200 cars, trucks and buses common in Brazil, plus motorcycles) and color, linked to each plate.
  • 🎞️ Video-aware: the same plate seen in many frames becomes one sighting with first/last time, number of reads and the best crop.
  • 🧹 Clean results: only reads that match a real plate format are returned (switch off to get everything).
  • 💸 Pay per use: per image or per minute of video. No subscription, no per-camera licence. Failed files are free.
  • 🧩 Works anywhere: API, schedules, webhooks, Make, Zapier, n8n and AI agents (MCP).

Who uses it

SectorTypical use
Parking lots, garages & condominiumsLog entries and exits from gate cameras, check registered vehicles
Logistics, yards & fleetsRecord trucks arriving at docks and yards, match them with orders
Security companies & monitoring centresSearch recorded footage for a plate after an incident
Car washes, workshops & dealershipsIdentify returning customers' vehicles automatically
Insurance & claimsExtract plate, make, model and color from claim photos
Toll, traffic & smart-city projectsCount and classify vehicles, build origin-destination studies
AI & data teamsLabel datasets, evaluate own models, pre-filter footage

What you get per plate

FieldMeaning
platePlate text without dash, e.g. EUE4635 or RDY7G98
formatBR (old Brazil), BR-MERCOSUR, AR-MERCOSUR, AR, PY/UY
confidenceAverage character confidence (0–1)
detectionConfidenceHow sure the detector is that the box is a plate
boxPlate position in pixels (x1, y1, x2, y2)
rawTextThe read before layout correction (only when it changed)
vehicletype (car, truck, van, bus, motorcycle…), make, model, color, their confidences and box
plateImageUrl, vehicleImageUrlCrops, when Save plate images is on

Make and model are only named when the detector is confident (about 81% right at that level); otherwise you still get the vehicle box and color.

Input

FieldTypeDefaultDescription
Photos (imageUrls)array—JPEG, PNG, WebP, BMP, TIFF up to 50 MB. Plate close-ups and crops work too
Videos (videoUrls)array—MP4, MKV, AVI, MOV, TS… up to 4 GB. Google Drive and Dropbox links work
Frames read per second (framesPerSecond)string22 for gates, parking and city traffic; 4–5 for fast highway traffic
Max minutes per video (maxDurationMinutes)integer120Only the first N minutes are read and billed
Vehicle make, model and color (includeVehicle)booleantrueAdd the vehicle carrying each plate
Save plate images (savePlateImages)booleanfalseStore crops of plates (and vehicles in videos)
Only plates in a known format (onlyValidPlates)booleantrueDrop partial and unknown-layout reads
Minimum read confidence (minTextConfidence)string0.5Raise to 0.8 for fewer, surer reads
Minimum plate detection confidence (minPlateConfidence)string0.25Detector threshold
{
"videoUrls": ["https://example.com/nvr/gate-entrance-2026-10-12.mp4"],
"framesPerSecond": "2",
"savePlateImages": true
}

Output

Photos: one row per image.

{
"sourceUrl": "https://example.com/gate/cam1-0042.jpg",
"width": 1280, "height": 720,
"platesFound": 1,
"plateNumbers": ["RYN8A72"],
"plates": [{
"plate": "RYN8A72", "format": "BR-MERCOSUR", "confidence": 0.939, "detectionConfidence": 0.929,
"box": { "x1": 483, "y1": 383, "x2": 565, "y2": 420 },
"vehicle": { "type": "car", "make": "Hyundai", "model": "Hb20", "confidence": 0.983, "color": "white",
"colorConfidence": 0.979, "box": { "x1": 237, "y1": 151, "x2": 669, "y2": 485 } }
}],
"vehiclesDetected": 1
}

Videos: one row per plate sighting (a vehicle passing), plus a SUMMARY-video001 record in the key-value store with all plate numbers, minutes read and billed.

{
"sourceUrl": "https://example.com/nvr/gate-entrance.mp4",
"sighting": 3,
"plate": "RDY7G98", "format": "BR-MERCOSUR", "confidence": 0.94,
"firstSeenSeconds": 812.5, "lastSeenSeconds": 815.0, "bestFrameSeconds": 813.5, "reads": 6,
"vehicle": { "type": "car", "make": "Hyundai", "model": "Hb20", "color": "white" },
"plateImageUrl": "https://api.apify.com/v2/key-value-stores/.../records/video001-plate0003.jpg",
"vehicleImageUrl": "https://api.apify.com/v2/key-value-stores/.../records/video001-vehicle0003.jpg"
}

Failed files return an error field and are not billed.

Pricing

Pay per image processed or per started minute of video read, plus a tiny per-run start fee. Apify plan discounts apply automatically (see the Pricing tab).

ExampleBilled
1 photo1 image
1,000 claim photos1,000 images
1 hour of a gate camera60 video minutes

Use Max minutes per video or the run's maximum cost to cap spending; the Actor stops cleanly at the limit.

Use it from code or an AI agent

Python: plates entering a gate last night

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("adorable_partial/license-plate-reader").call(run_input={
"videoUrls": ["https://example.com/nvr/gate-night.mp4"],
"savePlateImages": True,
})
for s in client.dataset(run["defaultDatasetId"]).iterate_items():
if "plate" in s:
v = s.get("vehicle") or {}
print(f'{s["firstSeenSeconds"]:>8.1f}s {s["plate"]} {v.get("make")} {v.get("model")} {v.get("color")}')

JavaScript: read plates in photos

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('adorable_partial/license-plate-reader').call({
imageUrls: ['https://example.com/parking/cam1-snapshot.jpg'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].plateNumbers);

HTTP (synchronous, one call)

curl -X POST "https://api.apify.com/v2/acts/adorable_partial~license-plate-reader/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"imageUrls": ["https://example.com/snapshot.jpg"]}'

No-code and agents: send camera snapshots from Make, Zapier or n8n, trigger runs from webhooks or schedules, or let an AI agent read plates through the Apify MCP server.

Tips for best results

  • The plate should be at least about 80 px wide in the image; zoom the camera on the lane, not the whole street.
  • Avoid strong motion blur: use a short shutter on gate cameras, or raise Frames read per second for fast traffic.
  • At night, infrared cameras work well; headlight glare on the plate does not.
  • Plates of other countries are detected, but the reader is tuned for Brazil and Mercosur. Turn off Only plates in a known format to see every read.

FAQ

Does it look up the owner or the vehicle registration? No. It reads what is visible in your images. It does not query any registry or database.

Which countries? Brazil (old and Mercosur), Argentina, Paraguay and Uruguay layouts are validated. Other plates can be read with the format filter off, with lower accuracy.

Can it read motorcycle plates (two rows)? Yes, characters are ordered row by row.

Can I use live RTSP camera streams? Not directly: send recorded clips or periodic snapshots (e.g. every few seconds from your NVR, scheduled through the API).

Is my footage kept? Files are processed inside your run and stored only in your own Apify storage, under your account's data-retention settings. Nothing is sent to third parties.

Responsible use

License plates are personal data under LGPD (Brazil) and GDPR (EU). Process only images you are allowed to process, for a legitimate purpose (access control, security, logistics, claims), keep results only as long as needed, and inform people where the law requires it (e.g. signs at camera-monitored entrances). Do not use this Actor to track or profile individuals.

Support

A plate read wrong? Open an issue in the Issues tab with the image (or a crop) and the correct text: it helps improve the models.

Need a different tool? Request it

Missing a feature, an input or output format, or a whole different tool for your workflow? Open an issue in the Issues tab and describe what you need:

  • what goes in (files, URLs, data) and what should come out,
  • roughly how much you process (per day or month),
  • one example, if you can share it.

Requests with a real use case get built, either as a new option in this Actor or as a new Actor in this collection, and you get notified in the issue when it's live. Every request is read.