Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/api-reference/events/httppostv2-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ IPC IP-AX8D, March 29, 2026, all five data types subscribed:
13:59:08.546 traject stops -- person leaves zone
13:59:19.056 alarmStatus -- perimeterAlarm=false (659 bytes)

14:00:49+ keepalives -- empty body posts every ~90 seconds
14:00:49+ keepalives -- empty body posts about every 90 seconds
```

:::note Keepalive interval and body
The keepalive interval is configurable in the camera's HTTP POST settings (`keepaliveTimeval`, 30-120 seconds; see [Webhook Configuration](/docs/api-reference/alarm/http-post-webhook-config)). The ~90 seconds above reflects that camera's setting, not a fixed value. The empty keepalive body was seen on this IP-AX8D. Other models and firmware send a body: LPR-IP4 firmware 5.3.1 sends a `config` 1.7 document with `messageType` `keepalive`. Older firmware uses a `<DeviceInfo>` root. See [IPC Format: Keepalive](./ipc-event-format.md#keepalive).
:::

**Total: 104 traject posts, 4 smartData+image posts, 2 alarmStatus posts, 3 keepalives**

**Key observations:**
Expand Down
193 changes: 169 additions & 24 deletions docs/api-reference/events/ipc-event-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,46 @@ IP cameras send alarm data directly to your HTTP server using config version `1.

The IPC sends three types of messages: keepalive heartbeats, alarm status changes, and full alarm data with detection details and images.

Several details depend on camera firmware. See [Firmware Differences](#firmware-differences) before you hard-code a field name or value.

## Keepalive

Periodic heartbeat. Uses a `<DeviceInfo>` root element (not `<config>`).
Periodic heartbeat. **The interval is configurable** in the camera's HTTP POST settings (`keepaliveTimeval`, 30-120 seconds; see [Webhook Configuration](/docs/api-reference/alarm/http-post-webhook-config)). Base any "connection lost" timeout on the value you configured, not on a fixed number. For example, an LPR-IP4 on firmware 5.3.1 with the setting at 90 seconds sent a keepalive every 90 seconds over one persistent connection. 90 seconds is an example setting, not a fixed value.

The body depends on firmware, so accept every form below.

### Firmware 5.3.1

Observed on LPR-IP4 firmware 5.3.1. A `<config>` document (version `1.7`) with `messageType` `keepalive` and a `deviceInfo` block. There is no XML declaration.

```xml
<config version="1.7" xmlns="http://www.ipc.com/ver10">
<messageType>keepalive</messageType>
<deviceInfo>
<deviceName><![CDATA[LPR Camera]]></deviceName>
<ip><![CDATA[192.0.2.100]]></ip>
<mac><![CDATA[00:00:00:00:00:00]]></mac>
</deviceInfo>
</config>
```

### Older firmware

Older firmware uses a `<DeviceInfo>` root element (not `<config>`) and includes the serial number.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<DeviceInfo>
<DeviceName>Device Name</DeviceName>
<DeviceNo.>1</DeviceNo.>
<SN><![CDATA[NF40D099BCM0]]></SN>
<ipAddress>192.168.1.192</ipAddress>
<macAddress>58:5B:69:40:F4:0D</macAddress>
<SN><![CDATA[SERIALNUMBER]]></SN>
<ipAddress>192.0.2.100</ipAddress>
<macAddress>00:00:00:00:00:00</macAddress>
</DeviceInfo>
```

Some cameras send keepalive posts with an empty body (see the [httpPostV2 Data Types](./httppostv2-data-types.md) timeline).

## Alarm Status (alarmStatusInfo)

Sent when an alarm state changes. Small post (~660 bytes), no images.
Expand All @@ -48,6 +73,8 @@ Sent when an alarm state changes. Small post (~660 bytes), no images.
</config>
```

`dataTime` follows the camera's date and time display format. The sample above uses `YYYY-MM-DD HH:MM:SS`. LPR-IP4 firmware 5.3.1 sent `MM-DD-YYYY hh:mm:ss AM/PM` (for example `09-21-2026 02:15:30 PM`). Parse both, or use `currentTime` on alarm data posts. License plate alarms use `vehiceAlarm` (firmware spelling).

**Key behavior:**
- `true` arrives shortly after first detection
- `false` arrives after `alarmHoldTime` expires -- NOT when the person leaves
Expand Down Expand Up @@ -128,7 +155,7 @@ When both source and target images are subscribed, the post includes a `<listInf
```xml
<config version="1.7" xmlns="http://www.ipc.com/ver10">
<smartType type="openAlramObj">PEA</smartType>
<subscribeRelation type="subscribeOption">FEATURE_RESULT</subscribeRelation>
<subscribeOption type="subscribeRelation">FEATURE_RESULT</subscribeOption>
<currentTime type="tint64">1563528106584193</currentTime>
<perimeter>
<perInfo type="list" count="1">
Expand Down Expand Up @@ -184,7 +211,9 @@ When both source and target images are subscribed, the post includes a `<listInf
| `boundary` | Zone polygon coordinates (normalized 0-10000) |
| `rect` | Target bounding box (normalized 0-10000) |
| `sourceDataInfo` | Full frame JPEG (when `sourceImage` subscribed) |
| `listInfo/targetImageData` | Cropped target JPEG. `targetType` is numeric: 1=person, 2=car, 4=bike |
| `listInfo/targetImageData` | Cropped target JPEG. `targetType` is numeric (1=person, 2=car, 4=bike) in the samples above. LPR-IP4 firmware 5.3.1 sends a string (`car`) on plate posts, so accept both. |

The `type` attributes are type names, and their spelling varies by firmware. The samples above show `openAlramObj` and `subscribeRelation`. LPR-IP4 firmware 5.3.1 sends `openAlarmObj` and `subscribeRelationV1`. Match on element names (`smartType`, `subscribeOption`), not on `type` attribute values.

## IPC smartType Codes (Complete)

Expand All @@ -203,35 +232,151 @@ When both source and target images are subscribed, the post includes a `<listInf
| `IPD` | People intrusion | `IPD` | `IPDAlarm` | Yes |
| `VFD` | Face detection | `VFD` | `VFDAlarm` | Yes |
| `VFD_MATCH` | Face recognition | `VFD_MATCH` | `VFDAlarm` | Yes |
| `VEHICE` | License plate | `VEHICE` | `vehiceAlarm` | Yes |
| `VEHICE` / `VEHICLE` | License plate (spelling depends on firmware, see [Firmware Differences](#firmware-differences)) | `listInfo` | `vehiceAlarm` | Yes |
| `AOIENTRY` | Region entry | `AOIENTRY` | (undocumented) | Yes |
| `AOILEAVE` | Region exit | `AOILEAVE` | (undocumented) | Yes |
| `PASSLINECOUNT` | Line counting | `PASSLINECOUNT` | (undocumented) | Yes |
| `TRAFFIC` | Area counting | `TRAFFIC` | (undocumented) | Yes |

### LPR Event Fields (VEHICE)
### LPR Event (VEHICE / VEHICLE)

License plate events include plate data in the second `<item>` of `<listInfo>`. The first item contains the overview image, the second contains the plate number, authorization status, and plate crop image.
A plate read arrives as one `FEATURE_RESULT` post. There is no `sourceDataInfo` block. `listInfo` has two items:

| Field | Description |
|-------|-------------|
| `plateNumber` | Detected plate text |
| `vehicleListType` | Plate database status (see table below) |
| `PlateConfidence` | Detection confidence score |
| `plateColor` | Plate color |
| `vehicleDirect` | Vehicle direction (`approach` or `leave`) |
| `targetImageData/targetBase64Data` | Base64 JPEG plate crop image |
- **Item 0** is the overview image (`image` 0, empty `plateNumber`, `width`/`height` 0, empty `targetType`).
- **Item 1** is the plate read and the plate crop (`image` 1, `targetType` `car`).

Shape observed on LPR-IP4 firmware 5.3.1 (HTTP POST V1 layout). Device identity, the timestamp, image data, and vehicle attribute values are placeholders. `IB36NL` is a test plate. The full file is [examples/ipc-v1x/lpr.xml](https://github.com/mikehaldas/IP-Camera-API/blob/main/examples/ipc-v1x/lpr.xml).

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<config version="1.7" xmlns="http://www.ipc.com/ver10">
<types><!-- ... enum lists ... --></types>
<smartType type="openAlarmObj">VEHICE</smartType>
<subscribeOption type="subscribeRelationV1">FEATURE_RESULT</subscribeOption>
<currentTime type="tint64">1785000000123456</currentTime>
<mac type="string"><![CDATA[00:00:00:00:00:00]]></mac>
<sn type="string"><![CDATA[SERIALNUMBER]]></sn>
<deviceName type="string"><![CDATA[LPR Camera]]></deviceName>
<channelId type="uint32">1</channelId>
<plateCount type="uint32">1</plateCount>
<listInfo type="list" count="2">
<item>
<image type="uint32">0</image>
<plateNumber type="string"><![CDATA[]]></plateNumber>
<!-- ... same fields as item 1, all zero ... -->
<targetImageData>
<dataType type="uint32">0</dataType>
<targetType type="targetType"></targetType>
<width type="uint32">0</width>
<height type="uint32">0</height>
<targetBase64Length type="uint32">770384</targetBase64Length>
<targetBase64Data type="string"><![CDATA[... (base64 JPEG overview) ...]]></targetBase64Data>
</targetImageData>
</item>
<item>
<image type="uint32">1</image>
<vehiceId type="uint32">1</vehiceId>
<plateNumber type="string"><![CDATA[IB36NL]]></plateNumber>
<plateCharCount type="uint32">6</plateCharCount>
<vehicleDirect type="vehicleDirectType">approach</vehicleDirect>
<vehicleListType type="vehileMatchAlarmList">whiteList</vehicleListType>
<PlateWidth type="uint32">176</PlateWidth>
<PlateHeight type="uint32">100</PlateHeight>
<SourceImageWidth type="uint32">2688</SourceImageWidth>
<SourceImageHeight type="uint32">1776</SourceImageHeight>
<leftTop><x type="uint32">7559</x><y type="uint32">2072</y></leftTop>
<rightTop><x type="uint32">8214</x><y type="uint32">2072</y></rightTop>
<leftBottom><x type="uint32">7559</x><y type="uint32">2635</y></leftBottom>
<rightBottom><x type="uint32">8214</x><y type="uint32">2635</y></rightBottom>
<PlateConfidence type="uint32" count="9900"/>
<plateColor type="uint32" count="3"/>
<plateColorRate type="uint32" count="0"/>
<plateStyle type="uint32" count="1"/>
<vehiceColor type="uint32" count="0"/>
<plateAngleH type="uint32" count="0"/>
<plateAngleV type="uint32" count="0"/>
<province type="string"></province>
<carAttr>
<color type="vsdCarAttrColorType">white</color>
<type type="vsdCarAttrTypeType">saloon car</type>
<brand type="vsdCarAttrBrandType">Toyota</brand>
<model type="vsdCarAttrModelType">Toyota_Camry</model>
</carAttr>
<carRect>
<x type="uint32">1242</x><y type="uint32"/>
<width type="uint32">586</width><height type="uint32">446</height>
</carRect>
<targetImageData>
<dataType type="uint32">0</dataType>
<targetType type="targetType">car</targetType>
<width type="uint32">176</width>
<height type="uint32">100</height>
<targetBase64Length type="uint32">19520</targetBase64Length>
<targetBase64Data type="string"><![CDATA[... (base64 JPEG plate crop) ...]]></targetBase64Data>
</targetImageData>
</item>
</listInfo>
</config>
```

#### LPR Fields

"Confirmed on" names the firmware where the field was seen in a captured post.

| Field | Description | Confirmed on |
|-------|-------------|--------------|
| `smartType` | `VEHICE` or `VEHICLE`, depending on firmware | 5.1.1, 5.3.1 |
| `currentTime` | Event time from the camera clock, Unix microseconds (16 digits). Check the camera clock before comparing it with arrival time. | 5.3.1 |
| `plateCount` | Number of plates in the post | 5.3.1 |
| `listInfo/item[0]/targetImageData` | Overview JPEG (base64). About 760 KB of base64 text in an LPR-IP4 post. | 5.1.1, 5.3.1 |
| `plateNumber` | Plate text (CDATA). Empty on item 0. | 5.1.1, 5.3.1 |
| `plateCharCount` | Number of characters in the plate text | 5.3.1 |
| `vehicleDirect` | `approach` or `away`. Earlier versions of this page listed `leave`, which has not been seen in a captured post. Treat `leave` like `away` if it appears. | 5.1.1 (`approach`), 5.3.1 (both) |
| `vehicleListType` | Plate list the plate matched (table below). Not sent at all on 5.1.x. | 5.3.1 |
| `PlateConfidence` | Value is in the `count` attribute, on a 0-10000 scale (`count="9900"` = 99%). The element has no text. | 5.3.1 |
| `plateColor` | Numeric code in the `count` attribute (for example `count="3"`), not a color name. The code-to-color mapping is not documented. | 5.3.1 |
| `plateColorRate`, `plateStyle`, `vehiceColor`, `plateAngleH`, `plateAngleV` | Numeric values in the `count` attribute. Meaning not documented. | 5.3.1 |
| `leftTop`, `rightTop`, `leftBottom`, `rightBottom` | Plate corner points, normalized 0-10000. There is no `rect` on IPC plate posts. | 5.3.1 |
| `PlateWidth`, `PlateHeight` | Plate crop size in pixels | 5.3.1 |
| `SourceImageWidth`, `SourceImageHeight` | Full-frame size in pixels | 5.3.1 |
| `province` | Plate region text. Empty in U.S. reads. | 5.3.1 |
| `carAttr/color`, `carAttr/type`, `carAttr/brand`, `carAttr/model` | Vehicle color, type (for example `saloon car`), brand, and model (`Brand_Model` form) | 5.3.1 |
| `carRect` | Vehicle box: `x`, `y`, `width`, `height`. `y` was an empty element. Units not confirmed. | 5.3.1 |
| `listInfo/item[1]/targetImageData` | Plate crop JPEG (base64), `targetType` `car`. About 19 KB of base64 text. | 5.1.1, 5.3.1 |

The post carries no plate group number. Map list names yourself.

**Plate database status (`vehicleListType`):**

| Value | Meaning |
|-------|---------|
| `whiteList` | Plate is on the allow list (within valid date range) |
| `blackList` | Plate is on the block list (within valid date range) |
| `temporaryList` | Plate is on the temporary list (within valid date range) |
| *(field absent)* | Plate is not in the database, or any plate with an expired date range |
| Value | Meaning | Confirmed on |
|-------|---------|--------------|
| `whiteList` | Plate is on the allow list | 5.3.1 |
| `blackList` | Plate is on the block list | 5.3.1 |
| `temporaryList` | Plate is on the temporary list | Not yet confirmed in a captured post |
| *(field absent)* | Plate is on no list. On 5.1.x the field is always absent, even for listed plates. | 5.1.1, 5.3.1 |

Not yet confirmed: plates whose valid date range has expired (allow, block, or temporary) are expected to have `vehicleListType` omitted, so the camera checks date ranges for every list type. Test this on your firmware before you rely on it.

#### Image data

Decode the actual base64 text, and don't size buffers from `targetBase64Length`. On LPR-IP4 firmware 5.3.1 the declared length didn't match the text: the overview declared 770,384 characters and carried about 760,500, and the plate crop declared 19,520 and carried 19,270.

## Firmware Differences

Observed on LPR-IP4 cameras. Behaviour on other models may differ.

| Behaviour | 5.1.1.0 (build 52592) | 5.1.1.0 (build 66800) | 5.3.1 |
|-----------|-----------------------|-----------------------|-------|
| Public API version (`GetDeviceInfo`) | 1.7 | 1.7 | 2.1.0 |
| Plate post layout | V1, config `1.7` | V1, config `1.7` | V1, config `1.7` (also when a V2 row is saved; see [IPC Format (v2.1)](./ipc-http-post-format-v21.md)) |
| `smartType` | `VEHICE` | `VEHICLE` | `VEHICE` |
| `vehicleListType` | Never sent | Never sent | Sent for listed plates (`whiteList`, `blackList`); absent for unlisted plates |
| `vehicleDirect` | `approach` seen on 5.1.1 (build not recorded) | `approach` seen on 5.1.1 (build not recorded) | `approach` and `away` seen |
| `carAttr` vehicle attributes | Not confirmed | Not confirmed | Sent |
| Keepalive body | Not confirmed | Not confirmed | `config` 1.7 + `messageType` `keepalive` + `deviceInfo` |
| `type` attribute names | Not confirmed | Not confirmed | `openAlarmObj`, `subscribeRelationV1` |

The camera validates date ranges internally for **all** list types — not just temporary plates. Any plate with an expired end date (allow, block, or temporary) will have `vehicleListType` omitted entirely.
Accept both `VEHICE` and `VEHICLE`. The spelling doesn't follow firmware age: 5.3.1 is newer than build 66800 and still sends `VEHICE`.

:::tip Application Guides
For step-by-step setup of IPC webhook events, see [Webhook Event Notification API](/docs/applications/webhook-event-notification-api). For traject-based real-time tracking from IPC, see [Real-Time Object Tracking](/docs/applications/real-time-object-tracking-api). For LPR plate database management, see [LPR Configuration](/docs/api-reference/smart-detection/license-plate-recognition-config).
Expand Down
6 changes: 6 additions & 0 deletions docs/api-reference/events/ipc-http-post-format-v21.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ sidebar_position: 9
Verification of direct camera posts on v2.1 firmware is in progress. Until this section is complete, log the raw post body and check for `messageType`, the `smartType` spelling, and where the plate list result appears.

Cameras on v2.1 firmware report `httpPostVersion` `2.1.0`. On a v2.1 LPR camera running 5.3.1 firmware, the HTTP POST V2 event list in the web interface is `ALL`, `MOTION`, `SENSOR`, `AVD`, and `VEHICLE`, and the data-type element is named `subDataType`. See [httpPostV2 Data Types](./httppostv2-data-types.md) and [Webhook Configuration](/docs/api-reference/alarm/http-post-webhook-config).

## V2 rows and the V1 sender

On LPR-IP4 firmware 5.3.1, saving a V2 (`httpPostV2`) row in the web interface also turned on the legacy V1 `httpPost` sender, aimed at the same host, port, and path. The page has no separate V1 switch. In testing with a V2 row saved for `VEHICLE`, every post received used the V1 layout: config version `1.7`, no `messageType` on plate posts, and `smartType` `VEHICE`. No V2-format posts were received. Plate posts from this firmware therefore follow the [IPC Event Format (v1.x)](./ipc-event-format.md#lpr-event-vehice--vehicle), including `vehicleListType` for listed plates.

No V2.1-format post body has been captured yet, so this page does not document one.
Loading
Loading