People Counting & Traffic Analytics API
Viewtron AI cameras include built-in people counting that runs entirely on the camera hardware — no cloud service or external software required. When a person, vehicle, or motorcycle crosses a virtual counting line or enters a defined counting area, the camera sends an HTTP POST webhook to your server with the event data, including a full-frame overview image, a cropped image of the counted target, and the boundary or line coordinates that were crossed.
There are two counting methods available, each suited to different use cases. Line counting tracks objects crossing a virtual line and classifies each crossing as an entrance or exit. Area counting tracks objects entering a defined polygon region. Both methods include images with every event, and line counting also supports a polling endpoint to query cumulative entrance/exit statistics without webhooks.
What You Can Build
- Retail foot traffic analytics — count customers entering and exiting a store entrance, track hourly and daily patterns
- Building occupancy monitoring — maintain a real-time occupancy count by tracking entrances minus exits
- Parking lot capacity — count vehicles entering and exiting a lot, display available spaces
- Queue monitoring — count people entering a service area and detect when queue length exceeds a threshold
- Bi-directional traffic analysis — use the line counting direction to separate inbound vs outbound foot traffic
- Multi-zone analytics — deploy area counting across different store sections to identify high-traffic areas
How It Works
- Configure a counting line or area on the camera — draw a virtual line with a direction arrow, or define a polygon region
- Enable HTTP POST webhooks — point the camera or NVR at your server's IP and port
- Your server receives XML when a count event occurs — the POST includes the counting method, target coordinates, boundary geometry, and base64 images
- Parse the event using the Viewtron Python SDK (
pip install viewtron) or Node.js SDK - Track counts and take action — maintain running entrance/exit totals, save images, log to CSV, trigger alerts at thresholds
Counting Methods
Line Counting (targetCountingByLine / PASSLINECOUNT)
Objects are counted when they cross a virtual line drawn on the camera view. The line has a direction arrow — crossings in the direction of the arrow are counted as entrances, and crossings against it are counted as exits. This is the most common method for doorways, hallways, and gates.
| Field | Description |
|---|---|
smartType | PASSLINECOUNT (IPC) or targetCountingByLine (NVR) |
targetType | person, car, or motor |
boundary | tripwire — indicates a line crossing event |
directionLine | Start and end point coordinates of the counting line |
rect | Bounding box of the target (may be all zeros for line counting) |
eventId / targetId | Unique IDs for the event and tracked target |
sourceBase64Data | Full-frame JPEG image (base64 encoded) |
targetBase64Data | Cropped target JPEG image (base64 encoded) |
currentTime | Detection timestamp |
Area Counting (targetCountingByArea / TRAFFIC)
Objects are counted when they enter a defined polygon region. This is useful for open areas, intersections, or zones where a single line crossing is not practical.
| Field | Description |
|---|---|
smartType | TRAFFIC (IPC) or targetCountingByArea (NVR) |
targetType | person, car, or motor |
boundary | area — indicates an area entry event |
pointGroup | Polygon coordinates defining the counting area |
rect | Bounding box of the detected target (x1, y1, x2, y2) |
eventId / targetId | Unique IDs for the event and tracked target |
sourceBase64Data | Full-frame JPEG image (base64 encoded) |
targetBase64Data | Cropped target JPEG image (base64 encoded) |
currentTime | Detection timestamp |
Parsing Counting Events
- Python SDK
- Node.js SDK
- NVR XML — Line Count
- NVR XML — Area Count
The simplest way to receive counting 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)
entrance_count = 0
area_count = 0
def on_event(event, client_ip):
global entrance_count, area_count
if event.category != "counting":
return
print(f"Counting event from {client_ip}")
print(f" Type: {event.get_alarm_type()} ({event.get_alarm_description()})")
# Track running totals
entrance_count += 1
print(f" Running total: {entrance_count}")
overview = event.get_source_image_bytes()
if overview:
with open(f"{IMG_DIR}/{event.get_time_stamp()}-count-overview.jpg", "wb") as f:
f.write(overview)
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 });
let entranceCount = 0;
const server = new ViewtronServer({ port: 5002 });
server.on('event', (event, clientIP) => {
if (event.category !== 'counting') return;
console.log(`Counting event from ${clientIP}`);
console.log(` Type: ${event.eventType} (${event.targetType})`);
console.log(` Boundary: ${event.boundary}`);
entranceCount++;
console.log(` Running total: ${entranceCount}`);
if (event.sourceImageBytes) {
fs.writeFileSync(
`images/${Date.now()}-count-overview.jpg`,
event.sourceImageBytes
);
}
});
server.start();
The NVR v2.0 targetCountingByLine format includes a direction line and target classification:
<?xml version="1.0" encoding="UTF-8"?>
<config version="2.0.0" xmlns="http://www.ipc.com/ver10">
<messageType>alarmData</messageType>
<deviceInfo>
<deviceName><![CDATA[Device Name]]></deviceName>
<ip><![CDATA[192.168.0.60]]></ip>
<mac><![CDATA[58:5B:69:40:F4:0D]]></mac>
<channelId>1</channelId>
</deviceInfo>
<smartType>targetCountingByLine</smartType>
<currentTime>1772140991308000</currentTime>
<eventInfo>
<item>
<eventId>1080</eventId>
<targetId>480</targetId>
<boundary>tripwire</boundary>
<directionLine>
<startPoint><x>3977</x><y>2146</y></startPoint>
<endPoint><x>3977</x><y>9974</y></endPoint>
</directionLine>
<rect><x1>0</x1><y1>0</y1><x2>0</x2><y2>0</y2></rect>
</item>
</eventInfo>
<sourceDataInfo>
<dataType>0</dataType>
<width>1280</width>
<height>720</height>
<sourceBase64Length>441256</sourceBase64Length>
<sourceBase64Data>... (base64 JPEG) ...</sourceBase64Data>
</sourceDataInfo>
<targetListInfo>
<item>
<targetId>480</targetId>
<targetType>person</targetType>
<targetImageData>
<dataType>0</dataType>
<width>336</width>
<height>448</height>
<targetBase64Length>72896</targetBase64Length>
<targetBase64Data>... (base64 JPEG) ...</targetBase64Data>
</targetImageData>
</item>
</targetListInfo>
</config>
The rect in eventInfo is all zeros for line counting. The target crop in targetListInfo still captures the person.
The NVR v2.0 targetCountingByArea format includes the polygon zone boundary:
<?xml version="1.0" encoding="UTF-8"?>
<config version="2.0.0" xmlns="http://www.ipc.com/ver10">
<messageType>alarmData</messageType>
<deviceInfo>
<deviceName><![CDATA[Device Name]]></deviceName>
<ip><![CDATA[192.168.0.60]]></ip>
<mac><![CDATA[58:5B:69:40:F4:0D]]></mac>
<channelId>1</channelId>
</deviceInfo>
<smartType>targetCountingByArea</smartType>
<currentTime>1772145352968000</currentTime>
<eventInfo>
<item>
<eventId>2904</eventId>
<targetId>2204</targetId>
<boundary>area</boundary>
<pointGroup>
<item><x>4450</x><y>4292</y></item>
<item><x>4469</x><y>9015</y></item>
<item><x>1079</x><y>8510</y></item>
<item><x>1344</x><y>4166</y></item>
</pointGroup>
<rect><x1>4431</x1><y1>4409</y1><x2>4971</x2><y2>9791</y2></rect>
</item>
</eventInfo>
<sourceDataInfo>
<dataType>0</dataType>
<width>1280</width>
<height>720</height>
<sourceBase64Length>414832</sourceBase64Length>
<sourceBase64Data>... (base64 JPEG) ...</sourceBase64Data>
</sourceDataInfo>
<targetListInfo>
<item>
<targetId>2204</targetId>
<targetType>person</targetType>
<targetImageData>
<dataType>0</dataType>
<width>336</width>
<height>448</height>
<targetBase64Length>72136</targetBase64Length>
<targetBase64Data>... (base64 JPEG) ...</targetBase64Data>
</targetImageData>
</item>
</targetListInfo>
</config>
Polling Statistics (v2.0 IPC Only)
For line counting, you can query the camera's cumulative entrance/exit counts directly without webhooks using the GetPassLineCountStatistics endpoint. This is useful for periodic polling or dashboard displays.
Request:
GET http://<camera-ip>/GetPassLineCountStatistics
Response:
<?xml version="1.0" encoding="utf-8"?>
<config xmlns="http://www.ipc.com/ver10" version="2.0.0">
<entranceCount>
<person type="uint32">0</person>
<car type="uint32">0</car>
<bike type="uint32">0</bike>
</entranceCount>
<exitCount>
<person type="uint32">0</person>
<car type="uint32">0</car>
<bike type="uint32">0</bike>
</exitCount>
</config>
This returns separate entrance and exit counts for each object type (person, car, bike). The counts are cumulative since the camera was last reset.
Use GetPassLineCountStatistics for simple dashboard displays where you only need current totals. Use webhook events when you need per-event images, timestamps, and real-time processing.
Relevant API Endpoints
| Endpoint | Purpose | Reference |
|---|---|---|
| GetSmartPassLineCountConfig | Read line counting zone configuration | Pass Line Count Config |
| GetPassLineCountStatistics | Query current entrance/exit counts (v2.0 IPC) | Pass Line Count Config |
| SetHttpPostConfig | Configure webhook destination | Webhook Config |
| GetAlarmStatus | Poll current alarm state | Alarm Status |
Integrations
Viewtron people counting also integrates with automation platforms via published packages:
| Platform | Package | What It Does |
|---|---|---|
| Home Assistant | viewtron-home-assistant | People/vehicle counting as native HA sensors for occupancy tracking |
| Node-RED | node-red-contrib-viewtron | Counting events direct to Node-RED flows — no middleware needed |
Related Applications
- Human Detection & Intrusion Detection — detect people entering defined zones with images
- Perimeter Security & Line Crossing — tripwire detection and region entry/exit
- Real-Time Object Tracking — continuous target position data via traject
- Webhook Event Notification — complete webhook setup and format reference
- Viewtron Python SDK — parse counting events in Python
Related Products
- Viewtron AI Security Cameras — IP cameras with built-in people counting
- 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.