Loitering Detection Camera API
Viewtron AI security cameras include built-in loitering detection that runs entirely on the camera hardware — no cloud service or external AI software required. When a person or vehicle remains in a defined zone beyond a configurable time threshold, the camera sends an HTTP POST webhook to your server with the detection event data, including a full-frame overview image and a cropped image of the loitering target.
Loitering detection differs from intrusion detection in that it measures dwell time — an intrusion event fires immediately when a target enters a zone, while a loitering event only fires after the target has remained in the zone for longer than the configured time threshold. This makes loitering detection ideal for identifying suspicious behavior where brief presence is normal but prolonged presence is not. All Viewtron IP cameras and NVRs are NDAA compliant.
What You Can Build
- ATM security monitoring — alert when someone lingers near an ATM beyond a normal transaction time
- Retail loss prevention — detect customers dwelling in high-theft areas for extended periods
- Restricted area monitoring — identify unauthorized individuals loitering near secure entrances, server rooms, or utility areas
- Public safety alerts — monitor bus stops, park benches, or public spaces for extended occupancy
- Loading dock security — detect unauthorized vehicles dwelling in delivery zones beyond permitted times
- Progressive response — combine with active deterrent to escalate from light activation to siren based on dwell duration
How It Works
- Configure a loitering zone on the camera — define a polygon region and set the dwell time threshold (seconds)
- Enable object filters — select which target types to monitor (person, vehicle, or both)
- Enable HTTP POST webhooks — point the camera at your server's IP and port
- Your server receives XML when loitering is detected — the POST includes alarm type, zone boundary, target bounding box, and base64 images
- Parse the event using the Viewtron Python SDK (
pip install viewtron) or Node.js SDK - Take action — save images, log to CSV, send alerts, trigger deterrent actions
Event Data Included
Each loitering detection webhook POST contains:
| Field | Description |
|---|---|
smartType | LOITER (IPC loitering detection) |
boundary | Polygon coordinates of the loitering zone |
rect | Bounding box of the loitering target |
eventId / targetId | Unique IDs for the event and tracked target |
status | SMART_START, SMART_PROCEDURE, or SMART_STOP |
sourceBase64Data | Full-frame JPEG image (base64 encoded) |
targetBase64Data | Cropped target JPEG image (base64 encoded) |
currentTime | Detection timestamp |
Parsing Loitering Events
- Python SDK
- Node.js SDK
- IPC XML (v1.x)
The simplest way to receive loitering 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 != "intrusion":
return
# Loitering events use the intrusion category with LOITER alarm type
if event.get_alarm_type() not in ("LOITER", "loitering"):
return
print(f"Loitering detected from {client_ip}")
print(f" Type: {event.get_alarm_description()}")
print(f" Time: {event.get_time_stamp_formatted()}")
overview = event.get_source_image_bytes()
if overview:
with open(f"{IMG_DIR}/{event.get_time_stamp()}-loitering-overview.jpg", "wb") as f:
f.write(overview)
target = event.get_target_image_bytes()
if target:
with open(f"{IMG_DIR}/{event.get_time_stamp()}-loitering-target.jpg", "wb") as f:
f.write(target)
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');
fs.mkdirSync('images', { recursive: true });
const server = new ViewtronServer({ port: 5002 });
server.on('event', (event, clientIP) => {
if (event.category !== 'intrusion') return;
if (event.eventType !== 'LOITER' && event.eventType !== 'loitering') return;
console.log(`Loitering detected from ${clientIP}`);
console.log(` Status: ${event.status}`);
if (event.sourceImageBytes) {
fs.writeFileSync(
`images/${Date.now()}-loitering-overview.jpg`,
event.sourceImageBytes
);
}
if (event.targetImageBytes) {
fs.writeFileSync(
`images/${Date.now()}-loitering-target.jpg`,
event.targetImageBytes
);
}
});
server.start();
Loitering detection uses the LOITER smartType with a <perimeter> block containing the loitering zone boundary:
<?xml version="1.0" encoding="UTF-8" ?>
<config version="1.7" xmlns="http://www.ipc.com/ver10">
<smartType type="openAlramObj">LOITER</smartType>
<deviceName type="string"><![CDATA[Lobby]]></deviceName>
<currentTime type="tint64">1774792701902505</currentTime>
<perimeter>
<perInfo type="list" count="1">
<item>
<eventId type="uint32">5012</eventId>
<targetId type="uint32">4812</targetId>
<status type="perStatus">SMART_START</status>
<boundary type="list" count="4">
<item><point><x type="uint32">1200</x><y type="uint32">800</y></point></item>
<item><point><x type="uint32">7500</x><y type="uint32">800</y></point></item>
<item><point><x type="uint32">7500</x><y type="uint32">8500</y></point></item>
<item><point><x type="uint32">1200</x><y type="uint32">8500</y></point></item>
</boundary>
<rect>
<x1 type="uint32">3200</x1><y1 type="uint32">1500</y1>
<x2 type="uint32">4800</x2><y2 type="uint32">8200</y2>
</rect>
</item>
</perInfo>
</perimeter>
<sourceDataInfo>
<sourceBase64Length>420000</sourceBase64Length>
<sourceBase64Data>... (base64 JPEG) ...</sourceBase64Data>
</sourceDataInfo>
<listInfo count="1">
<item>
<targetImageData>
<targetBase64Length>65000</targetBase64Length>
<targetBase64Data>... (base64 JPEG) ...</targetBase64Data>
</targetImageData>
</item>
</listInfo>
</config>
See the IPC Event Format reference for the complete v1.x XML structure.
Relevant API Endpoints
| Endpoint | Purpose | Reference |
|---|---|---|
| GetSmartLoiteringConfig | Read loitering detection zone and time threshold configuration | Loitering Detection Config |
| SetHttpPostConfig | Configure webhook destination | Webhook Config |
| GetAlarmStatus | Poll current alarm state | Alarm Status |
Integrations
Viewtron loitering detection also integrates with automation platforms via published packages:
| Platform | Package | What It Does |
|---|---|---|
| Home Assistant | viewtron-home-assistant | Loitering events as native HA sensors — automate deterrents, alerts, notifications |
| Node-RED | node-red-contrib-viewtron | Loitering events direct to Node-RED flows — no middleware needed |
Related Applications
- Human Detection & Intrusion — immediate zone entry detection (no dwell time requirement)
- Vehicle Detection & Parking — dwell time detection for vehicles in parking zones (PVD)
- Active Deterrent — trigger sirens and strobe lights when loitering is detected
- Real-Time Object Tracking — continuous position tracking for custom dwell time logic
Related Products
- Viewtron AI Security Cameras — IP cameras with built-in loitering detection
- Viewtron IP Camera NVRs — NVRs with HTTP POST event forwarding
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.