License Plate Recognition Camera API (LPR/ALPR)
Viewtron AI security cameras include built-in license plate recognition (LPR/ALPR) that runs entirely on the camera hardware — no cloud service, external software, or third-party LPR engine required. When a vehicle passes through the camera's detection zone, the camera reads the license plate and sends an HTTP POST webhook to your server with the plate number, a cropped plate image, and (on NVR v2.0) detailed vehicle attributes including type, color, brand, and model.
The API also supports managing an on-camera plate database with whitelist and blacklist entries, enabling automated gate access control without any middleware. Plates can be added with date ranges and owner information. The camera includes a Wiegand output for direct integration with gate controllers and access control panels. All Viewtron IP cameras and NVRs are NDAA compliant.
What You Can Build
- Automated gate access control — open gates and barriers when whitelisted plates are detected, using Wiegand output or webhook-triggered relay
- Vehicle access logs — record every plate read with timestamp, plate image, and authorization status for parking garages, gated communities, or corporate campuses
- Visitor management systems — pre-register expected visitor plates with date ranges using AddLicensePlates, automatically grant access on arrival
- Blacklist alerting — receive instant notifications when a blacklisted plate is detected on property
- Fleet tracking — monitor arrival/departure times for company vehicles across multiple camera locations
- Law enforcement integration — feed plate reads into stolen vehicle databases or BOLO systems in real time
- Parking enforcement — detect unauthorized vehicles and trigger alerts or record violations with plate crop images
How It Works
- Install an LPR camera at the vehicle entry point — position the camera to capture plates at the correct angle and distance
- Configure LPR detection on the camera — set the plate region (U.S.A, Canada, Europe, etc.), sensitivity, and detection zone
- Enable HTTP POST webhooks — point the camera or NVR at your server's IP and port
- Manage the plate database (optional) — add plates to the whitelist or blacklist using the AddLicensePlates API with owner info
- Your server receives XML when a plate is read — the POST includes the plate number, plate group status, plate crop image, and vehicle attributes
- Parse the event using the Viewtron Python SDK (
pip install viewtron) or raw XML parsing in any language - Take action — log the plate read, trigger a gate relay, send alerts, or update your database
Event Data
Each LPR webhook POST contains:
| Field | Description |
|---|---|
smartType | VEHICE (IPC) or vehicle (NVR) |
plateNumber / licensePlateNumber | Detected plate text (e.g., JP116D) |
vehicleListType | IPC: whiteList, blackList, temporaryList, or absent if not in database |
licensePlateMatchInfo/groupName | NVR: user-defined group name (e.g., "Whitelist", "Residents"), or absent if not in database |
licensePlateAttribute/color | Plate color (NVR v2.0) |
carAttribute/carType | Vehicle type: sedan, suv, mpv, truck, etc. (NVR v2.0) |
carAttribute/color | Vehicle color (NVR v2.0) |
carAttribute/brand | Vehicle brand: GMC, Ford, Toyota, etc. (NVR v2.0) |
carAttribute/model | Vehicle model: GMC_SAVANA, etc. (NVR v2.0) |
rect | Plate bounding box coordinates (x1, y1, x2, y2) |
targetBase64Data | Cropped plate JPEG image (base64 encoded, ~10-20 KB) |
sourceBase64Data | Full-frame overview JPEG image (base64 encoded, ~400-500 KB) |
currentTime | Detection timestamp |
Parsing LPR Events
- Python SDK (Server)
- Node.js SDK
- NVR XML (v2.0)
- IPC XML (v1.x)
The simplest way to receive LPR events. The SDK's ViewtronServer handles HTTP connections, keepalives, XML parsing, and version detection — you just write the callback:
pip install viewtron
from viewtron import ViewtronServer
import os
IMG_DIR = "images"
os.makedirs(IMG_DIR, exist_ok=True)
def on_event(event, client_ip):
if event.category != "lpr":
return
plate = event.get_plate_number()
group = event.get_plate_group() # "whiteList", NVR group name, or ""
print(f"Plate: {plate} | Group: {group or 'Unknown'}")
# Save plate crop image
plate_jpg = event.get_target_image_bytes()
if plate_jpg:
with open(f"{IMG_DIR}/{plate}.jpg", "wb") as f:
f.write(plate_jpg)
# NVR v2.0 includes vehicle attributes
if event.get_alarm_type() == "vehicle":
print(f" Vehicle: {event.get_car_brand()} {event.get_car_model()}")
server = ViewtronServer(port=5002, on_event=on_event)
server.serve_forever()
See the Python SDK reference for the full list of methods and event classes.
npm install viewtron-sdk
const { ViewtronServer } = require('viewtron-sdk');
const fs = require('fs');
const path = require('path');
const IMG_DIR = 'images';
if (!fs.existsSync(IMG_DIR)) fs.mkdirSync(IMG_DIR);
const server = new ViewtronServer({ port: 5002 });
server.on('event', (event, clientIP) => {
if (event.category !== 'lpr') return;
console.log(`Plate: ${event.plateNumber} | Group: ${event.plateGroup || 'Unknown'}`);
// Save plate crop image
if (event.targetImageBytes) {
fs.writeFileSync(
path.join(IMG_DIR, `${event.plateNumber}.jpg`),
event.targetImageBytes
);
}
// NVR v2.0 includes vehicle attributes
if (event.vehicle) {
console.log(` Vehicle: ${event.vehicle.brand} ${event.vehicle.model}`);
}
});
server.start();
See the Node.js SDK reference for all event properties and server options.
The NVR v2.0 format uses licensePlateListInfo with detailed vehicle attributes and licensePlateMatchInfo for plate database group matching:
<?xml version="1.0" encoding="UTF-8"?>
<config version="2.0.0" xmlns="http://www.ipc.com/ver10">
<messageType>alarmData</messageType>
<deviceInfo>
<deviceName><![CDATA[Parking Entrance]]></deviceName>
<ip><![CDATA[192.168.0.60]]></ip>
<mac><![CDATA[58:5B:69:40:F4:0D]]></mac>
<channelId>2</channelId>
</deviceInfo>
<smartType>vehicle</smartType>
<currentTime>1772210268473000</currentTime>
<sourceDataInfo>
<sourceBase64Length>483768</sourceBase64Length>
<sourceBase64Data>... (base64 JPEG overview) ...</sourceBase64Data>
</sourceDataInfo>
<licensePlateListInfo>
<item>
<targetId>104</targetId>
<rect>
<x1>1104</x1><y1>546</y1>
<x2>1232</x2><y2>610</y2>
</rect>
<licensePlateAttribute>
<licensePlateNumber><![CDATA[JP116D]]></licensePlateNumber>
<color>white</color>
</licensePlateAttribute>
<licensePlateMatchInfo>
<groupName><![CDATA[Whitelist]]></groupName>
</licensePlateMatchInfo>
<carAttribute>
<carType><![CDATA[mpv]]></carType>
<color><![CDATA[white]]></color>
<brand><![CDATA[GMC]]></brand>
<model><![CDATA[GMC_SAVANA]]></model>
</carAttribute>
<targetImageData>
<targetBase64Length>2760</targetBase64Length>
<targetBase64Data>... (base64 JPEG plate crop) ...</targetBase64Data>
</targetImageData>
</item>
</licensePlateListInfo>
</config>
See the NVR Event Format reference for the complete v2.0 XML structure.
The IPC v1.x format uses listInfo with the plate number and whitelist/blacklist status:
<?xml version="1.0" encoding="UTF-8"?>
<config version="1.7" xmlns="http://www.ipc.com/ver10">
<smartType type="openAlramObj">VEHICE</smartType>
<currentTime type="tint64">1732045234584193</currentTime>
<sourceDataInfo>
<sourceBase64Length type="uint32">418200</sourceBase64Length>
<sourceBase64Data type="string">... (base64 JPEG overview) ...</sourceBase64Data>
</sourceDataInfo>
<listInfo type="list" count="2">
<item>
<targetImageData>
<targetBase64Length type="uint32">52480</targetBase64Length>
<targetBase64Data type="string">... (base64 JPEG overview crop) ...</targetBase64Data>
</targetImageData>
</item>
<item>
<plateNumber type="string"><![CDATA[ABC1234]]></plateNumber>
<vehicleListType type="string">whiteList</vehicleListType>
<targetImageData>
<targetBase64Length type="uint32">8640</targetBase64Length>
<targetBase64Data type="string">... (base64 JPEG plate crop) ...</targetBase64Data>
</targetImageData>
</item>
</listInfo>
</config>
The IPC smartType uses VEHICE (note the typo in the firmware — not VEHICLE). The NVR uses vehicle.
See the IPC Event Format reference for the complete v1.x XML structure.
Managing the Plate Database
The LPR camera maintains an on-device plate database. Use the Viewtron Python SDK or the raw API to manage plates:
- Python SDK
- curl
from viewtron import ViewtronCamera
camera = ViewtronCamera("192.168.0.20", "admin", "password")
# Add a plate to the allow list
camera.add_plate("ABC1234")
# Query the database
plates = camera.get_plates()
for plate in plates:
print(plate["plate_number"], plate["owner"])
# Update plate details
camera.modify_plate("ABC1234", owner="Mike", telephone="555-1234")
# Remove a plate
camera.delete_plate("ABC1234")
# Add a plate
curl -u admin:password -X POST http://192.168.0.20/AddLicensePlates \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<config version="2.1.0" xmlns="http://www.ipc.com/ver10">
<licensePlates type="list" maxCount="100" count="1">
<item>
<index>1</index>
<licensePlateNumber><![CDATA[ABC1234]]></licensePlateNumber>
<groupId><![CDATA[1]]></groupId>
</item>
</licensePlates>
</config>'
# Query the database
curl -u admin:password -X POST http://192.168.0.20/GetLicensePlates \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<config version="2.1.0" xmlns="http://www.ipc.com/ver10">
<searchFilter>
<maxResult>50</maxResult>
<resultOffset>1</resultOffset>
<groupId><![CDATA[1]]></groupId>
</searchFilter>
</config>'
See the LPR Config API reference for the complete plate database API including ModifyLicensePlate and DeleteLicensePlate.
Relevant API Endpoints
| Endpoint | Purpose | Reference |
|---|---|---|
| GetSmartVehicleConfig | Read LPR detection settings (sensitivity, region, dedup mode) | LPR Config |
| AddLicensePlates | Add plates to the database | LPR Config |
| GetLicensePlates | Query the plate database with pagination | LPR Config |
| ModifyLicensePlate | Update plate details (owner, phone) | LPR Config |
| DeleteLicensePlate | Remove a plate from the database | LPR Config |
| SetHttpPostConfig | Configure webhook destination | Webhook Config |
| GetAlarmStatus | Poll current alarm state | Alarm Status |
Viewtron LPR cameras include a Wiegand output that sends the plate number directly to gate controllers and access control panels. This works independently of the HTTP API — the camera can simultaneously send Wiegand signals to a gate controller and HTTP POST webhooks to your software.
Integrations
Viewtron LPR cameras also integrate with automation platforms via published packages:
| Platform | Package | What It Does |
|---|---|---|
| Home Assistant | viewtron-home-assistant | Plate reads + images as native HA sensors via MQTT — automate gates, lights, alerts |
| Node-RED | node-red-contrib-viewtron | Plate reads direct to Node-RED flows — no middleware needed |
Related Applications
- Vehicle Detection & Parking Management — detect vehicles without reading plates
- Relay Control & IoT Automation — trigger gate relays based on plate authorization
- Webhook Event Notification — complete webhook setup and format reference
- Human Detection & Intrusion Detection — detect people in the same zones
- Viewtron Python SDK — ViewtronServer, ViewtronEvent, and plate database management
Related Products
- Viewtron LPR Cameras — IP cameras with built-in license plate recognition
- Viewtron LPR Gate Access Camera Systems — complete LPR systems for gated communities and commercial facilities
- Viewtron IP Camera NVRs — NVRs with HTTP POST event forwarding
- Best License Plate Recognition Cameras — buyer's guide comparing LPR camera options
Video Guides
- LPR Camera API Setup and Demo — video walkthrough of configuring LPR webhooks and viewing live plate reads
- ANPR / LPR Camera System Overview — camera installation, plate capture zones, and system design
- LPR Camera Installation Best Practices — mounting angles, distances, and IR illumination
Questions & Development Inquiries
- Email: mike@viewtron.com
- Phone: 561-433-8488
- Forum: NVR Webhook Setup Guide
Mike Haldas is available for questions, consultation, and custom software development for Viewtron API related projects. Email details about your project to mike@viewtron.com.