VisionAlert API Reference
Welcome to the Plate Recognizer VisionAlert API! Use our API to create camera monitoring logs and detect issues such as camera blockage, movement, blurry images, or glare.
For detailed instructions on how to set up VisionAlert, go here.
VisionAlert Cloud API​
Authentication​
All API calls must include an Authorization header containing the API Token in below format:
Authorization: Token YOUR_API_TOKEN
For the commands below, make sure to replace YOUR_API_TOKEN with your API Token. For example, Authorization: Token abcdef123456xxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Get your token from here.
Create Camera Monitoring Log​
This VisionAlert API endpoint creates a camera monitoring log by analyzing an uploaded image for issues such as camera blockage, movement, blurry images, or glare.
HTTP Request​
POST https://api.platerecognizer.com/v1/vision-alert/create-log/
- Content-Type:
multipart/form-data - The
CORSpolicy of this endpoint allows requests from all origins.
POST Parameters​
| Parameter | Required | Description |
|---|---|---|
| upload | Yes | The image file to be analyzed for camera issues. |
| camera_id | Yes | Unique identifier for the camera submitting the image for analysis. |
| tag | No | Tag to associate with the camera. If the tag does not exist, it will be created. If the camera is not already associated with the tag, it will be added. Existing tags are preserved. |
- Shell
- Python
# Upload an image for camera monitoring analysis
curl -X POST \
-H "Authorization: Token YOUR_API_TOKEN" \
-F "camera_id=camera1" \
-F "tag=TAG-XX" \
-F "upload=@/path/to/image.png" \
https://api.platerecognizer.com/v1/vision-alert/create-log/
import requests
# Upload an image for camera monitoring analysis
with open('/path/to/image.png', 'rb') as image_file:
response = requests.post(
'https://api.platerecognizer.com/v1/vision-alert/create-log/',
files={'upload': image_file},
data={
'camera_id': 'camera1',
'tag': 'TAG-XX'
},
headers={'Authorization': 'Token YOUR_API_TOKEN'}
)
print(response.json())
Response​
The API will merely receive send images and return a success message. This is because VisionAlert analyzes all the footage asynchronously, making the results available through the VisionAlert dashboard or webhooks if configured, within an hour from the last image was uploaded.
If successful, the API will return:
{
"message": "Log created successfully."
}
Otherwise, the response is an error message, such as the following:
{
"message": "Camera already uploaded a log recently."
}
The above response indicates that the camera has already uploaded a log recently, and the API will not process the request.
Rate Limits​
- 1 request per second, for any camera is applied, as per our general API rate limiting policy.
- 1 request every 15 minutes for each camera, meaning that each camera can only upload one image every 15 minutes for analysis.
Errors​
| Error Code | Meaning |
|---|---|
| 400 | Bad Request: Missing required parameters or invalid image format |
| 401 | Unauthorized: Invalid or missing API token |
| 403 | Forbidden: VisionAlert is not enabled for your account |
| 429 | Too Many Requests: Rate limit exceeded |
The following endpoints let you retrieve licenses, cameras, logs, and alerts. You can only access resources belonging to your own licenses.
Base URL: https://app.platerecognizer.com/v1/vision-alert/
List Licenses​
Retrieve all VisionAlert licenses for the authenticated user, ordered by most recent first.
HTTP Request​
GET https://app.platerecognizer.com/v1/vision-alert/licenses/
- Shell
- Python
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/licenses/"
import requests
response = requests.get(
'https://app.platerecognizer.com/v1/vision-alert/licenses/',
headers={'Authorization': 'Token YOUR_API_TOKEN'}
)
print(response.json())
Response 200 OK​
Returns a JSON array of license objects.
[
{
"id": 5,
"code": "LIC-ABC123",
"size": 50,
"va_type": "meraki",
"expiration": "2027-01-15T00:00:00Z",
"created": "2026-01-15T10:30:00Z",
"modified": "2026-04-10T14:22:00Z"
}
]
Response Fields​
| Field | Type | Description |
|---|---|---|
id | integer | License ID (used as license_id in other endpoints) |
code | string | License code |
size | integer | Maximum number of cameras allowed |
va_type | string | License type (e.g. meraki, openeye, ftp, nx) |
expiration | datetime | When the license expires |
created | datetime | When the license was created |
modified | datetime | When the license was last updated |
List Cameras​
Retrieve all cameras under a specific VisionAlert license.
HTTP Request​
GET https://app.platerecognizer.com/v1/vision-alert/{license_id}/cameras/
Path Parameters​
| Parameter | Type | Description |
|---|---|---|
license_id | integer | ID of the VisionAlert license |
Query Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter cameras by latest log status. Possible values: normal, anomaly, under_review, offline, config_issue, no_data, pending_retry |
- Shell
- Python
# List all cameras for license ID 5
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/cameras/"
# Filter by status
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/cameras/?status=anomaly"
import requests
response = requests.get(
'https://app.platerecognizer.com/v1/vision-alert/5/cameras/',
params={'status': 'anomaly'},
headers={'Authorization': 'Token YOUR_API_TOKEN'}
)
print(response.json())
Response 200 OK​
Returns a JSON array of camera objects.
[
{
"id": 42,
"serial": "Q2GV-ABCD-1234",
"name": "Front Entrance",
"license": "LIC-ABC123",
"tags": ["site-a", "floor-1"],
"notes": "Installed 2026-01-15",
"latest_status": "normal",
"created": "2026-01-15T10:30:00Z",
"modified": "2026-04-10T14:22:00Z"
}
]
Response Fields​
| Field | Type | Description |
|---|---|---|
id | integer | Camera ID |
serial | string | Camera serial number |
name | string | Camera display name |
license | string | License code |
tags | string[] | List of tag names assigned to the camera |
notes | string | Optional notes for this camera |
latest_status | string | null | Status from the most recent log. null if no logs exist (equivalent to no_data) |
created | datetime | When the camera was registered |
modified | datetime | When the camera was last updated |
List Camera Logs​
Retrieve log entries for a specific camera under a license.
HTTP Request​
GET https://app.platerecognizer.com/v1/vision-alert/{license_id}/cameras/{serial}/logs/
Path Parameters​
| Parameter | Type | Description |
|---|---|---|
license_id | integer | ID of the VisionAlert license |
serial | string | Camera serial number |
Query Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
start | date (YYYY-MM-DD) | No | Filter logs created on or after this date |
end | date (YYYY-MM-DD) | No | Filter logs created before end of this date (inclusive) |
status | string | No | Filter by log status. Possible values: normal, anomaly, under_review, offline, config_issue, no_data, pending_retry |
- Shell
- Python
# Logs for camera C1 within a date range
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/cameras/C1/logs/?start=2026-04-01&end=2026-04-10"
# Only anomaly logs
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/cameras/C1/logs/?status=anomaly"
import requests
response = requests.get(
'https://app.platerecognizer.com/v1/vision-alert/5/cameras/C1/logs/',
params={'start': '2026-04-01', 'end': '2026-04-10', 'status': 'anomaly'},
headers={'Authorization': 'Token YOUR_API_TOKEN'}
)
print(response.json())
Response 200 OK​
Returns a JSON array of camera log objects, ordered by most recent first.
[
{
"id": 1001,
"camera_serial": "Q2GV-ABCD-1234",
"camera_name": "Front Entrance",
"status": "anomaly",
"anomalies": {
"Blur": 0.87,
"Obstruction": 0.65
},
"snapshot": "https://app.platerecognizer.com/media/camera_snapshot/04/10/1430_aB3cD_front.jpg",
"created": "2026-04-10T14:30:00Z"
}
]
Response Fields​
| Field | Type | Description |
|---|---|---|
id | integer | Log entry ID |
camera_serial | string | Serial of the camera that generated this log |
camera_name | string | Display name of the camera |
status | string | Log status (normal, anomaly, under_review, offline, config_issue, pending_retry) |
anomalies | object | {} | Dictionary of detected anomalies and their scores. Only includes anomalies that exceed the camera's configured thresholds. Empty object if none. |
snapshot | string | null | Absolute URL to the snapshot image. null if no snapshot is available. |
created | datetime | When the log was created |
List Anomaly Alerts​
Retrieve anomaly alerts generated for a license.
HTTP Request​
GET https://app.platerecognizer.com/v1/vision-alert/{license_id}/alerts/
Path Parameters​
| Parameter | Type | Description |
|---|---|---|
license_id | integer | ID of the VisionAlert license |
Query Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
start | date (YYYY-MM-DD) | No | Filter alerts created on or after this date |
end | date (YYYY-MM-DD) | No | Filter alerts created before end of this date (inclusive) |
license | string | No | Filter by license code |
sent | boolean | No | Filter by whether the alert notification was sent (true/false) |
- Shell
- Python
# All sent alerts for a license
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/alerts/?sent=true"
# Alerts within a date range
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.platerecognizer.com/v1/vision-alert/5/alerts/?start=2026-04-01&end=2026-04-14"
import requests
response = requests.get(
'https://app.platerecognizer.com/v1/vision-alert/5/alerts/',
params={'sent': 'true', 'start': '2026-04-01', 'end': '2026-04-14'},
headers={'Authorization': 'Token YOUR_API_TOKEN'}
)
print(response.json())
Response 200 OK​
Returns a JSON array of anomaly alert objects, ordered by most recent first.
[
{
"id": 500,
"license": "LIC-ABC123",
"review_status": "pending",
"sent": true,
"cameras": [
{
"serial": "Q2GV-ABCD-1234",
"name": "Front Entrance",
"status": "Anomaly",
"anomalies": {
"Blur": 0.87
}
},
{
"serial": "Q2GV-EFGH-5678",
"name": "Parking Lot B",
"status": "Offline",
"anomalies": {}
}
],
"created": "2026-04-10T15:00:00Z"
}
]
Response Fields​
| Field | Type | Description |
|---|---|---|
id | integer | Alert ID |
license | string | License code |
review_status | string | Review status of the alert: pending, has_anomaly, or no_anomaly |
sent | boolean | Whether notification (email/webhook) was sent for this alert |
cameras | object[] | List of cameras involved in this alert |
cameras[].serial | string | Camera serial number |
cameras[].name | string | Camera display name |
cameras[].status | string | Camera status display label (e.g. "Anomaly", "Offline", "Normal") |
cameras[].anomalies | object | Detected anomalies with scores, above threshold. Empty object if none. |
created | datetime | When the alert was created |
Status Codes Summary​
| Code | Description |
|---|---|
200 | Success — returns the requested data |
401 | Unauthorized: Invalid or missing API token |
403 | Forbidden: Resource does not belong to the authenticated user |
Enum Reference​
Camera / Log Status​
| Value | Description |
|---|---|
normal | Camera is operating normally |
anomaly | Anomaly detected (blur, obstruction, glare, or position change) |
under_review | Log is awaiting manual review |
offline | Camera is offline / unreachable |
config_issue | Configuration error |
no_data | No logs received yet |
pending_retry | Processing failed, scheduled for retry |
Review Status (Alerts)​
| Value | Description |
|---|---|
pending | Alert has not been reviewed |
has_anomaly | Reviewed — confirmed anomaly |
no_anomaly | Reviewed — false positive |
Anomaly Types​
| Key | Description |
|---|---|
Blur | Image blur detected |
Obstruction | Camera view is obstructed |
Glare | Glare or overexposure detected |
Position change | Camera has shifted position |