Milestone XProtect Nodes
Nodes for connecting a flow to a Milestone XProtect VMS. Events from XProtect can drive flow logic, and the flow can act back on the VMS: raise events, control recording, switch outputs and create bookmarks.
The camera talks to the XProtect API Gateway directly over HTTPS and WebSocket. There is no plug-in to compile, no MIP SDK and no Windows service to install.
Requirements
| Requirement | Detail |
|---|---|
| XProtect version | 2023 R3 or later. The Events and State WebSocket API used by the subscribe node was introduced in 2023 R3 |
| API Gateway | Must be installed. It is mandatory from 2023 R3 onward |
| Event Server | Must be running. Configuration endpoints keep working without it, but events and actions do not |
| Account | A basic user. Windows and Active Directory accounts are not supported |
| Network | The camera needs outbound access to the API Gateway host, normally port 443 |
Editions
Verified on XProtect Corporate. Support on Professional+ has not been confirmed.
Milestone Connection
Opens a connection to an XProtect system and publishes a Conn Key that the other Milestone nodes consume. This mirrors how the SQL Connection node works: only the key travels along edges, never the credentials.
Category: Milestone
Functionality
- Authenticates against the built-in identity provider using a basic user
- Connects on its own as soon as the flow starts, with no trigger input
- Retries automatically with backoff from 5 up to 60 seconds if the server is unreachable
- Re-authenticates on its own, since XProtect tokens last one hour and no refresh token is issued
- One connection node can feed any number of subscribe and action nodes
Outputs
| Name | Type | Description |
|---|---|---|
| Connected | Boolean | TRUE once authenticated against XProtect |
| Conn Key | String | Feed this into the Milestone subscribe and action nodes |
| Last Error | String | Message from the most recent connection failure |
Properties
| Field | Description |
|---|---|
| Host | Management Server host. https is assumed unless a scheme is typed |
| Username | A basic user, not a Windows or AD account |
| Password | Password for that user |
| Allow untrusted certificate | Accepts a self signed certificate. XProtect installs commonly ship one |
| Timeout | Request timeout in seconds |
Press Test connection to check the setup before wiring anything up. The result reports how many event types are available and, separately, whether the Event Server is reachable. That distinction matters: configuration endpoints answer even when the Event Server is stopped, so a connection can look healthy while events and actions silently do nothing.
Untrusted certificates
Traffic stays encrypted, but the server identity is not verified. Prefer a trusted certificate where the customer can provide one.
Milestone Event (Subscribe)
Subscribes to XProtect events and turns them into flow signals. Each event you select becomes its own output.
Category: Milestone
Inputs
| Name | Type | Description |
|---|---|---|
| Conn Key | String | Key from a Milestone Connection node |
Outputs
| Name | Type | Description |
|---|---|---|
| New Event | Boolean | Pulses TRUE for one tick when any selected event arrives |
| Event Gap | Boolean | Pulses TRUE when the connection dropped long enough that events were missed |
| Last Source | String | Resource path of the most recent event, for example cameras/{id} |
| (one per selected event) | Boolean | Pulses TRUE for one tick each time that event fires |
Choosing events
Press Setup events to open the picker. Events are grouped the way the Milestone Management Client groups them:
- Devices: Predefined Events and Configurable Events
- Hardware: Predefined Events and Configurable Events
- External Events: Predefined Events and User-defined Events
- Recording Servers, Servers, System, System Monitor, MIP Plugin Events
ONVIF driver events are nested by their topic path under Onvif Events, so
Device/IO/OutputPort becomes Device > IO > OutputPort, which puts paired rising and falling
events next to each other. Search matches both the friendly name and the raw topic, so searching
for OutputPort works even though the tree shows the readable name.
A typical system exposes several hundred event types. The validation system had 486.
Pinning an event to specific devices
Most XProtect event types are device scoped. "Recording Started" on its own tells you a recording began somewhere, not which camera. Each selected event can therefore be restricted to specific sources.
- Leave the source list empty to accept the event from any source
- Pick one or more devices to accept it only from those
- Only the source kinds the event actually accepts are offered, read from the event's own definition. A microphone-only event will not offer cameras
- Events that are not device scoped say so and offer no source list
Filtering happens on the Milestone side wherever possible, so pinned subscriptions do not pull traffic the flow will discard.
Reconnects and gaps
The node reconnects automatically and asks XProtect to resume the session, which replays events that arrived while it was disconnected.
XProtect keeps an inactive session for about 30 seconds. Reconnects inside that window lose nothing. A longer outage means the events in between are gone, and the node pulses Event Gap rather than continuing as if nothing happened. Wire that output up if losing an event matters, for example to re-read state instead of assuming continuity.
If no data arrives at all for two minutes the connection is recycled. Milestone documents no heartbeat for this API, so the node does not rely on the server noticing a dead socket first.
Batched events
One frame from Milestone can carry several events. The node queues them and emits one pulse per tick, so two events of the same type arriving together are not collapsed into one.
Milestone Action
Performs actions inside XProtect. Each configured action becomes one input; a rising edge performs it.
Category: Milestone
Inputs
| Name | Type | Description |
|---|---|---|
| Conn Key | String | Key from a Milestone Connection node |
| (one per configured action) | Boolean | Rising edge performs that action |
| (one per bookmark placeholder) | String | Value substituted into bookmark text |
Outputs
| Name | Type | Description |
|---|---|---|
| Connected | Boolean | TRUE once the node has authenticated |
| Last Action OK | Boolean | TRUE when the most recent action was accepted |
| Last Error | String | Message from the most recent failure |
Available actions
| Action | Targets | Notes |
|---|---|---|
| Trigger user defined event | User defined events | Fires an event your rules and alarms can react to |
| Start recording | Cameras, microphones, speakers, metadata | Ignored harmlessly if a rule is already recording |
| Stop recording | Same | |
| Activate output | Outputs | Holds the output on |
| Deactivate output | Outputs | Holds the output off |
| Create bookmark | Cameras and other recording devices | Header and description support placeholders |
Only user defined events can be raised by an integration. Other event types can be observed with the subscribe node but not triggered. Create them in the Milestone Management Client, then press Reload from Milestone in the picker.
Placeholders in bookmark text
Bookmark header and description support $name placeholders, the same syntax as the JSON
Placeholder node.
Writing this in a bookmark header:
adds a string input named plate and one named zone to the node. Whatever is on those inputs at
the moment the action fires is substituted into the text.
- The same placeholder used by several bookmarks shares one input
- An empty input substitutes an empty string. The bookmark is still created, so a missing value never silently swallows the whole action
- Values are read at the moment of the rising edge, not when the request is sent, so a slow server cannot produce stale text
Configuring actions
Press Setup actions. The dialog has three columns: choose the action and its target, fill in its details, then review the list of inputs the node will expose. Actions can be reordered, and the order is the order of the inputs on the node.
A bookmark requires a header. Milestone itself accepts a headerless bookmark, but it shows up blank in Smart Client and is useless to an operator, so the node refuses it.
Worked example
Reading a temperature from an OPC UA server and marking the recording when it goes out of range:
- Milestone Connection points at the VMS and publishes its Conn Key
- OPC UA Read polls the temperature
- Compare checks it against a limit
- Milestone Action takes the comparison on a bookmark input, with the header
Overtemperature $temp Cand the temperature wired into thetempplaceholder input
The operator scrubbing that recording later sees the value on the timeline.
The reverse direction works the same way: a Milestone Event (Subscribe) node pinned to one camera's motion event drives flow logic, which writes to SQL, talks Modbus to a PLC, or fires a user defined event back into XProtect for the existing alarm rules to pick up.
Troubleshooting
| Symptom | Cause |
|---|---|
no Conn Key: connect a Milestone Connection node |
The subscribe or action node has nothing wired into Conn Key |
Conn Key "..." is not connected |
The connection node has not authenticated yet, or its credentials are wrong. Check its Last Error output |
| Connection tests fine but no events arrive | The Event Server is stopped. The Test connection result reports this separately |
| Event Gap keeps pulsing | The connection is dropping for longer than about 30 seconds. Check network stability between the camera and the gateway |
| An action reports OK but nothing happens | Milestone returning success means the command was accepted, not that it took effect. A start recording action reports success even when the Recording Server is stopped |
| No user defined events in the picker | None exist on the system. Create them in the Management Client |