Milestone Integration Platform VMS RESTful API (1.0.0)

Introduction

The Milestone XProtect VMS has offered integration options through the MIP SDK plug-in architecture, native .NET components and libraries, and various protocols since 2011.

The Milestone Integration Platform VMS API will include RESTful APIs and other industry standard protocols that expose the functionality currently available through the MIP SDK native .NET libraries and various proprietary protocols.

Currently, the following APIs are available through the API Gateway:

Intended audience

You are assumed to be somewhat familiar with XProtect VMS products, the Milestone Integration Platform (MIP), and specifically the Configuration API.

You are assumed to be somewhat familiar with RESTful APIs, specifically OpenAPI 3.

To learn more about the Milestone Integration Platform, go to Milestone Developer Forum.

A very comprehensive .NET Framework-based example of using the Configuration API is available at https://github.com/milestonesys/mipsdk-samples-component/tree/main/ConfigApiClient.

Support forums and support cases

Milestone XProtect products are supported through the Milestone Support Community, the Milestone Developer Forum, and through a Milestone Technology Partner account.

To submit questions on the support forums, you must have a My Milestone account.

To create support cases, you must be a Milestone Technology Partner.

Overview

The XProtect VMS offers a number of APIs to support integrations. The full functionality is currently available through a plug-in environment, through native .NET libraries, and through various SOAP and native protocols. These APIs are used internally by XProtect VMS, and a large number of integrations have been developed using these APIs. But they are not practical for integrations in a cloud environment:

  • The SOAP-based protocols relies on Windows Communication Framework (WCF) which is part of .NET Framework, making it difficult to implement non-Windows integrations.
  • To use the protocols, your integration must keep track of a number of service endpoints.

The API Gateway simplifies this by providing a single entry point for all services.

API Gateway and IDP

To use the API Gateway, a client first authenticates and requests an access token from the Identity Provider. The client receives a bearer token that grants privileges to access services and to perform operations, as determined by the user's roles.

The client now uses the bearer token in the authorization header in subsequent requests. The client renews the bearer token before it expires by posting a new access token request with the same credentials.

The API Gateway acts as broker, routing requests and responses between the client and the various downstream XProtect VMS services.

User credentials, bearer tokens, and other sensitive data are transmitted in cleartext if you do not set up certificates and use HTTPS.

This release

New in XProtect VMS 2023 R3

  • The API Gateway is no longer optional.
    At least one API Gateway must be present in an XProtect VMS site.
  • WebRTC new features:
    • Optionally, select a specific stream when creating a WebRTC session.
    • Playback (beta). Specify playback time, speed and whether gaps should be skipped when creating a WebRTC session.
    • Multiple STUN and TURN servers can now be specified in the configuration file for the API Gateway, or when creating a WebRTC session.
    • No default STUN server in the API Gateway configuration.
    • Privacy mask prevents new WebRTC connection.
  • Event and State WebSocket API added.
    Use the Event and States WebSocket API to subscribe to events in the VMS. When using this API, events will be pushed to the recipient through the established WebSocket connection.
  • WebSockets Messages API (beta) added.
    Use the WebSockets Messages API to publish and subscribe to JSON messages in real time between Smart Client, Management Client, Event Server and standalone services. Future releases of this API might break backwards compatibility

New in XProtect VMS 2023 R2

  • RESTful Events API (beta) and RESTful Alarms API (beta)
    Use the RESTful Events and Alarms APIs to retrieve stored events and trigger new events, as well as to retrieve alarms, update their priority and state, attach snapshots, and trigger new alarms. While these APIs are in beta, future releases of these APIs might break backwards compatibility.

New in XProtect VMS 2023 R1

  • Some changes to API Gateway configuration files.
  • WebRTC is enabled by default and now supports mDNS.

New in XProtect VMS 2022 R3

  • The API Gateway can be configured to support Cross-Origin Resource Sharing (CORS).
  • Pre-release support for a WebRTC connection through the API Gateway. For more information, refer to sample documentation at WebRTC - JavaScript client.
  • Syntax issues in the OpenAPI spec file have been fixed
  • The OpenAPI spec file more accurately complies with the API.

New in XProtect VMS 2022 R2

  • A number of syntax issues in the OpenAPI spec file have been fixed.
  • More complete coverage of the Configuration API.
  • Breaking change: In some parts of the RESTful API, booleans were treated as strings, meaning that the values when provided as input would have to be enclosed in quotation marks and also would be returned in this form. As this is not in compliance with the JSON standard, and also not in accordance the OpenAPI spec file we provide, we have decided to change it to use true/false without the quotation marks.

New in XProtect VMS 2022 R1

  • The API Gateway is now included in the XProtect VMS Products installer and the Administrative Installation Page.
  • The API Gateway offers a list of registered services at /api/.well-known/uris
  • The API Gateway now uses YARP in place of Ocelot for reverse proxy functionality
  • Logging has been added, using NLog

Limitations

  • Only the following APIs are exposed through the API Gateway:
    • Configuration RESTful API
    • Alarms RESTful API (beta)
    • Events RESTful API (beta)
    • Event and State WebSocket API
    • Messages WebSocket API (beta)
  • To upgrade from the 2021 R2 pre-release of the API Gateway to a later release, you'll have to uninstall the 2021 R2 pre-release first.

To upgrade from the 2021 R2 pre-release of the API Gateway to later releases, you'll have to uninstall the 2021 R2 pre-release before upgrading.

Get started

You are recommended to set up a small separate system for development.

You should consider setting up a server certificate and using HTTPS. While the IDP, the API Gateway, and the management server all can work with either HTTP or HTTPS, production systems should be set up with server certificates.

User credentials, bearer tokens, and other sensitive data are transmitted in cleartext if you do not set up certificates and use HTTPS.

The following instructions assume that you will set up a server certificate and use HTTPS. If you choose to not create and use a server certificate, replace https with http in the following installation instructions, and skip steps related to managing certificates.

Requirements

To set up a development system with the XProtect API Gateway, you'll need:

  • XProtect VMS Products 2022 R1 or later
  • An XProtect VMS license file

To deploy the system with certificates, you'll need:

  • The fully qualified domain name of the development system
  • A server certificate for the development system

If you have previously installed the 2021 R2 pre-release of the API Gateway, you'll have to uninstall the pre-release before proceeding.

Please refer to Milestone product system requirements for more information about system requirements.

TL;DR

This is a brief walkthrough of the installation of a simple development system with all system components on the same host.

For more information, go to Getting started with XProtect VMS.

If you have already set up a system with XProtect VMS 2022 R1 or later, you can skip to Verify that the API Gateway is operational. Please note that you need an XProtect Basic user account with the Administrators role to run the verification scripts.

You can find more information about the steps in Notes and tips.

Create a server certificate

  1. Create and install a server certificate, for example by following the instructions in XProtect VMS certificates guide.

    • When prompted for DNS names, include the fully qualified domain name for the server.

Install XProtect VMS

  1. Download the XProtect VMS products installer from the software download page.

  2. Install XProtect VMS:

    • When you get to the Select license file page, download and select a free XProtect Essential+ license file, unless you have requested a free trial license, or have created a test license as a Milestone Technology Partner.
    • When you get to the Select an installation type page, select Single computer.
    • When you get to the Select encryption page, enable Server certificate and select the VMS SSL Certificate you just created and installed in step 1.
    • When you get to the Add users page, add a Basic user with the Administrators role, for example user seamrune with password Rad23Swops#.

Verify that the API Gateway is operational

  1. Verify that you can get a list of well-known URIs from the API Gateway:

    cURL

    curl --insecure --request GET "https://test-01.example.com/api/.well-known/uris"
    

    PowerShell

    $response = Invoke-RestMethod 'https://test-01.example.com/api/.well-known/uris' -Method 'GET'
    $response | ConvertTo-Json
    

    Response body

{
  "ProductVersion": "22.1.5804.1",
  "UnsecureManagementServer": "http://test-01.example.com/",
  "SecureManagementServer": "https://test-01.example.com/",
  "IdentityProvider": "https://test-01.example.com/IDP",
  "ApiGateways": [
      "https://test-01.example.com/API/"
  ]
}  

In case you had installed an API Gateway on another host, you could use the hostname of that host.

  1. Verify that you can authenticate and retrieve a bearer token from the built-in IDP.

    Replace the hostname test-01.example.com, username seamrune, and password Rad23Swops# in the following code samples. In Windows Command Prompt (CMD), replace the line continuation character \ with ^.

    cURL

    curl --insecure --request POST "https://test-01.example.com/idp/connect/token" \
    --header "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "grant_type=password" \
    --data-urlencode "username=seamrune" \
    --data-urlencode "password=Rad23Swops#" \
    --data-urlencode "client_id=GrantValidatorClient"
    

    PowerShell

    $headers = @{ "Content-Type" = "application/x-www-form-urlencoded" }
    $body = @{grant_type='password'
        username='seamrune'
        password='Rad23Swops#'
        client_id='GrantValidatorClient'}
    $response = Invoke-RestMethod 'https://test-01.example.com/idp/connect/token' -Method 'POST' -Headers $headers -Body $body
    $response | ConvertTo-Json
    

    Response body

    {
     "access_token": "eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L . . . ay0ferTwm-DZ4OxNXGTHk5t7R_YTWPjg",
     "expires_in": 3600,
     "token_type": "Bearer",
     "scope": "managementserver"
    }
    

    Copy the access_token value from the response body; you will use the value as the bearer token value in the following request.

  2. Verify that you can submit a request through the API Gateway.

    Replace the hostname test-01.example.com and the bearer token value eyJhbG . . . YTWPjg in the following code samples. In Windows Command Prompt (CMD), replace the line continuation character \ with ^.

    cURL

    curl --insecure --request GET "https://test-01.example.com/api/rest/v1/sites" \
    --header "Authorization: Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L . . . ay0ferTwm-DZ4OxNXGTHk5t7R_YTWPjg"
    

    PowerShell

    $headers = @{ "Authorization" = "Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L . . . ay0ferTwm-DZ4OxNXGTHk5t7R_YTWPjg" }
    $response = Invoke-RestMethod 'https://test-01.example.com/api/rest/v1/sites' -Method 'GET' -Headers $headers
    $response | ConvertTo-Json
    

    Response body

    {
      "array": [
        {
          "displayName": "TEST-01",
          "id": "2d12465c-3485-4ca8-a9fb-86a79de1a82f",
          "name": "TEST-01",
          "description": "",
          "lastModified": "2021-11-11T11:11:11.1111111Z",
          "timeZone": "Central Europe Time",
          "computerName": "TEST-01",
          "domainName": "example.com",
          "lastStatusHandshake": "2021-11-11T11:11:11.1111111Z",
          "physicalMemory": 0,
          "platform": "[Not Available]",
          "processors": 0,
          "serviceAccount": "S-1-5-20",
          "synchronizationStatus": 0,
          "masterSiteAddress": "",
          "version": "22.1.0.1",
          "relations": {
            "self": {
              "type": "sites",
              "id": "2d12465c-3485-4ca8-a9fb-86a79de1a82f"
            }
          }
        }
      ]
    }
    

Notes and tips

XProtect VMS license

Most of the Configuration API is supported with the free XProtect Essential+ license. To determine which XProtect VMS product license you need, please visit Milestone product index.

You can get a license in several ways:

Creating an XProtect Basic user

You can use the XProtect Management Client to create XProtect Basic and Windows users after installation.

For more information, go to XProtect VMS administrator manual/Create basic user.

Setting up Postman to handle certificates

Postman does not use the certificate store on your platform. To work with secure services, you have two options:

  • Disable certificate verification in Postman
  • Add the CA certificate used to sign the VMS server certificate

For more information, see Encryption, SSL/TLS, and Managing Your Certificates in Postman.

Disable certificate verification in Postman
  1. Open Postman, then select File > Settings
  2. In the Settings dialog, select the General tab.
  3. Move the slider for SSL certificate verification to the OFF position.

With certificate verification disabled, Postman makes no attempt to verify the connection.

Add the CA certificate used to sign the VMS server certificate

For Postman, the CA certificate needs to be in PEM format. A PEM file is a collection of Base-64 encoded certificates contained within a single file. As long as the CA certificate is exported in Base-64 encoded format, Postman will accept a .cer file.

The following instructions assumes that you have set up your own CA certificate as described in XProtect VMS certificates guide, and that you have the CA certificate installed on a Windows platform. Adjust as necessary for other CA certificates and platforms.

  1. Start the Local Computer certificates manager, for example by running certlm.msc.
  2. Select Trusted Root Certification Authorities > Certificates
  3. Select the VMS Certificate Authority, then right-click and select All Tasks > Export....
  4. Within the Certificate Export Wizard dialog:
    1. Select Next on the Welcome screen.
    2. Select Base-64 encoded X.509 (.CER) on the Export File Format screen, and select Next.
    3. Enter a path and filename to save the certificate on the File To Export screen, and select Next.
    4. Select Finish to complete the wizard and save the certificate.
  5. Copy the exported certificate file to the machine you are running Postman on.
  6. Open Postman, then select File > Settings.
  7. In the Settings dialog, select the Certificates tab.
  8. Within the CA Certificates section, move the slider to the ON position, click Select File, then select the Base-64 encoded CA certificate file exported earlier.

Download OpenAPI specification

Download the OpenAPI specification for the Configuration API from https://doc.developer.milestonesys.com/mipvmsapi/api/config-rest/v1/openapi.yaml.

Samples

Simple code samples are available at Milestone System's GitHub page.

Using RESTful APIs

Using WebSocket APIs

Using WebRTC

Configuration

API Gateway configuration files are located in the installation location, by default %ProgramFiles%\Milestone\XProtect API Gateway\.

These configuration files are relevant for the API Gateway:

  • appsettings.json: Reverse proxy (routing), CORS, WebRTC, log levels, etc.
  • appsettings.Production.json: Overrides the configuration settings in appsettings.json.
  • nlog.config: Log layout, log targets, etc.

Editing configuration files

Use a validating editor to edit configuration files. Most popular code editors support JSON and XML syntax validation, either by default or through extensions.

appsettings.json and appsettings.Production.json

Do not edit the appsettings.json file manually. The configuration is created by the XProtect product installer and maintained by the Server Configurator.

If you need to override a configuration setting in appsettings.json, create appsettings.Production.json and add configuration overrides here. appsettings.Production.json will not be removed or changed by product updates.

To override configuration settings in appsettings.json, copy the complete top level property from appsettings.json to appsettings.Production.json and remove the nested properties that you don't want to change.

For example, to change the management server host address but no other ReverseProxy settings, include this in appsettings.Production.json:

{
  "ReverseProxy": {
    "Clusters": {
      "managementserver": {
        "Destinations": {
          "hostname": {
            "Address": "https://test-02.example.com/"
          }
        }
      }
    }
  }
}

If you add several properties to appsettings.Production.json, remember to include a comma between the properties, but no trailing comma:

{
  "Logging": {
    "LogLevel": {
      "Yarp": "Information"
    }
  },
  "ReverseProxy": {
    "Clusters": {
      "managementserver": {
        "Destinations": {
          "hostname": {
            "Address": "https://test-02.example.com/"
          }
        }
      }
    }
  }
}

Reverse proxy

The reverse proxy functionality of the API Gateway is implemented using YARP.

The ReverseProxy section in appsettings.json is related to the reverse proxy functionality. The configuration is created by the product installer and maintained by the Server Configurator.

  "ReverseProxy": {
    "Routes": {
      "well-known": {
        "ClusterId": "managementserver",
        "Match": {
          "Path": "/.well-known/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/ManagementServer/.well-known/{**remainder}"
          }
        ]
      },
      "rest-api": {
        "ClusterId": "managementserver",
        "Match": {
          "Path": "/rest/v1/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/ManagementServer/Rest/{**remainder}"
          }
        ]
      },
      "alarm-definitions-rest-api": {
        "ClusterId": "managementserver",
        "Match": {
          "Path": "/rest/v1/alarmDefinitions/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/ManagementServer/Rest/alarmDefinitions/{**remainder}"
          }
        ]
      },
      "events-rest-api": {
        "ClusterId": "eventserver",
        "Match": {
          "Path": "/rest/v1/events/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/rest/events/v1/events/{**remainder}"
          }
        ]
      },
      "alarms-rest-api": {
        "ClusterId": "eventserver",
        "Match": {
          "Path": "/rest/v1/{resource:regex(^alarm.*)}/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/rest/alarms/v1/{resource}/{**remainder}"
          }
        ]
      },
      "ws-messages": {
        "ClusterId": "eventserver",
        "Match": {
          "Path": "/ws/messages/v1/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/ws/messages/v1/{**remainder}"
          }
        ]
      },
      "ws-events": {
        "ClusterId": "eventserver",
        "Match": {
          "Path": "/ws/events/v1/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/ws/events/v1/{**remainder}"
          }
        ]
      },
      "idp": {
        "ClusterId": "managementserver",
        "Match": {
          "Path": "/IDP/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/IDP/{**remainder}"
          }
        ]
      },
      "share": {
        "ClusterId": "managementserver",
        "Match": {
          "Path": "/share/{**remainder}"
        },
        "Transforms": [
          {
            "PathPattern": "/share/{**remainder}"
          },
          {
            "X-Forwarded": "Append",
            "Prefix": "Off"
          },
          {
            "RequestHeader": "X-Forwarded-Prefix",
            "Append": "/api/share"
          }
        ]
      }
    },
    "Clusters": {
      "managementserver": {
        "Destinations": {
          "hostname": {
            "Address": "https://test-02.example.com/"
          }
        }
      }
    }
  }

For more information about YARP, please refer to YARP: Yet Another Reverse Proxy.

Cross-Origin Resource Sharing (CORS)

The API Gateway can be configured to support Cross-Origin Resource Sharing (CORS). The following response headers are supported:

CORS is disabled by default. You enable and configure CORS support by creating and editing appsettings.Production.json.

  1. Create appsettings.Production.json (if not already created).

  2. Enable and configure CORS response headers similar to this:

      {
        "CORS": {
          "Enabled": true,
          "Access-Control-Allow-Origin": "yourdomain1.com,yourdomain2.com",
          "Access-Control-Allow-Headers": "Content-Type",
          "Access-Control-Allow-Methods": "*"
        }
      }
    
  3. Restart the IIS, or at least recycle VideoOS ApiGateway AppPool.

Only required response headers should be defined. Each response header can have multiple values, provided as a list of comma-separated values.

In a production system, always specify the Access-Control-Allow-Origin value with explicit origins. Never use wildcard (*) or null in your origin as this can put the security of your system at risk.

For development and test purposes, you can use a very permissive policy:

  {
    "CORS": {
      "Enabled": true,
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "*",
      "Access-Control-Allow-Methods": "*"
    }
  }

This will allow calls from any origin, including a local file system, to the API Gateway.

For more information about CORS, please refer to Cross-Origin Resource Sharing (CORS)

WebRTC

WebRTC is a peer-to-peer protocol for streaming data, for example video.

STUN and TURN server addresses

To help establish a connection through NATs, WebRTC uses STUN (Session Traversal Utilities for NAT) and/or TURN (Traversal Using Relays around NAT) servers.

A STUN server is used to discover the public IP address and port number of a device behind a NAT.

A TURN server is used to relay traffic between peers when a direct connection is not possible due to firewall or NAT restrictions. TURN servers can also act as STUN servers.

No default STUN or TURN server URLs are configured API Gateway-side.

To specify STUN and/or TURN servers:

  1. Create appsettings.Production.json (if not already created).

  2. Add a WebRTC object and add STUN and TURN server URLs, for example:

    {
      "WebRTC": {
        "iceServers": [ 
          { "url": "stun:mystun.zyx:3478"}, 
          { "url": "turn:myturn.zyx:5349"} 
        ] 
      }
    }
    
  3. Restart the IIS, or at least recycle VideoOS ApiGateway AppPool.

For more information about WebRTC, please refer to WebRTC API and the WebRTC sample documentation at ProtocolSamples/WebRTC_JavaScript

Logging

The API Gateway uses NLog for logging.

Logging is configured in two places:

  • appsettings.json and appsettings.Production.json: Log levels
  • nlog.config: Log layout, target, etc.

Log levels

This part of appsettings.json is related to logging:

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "Yarp": "Warning"
    }

To include YARP routing log messages, add a log level setting in appsettings.production.json for Yarp, for example Information:

  1. Create appsettings.Production.json (if not already created).

  2. Add the configuration that you want to override, for example:

    {
      "Logging": {
        "LogLevel": {
          "Yarp": "Information"
        }
      }
    }
    
  3. Restart the IIS, or at least recycle VideoOS ApiGateway AppPool.

Log layout, log targets, etc

This is the default NLog configuration file:

<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  autoReload="true"
  internalLogLevel="Warn"
  internalLogFile="internal-nlog.txt">
  <variable
    name="logDirectory"
     value="C:\ProgramData\Milestone\ApiGateway\Logs" />
  <variable
    name="archiveDirectory"
   value="${var:logDirectory}\Archive" />
  <variable
    name="defaultLayout" 
    value="${date:format=yyyy-MM-dd HH\:mm\:ss.fffzzz} [${threadid:padding=6}] ${level:uppercase=true:padding=-10} - ${message} ${exception:format=tostring}" />
  <targets>
    <target
      name="logfile"
      xsi:type="File"
      fileName="${var:logDirectory}\gateway.log"
      archiveFileName="${var:archiveDirectory}\gateway-{####}.log"
      archiveNumbering="Rolling"
      maxArchiveFiles="20"
      archiveEvery="Day"
      archiveAboveSize="1000000"
      archiveOldFileOnStartup="true"
      createDirs="true"
      layout="${var:defaultLayout}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Debug" writeTo="logfile" />
  </rules>
</nlog>

For more information about NLog configuration, please refer to NLog Configuration options.

Authentication and authorization

For authentication and authorization, the API Gateway can use

  • XProtect Basic user authentication, available through OpenID Connect and OAuth 2.0 Identity Provider (IDP) endpoints
  • XProtect Windows user authentication, available through a Milestone .NET Framework library

Authorization is based on OAuth2 bearer tokens.

An internal IDP endpoint is provided with the XProtect VMS management server. Either the internal IDP or an external IDP can be used.

For more information about using external IDPs with XProtect VMS, please refer to XProtect VMS administrator manual/Authentication/External IDP (explained).

XProtect Basic user authentication through the IDP is not based on HTTP Basic authentication

API usage

Notation

Root entry points

The API Gateway exposes a list of relevant server and API Gateway URIs at this URI:

  • /api/.well-known/uris

RESTful APIs are exposed at this root entry point:

  • /api/rest/v1

WebSocket APIs are exposed at these root entry points:

  • /api/ws/events/v1
  • /api/ws/messages/v1

A complete request URI includes scheme, hostname, root entry point, endpoint route, and optionally query parameters, for example:

https://test-01.example.com/api/rest/v1/recordingservers/b1c84b2c-47a9-48aa-b7d5-ee43167b30da?resources

In this document, the https://test-01.example.com/api/rest/v1 part is omitted from request URIs. Only endpoint and query parameters are included:

/recordingservers/b1c84b2c-47a9-48aa-b7d5-ee43167b30da?resources

Syntax examples

A complete dump of a simple request and response might look like this:

GET /api/rest/v1/sites HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjBhYWI3ZGU2YzExN . . . MRfqBFqhvkoOMndXAkQnpPX5NdXQiS5Q
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Cache-Control: no-cache
Postman-Token: bdb5ef08-659c-45df-8a66-98f94d0e286d
Host: test-01.example.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 656
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
X-Powered-By: ASP.NET
Date: Wed, 23 Feb 2022 09:28:58 GMT
 
{ "array" : [ { "displayName" : "TEST-01", "id" : "c4de19a0-d148-4858-8f55-2a3c4875638d", "name" : "TEST-01", "description" : "", "lastModified" : "2022-02-23T09:11:02.9100000Z", "timeZone" : "FLE Standard Time", "computerName" : "TEST-01", "domainName" : "example.com", "lastStatusHandshake" : "2022-02-23T09:11:02.9100000Z", "physicalMemory" : 0, "platform" : "[Not Available]", "processors" : 0, "serviceAccount" : "S-1-5-20", "synchronizationStatus" : 0, "masterSiteAddress" : "", "version" : "22.1.0.1", "relations" : { "self" : { "type" : "sites", "id" : "c4de19a0-d148-4858-8f55-2a3c4875638d" } } } ] }

The syntax examples in this document includes only the most relevant data:

  • The request includes only the request line, and the request body in case of most POST, PUT, and PATCH requests.

    GET /api/rest/v1/sites HTTP/1.1
    
  • The response includes the HTTP status code if relevant, and the response body might be abbreviated:

    HTTP/1.1 200 OK
    
    {
        "array": [
            {
                "displayName": "TEST-01",
                "id": "c4de19a0-d148-4858-8f55-2a3c4875638d",
                "name": "TEST-01",
                // more properties
                "relations": {
                    "self": {
                        "type": "sites",
                        "id": "c4de19a0-d148-4858-8f55-2a3c4875638d"
                    }
                }
            }
        ]
    }
    

References

Design considerations

The RESTful API is designed following these guidelines:

  • Objects are identified by resource URIs.
  • The object model content is represented in request and response body content, never by URI parameters.
  • The response body contains IDs of the requested and related resources.
  • The response body object contains wrappers for each part of the response, e.g. data, array, result, error, both data and resources, both data and definitions, both error and params, etc.
  • Only nouns in resource URIs, no verbs.
  • Plural resource nouns identify collection objects, and IDs identify single resouces within collections.
  • We use lowerCamelCase for objects and property names.

Object model and URIs

Any VMS item that can be read and/or updated independently is considered an object, and each VMS item has a specific URI that identifies it.

For objects within objects, the resource URI contains the object type and ID of its parent. Also, each object contains a relations element with relevant links to itself, parent, or related objects.

Object model

The top level object name is data for the requested data, or array if the requested data is an array of data.

For example, the collection of hardware objects is represented as an array:

GET /hardware
{
    "array": [
        {
            "displayName": "AXIS P5522 PTZ Dome Network Camera (10.100.50.129)",
            "enabled": "True",
            "id": "149d6f4d-4f71-4ced-98b4-8b1e914578db",
            "name": "AXIS P5522 PTZ Dome Network Camera (10.100.50.129)",
            "description": "",
            "address": "http://10.100.50.129/",
            "userName": "root",
            "model": "AXIS P5522 PTZ Dome Network Camera",
            "lastModified": "2022-01-19T07:58:28.3170000Z",
            "hardwareDriverPath": {
                "type": "hardwareDrivers",
                "id": "316f4995-decd-4fa9-9877-0833b369c053"
            },
            "relations": {
                "parent": {
                    "type": "recordingServers",
                    "id": "b1c84b2c-47a9-48aa-b7d5-ee43167b30da"
                },
                "self": {
                    "type": "hardware",
                    "id": "149d6f4d-4f71-4ced-98b4-8b1e914578db"
                }
            }
        },
        {
            "displayName": "AXIS M1144-L Network Camera (10.100.50.187)",
            "enabled": "True",
            "id": "4d7a1e6a-b538-482f-9ce0-e44048cb5955",
            "name": "AXIS M1144-L Network Camera (10.100.50.187)",
            "description": "",
            "address": "http://10.100.50.187/",
            "userName": "root",
            "model": "AXIS M1144-L Network Camera",
            "lastModified": "2022-01-19T07:58:29.6130000Z",
            "hardwareDriverPath": {
                "type": "hardwareDrivers",
                "id": "316f4995-decd-4fa9-9877-0833b369c053"
            },
            "relations": {
                "parent": {
                    "type": "recordingServers",
                    "id": "b1c84b2c-47a9-48aa-b7d5-ee43167b30da"
                },
                "self": {
                    "type": "hardware",
                    "id": "4d7a1e6a-b538-482f-9ce0-e44048cb5955"
                }
            }
        },
        // more hardware objects related to this recording server
    ]
}

A single object is addressed by its type and ID:

GET /hardware/149d6f4d-4f71-4ced-98b4-8b1e914578db
{
    "data": {
        "displayName": "AXIS P5522 PTZ Dome Network Camera (10.100.50.129)",
        "enabled": "True",
        "id": "149d6f4d-4f71-4ced-98b4-8b1e914578db",
        "name": "AXIS P5522 PTZ Dome Network Camera (10.100.50.129)",
        "description": "",
        "address": "http://10.100.50.129/",
        "userName": "root",
        "model": "AXIS P5522 PTZ Dome Network Camera",
        "lastModified": "2022-01-19T07:58:28.3170000Z",
        "hardwareDriverPath": {
            "type": "hardwareDrivers",
            "id": "316f4995-decd-4fa9-9877-0833b369c053"
        },
        "relations": {
            "parent": {
                "type": "recordingServers",
                "id": "b1c84b2c-47a9-48aa-b7d5-ee43167b30da"
            },
            "self": {
                "type": "hardware",
                "id": "149d6f4d-4f71-4ced-98b4-8b1e914578db"
            }
        }
    }
}

Resource URIs

The object that represents the configuration of the management server itself has this URI:

/sites

Almost any other object will have a format like these:

/recordingServers/{id}
/hardware/{id}
/cameras/{id}

For objects that are parented by another object, the resource URI grows to:

/recordingServers/{id}/hardwareDrivers/{id2}
/cameras/{id}/ptzPresets/{id2}

There are never more than two levels in resource URIs. A resource with only one instance will re-use the ID of its parent. For example, there is only one streams collection for each camera, and the camera ID is re-used for the streams related to the camera:

GET /streams/{camera-id}

See also Operations on objects

Request query parameters

The following query parameters can be added to a request URI:

  • disabled : include disabled objects
  • resources : get a list of child resources to an object
  • task: specify a task to be invoked, like this: ?task={someTaskId}
  • tasks: get a list of valid tasks for an object
  • noData : suppress data in the response
  • definitions: get definition of object (including task) parameters
  • language : get all translations for a given language

The language parameter is only relevant for the translations resource. The other parameters can be combined.

disabled parameter

By default, only enabled objects will be included in the response.

To include all disabled objects in the response, include the query parameter disabled, like this:

GET /cameras?disabled

resources parameter

To find out which resource types are available for a specific object, include the query parameter resources, like this:

GET /recordingServers/{id}?resources

The response body will contain an array of all the child resource types available for the requested resource:

{
    "data": {
        // properties for this recording server object
    },
    "resources": [
        {
            "type": "hardware",
            "displayName": "Hardware"
        },
        {
            "type": "hardwareDrivers",
            "displayName": "Drivers"
        },
        {
            "type": "storages",
            "displayName": "Storages"
        },
        {
            "type": "recordingServerMulticasts",
            "displayName": "Multicasts"
        },
        {
            "type": "recordingServerFailovers",
            "displayName": "Failover"
        }
    ]
}

To get an array of child objects, append the resource type value to the specific parent resource route, like this:

GET /recordingServers/{id}/storages

For objects that do not have any child resources, the response will contain an empty array:

{
    "resources": []
}

tasks parameter

To get an array of tasks available for a given resource, use the query parameter tasks, like this:

GET /hardware/{id}?tasks
{
    "data": {
        // properties for this hardware object
    },
    "tasks": [
        {
            "id": "ReadPasswordHardware",
            "displayName": "Read hardware password"
        },
        {
            "id": "ChangePasswordHardware",
            "displayName": "Change hardware password"
        },
        {
            "id": "UpdateFirmwareHardware",
            "displayName": "Update firmware"
        },
        {
            "id": "MoveHardware",
            "displayName": "Move hardware"
        },
        {
            "id": "UpdateHardware",
            "displayName": "Update hardware"
        }
    ]
}

The task id can then be used to invoke a task.

See also task parameter and Tasks

task parameter

To invoke a task on a resource, specify the task as the value of the query parameter task in a POST request, like this:

POST /hardware/{id}?task=MoveHardware

Provide parameters to the request in the request body. If the body does not contain the required parameters, the response will contain an error object and a params object listing the required parameters:

{
    "error": {
        "httpCode": 400,
        "details": [
            {
                "errorText": "Bad request: parameters missing"
            }
        ]
    },
    "params": {
        "destinationRecordingServer": ""
    }
}

To understand the parameters in detail, add the query parameter definitions to either a GET or POST query like this:

POST /hardware/{id}?task=MoveHardware&definitions

The response will include a list of definitions for each of the parameters, like this:

{
    "error": {
        "httpCode": 400,
        "details": [
            {
                "errorText": "Bad request: parameters missing"
            }
        ]
    },
    "params": {
        "destinationRecordingServer": ""
    },
    "definitions": {
        "displayName": {
            "canSet": "false",
            "translationId": "PropertyDisplayName"
        },
        "destinationRecordingServer": {
            "canSet": "true",
            "options": [
                {
                    "value": "recordingServers/c9cef804-e600-4b4b-b5f9-be246bb49133",
                    "displayName": "My recording server"
                },
                {
                    "value": "recordingServers/b1c84b2c-47a9-48aa-b7d5-ee43167b30da",
                    "displayName": "My other recording server"
                }
            ],
            "valueType": "enum",
            "translationId": "PropertyHardwareDestinationRecorder",
            "toolTipTranslationId": "PropertyHardwareDestinationRecorderToolTip"
        }
    }
}

Add the required parameter value to the request body, and submit the request again:

POST /hardware/{id}?task=MoveHardware

{
    "destinationRecordingServer": "recordingServers/c9cef804-e600-4b4b-b5f9-be246bb49133"
}

See also Task invocation

noData parameter

Add the query parameter noData to suppress data content in the response. Can be used when other query parameters are present, e.g. resources or tasks.

language parameter

The translations collection represents the translation of display names for parameters. Add the language query parameter to specify the language:

GET /translations?language=tr-TR

The response body contains an array of translated display names for the specified language:

{
    "array": [
        {
            "id": "PropertyLicenseActivationAutomatic",
            "text": "Enable automatic license activation"
        },
        {
            "id": "PropertyCameraGroupPaths",
            "text": "Camera group paths"
        },
        // and 6000 more entries here
    ]
}

Note: Translations are not yet supported, and it will return English for now.

definitions parameter

Add the query parameter definitions to request the definition for each property of an object. Most of the properties use enumerations or numbers within a defined range.

The following example is from the hardwareDriverSettings resource on an Axis hardware:

GET /hardwareDriverSettings/3954fd12-a071-4464-89d3-d8147ff8a4c5?definitions
{
    "data": {
        "displayName": "Settings",
        "HardwareDriverSettings": {
            "displayName": "General",
            "detectedModelName": "AXIS Q1647 Network Camera",
            // ...
            "bandwidth": "Unlimited",
            // ...
            "brightness": "50",
            // ...
            "whiteBalance": "Fixed indoor",
            // ...
            "auxUse": "Wiper",
            // ...
        }
    },
    "definitions": {
        "HardwareDriverSettings": {
            "detectedModelName": {
                "canSet": "false",
                "translationId": "a57d4e50-4158-4d04-955a-3141653e44dc"
            },
            // ...
            "bandwidth": {
                "canSet": "true",
                "valueType": "enum",
                "options": {
                    "Unlimited": "Unlimited",
                    "4 Mbit": "4 Mbit",
                    "2 Mbit": "2 Mbit",
                    "1 Mbit": "1 Mbit",
                    "768 Kbit": "768 Kbit",
                    "512 Kbit": "512 Kbit",
                    "256 Kbit": "256 Kbit",
                    "128 Kbit": "128 Kbit",
                    "64 Kbit": "64 Kbit"
                },
                "translationId": "3379b746-444c-4fdc-8447-8e7215cdb1e7"
            },
            "audioEncoding": {
                "canSet": "true",
                "valueType": "enum",
                "options": {
                    "G711": "G.711",
                    "G726-32": "G.726 32 kbit/s",
                    "G726-24": "G.726 24 kbit/s",
                    "AAC": "AAC"
                },
                "translationId": "1d0b927a-ac2d-4fba-98bc-fcc05c2dbd4a"
            },
            // ...
            "brightness": {
                "canSet": "true",
                "valueType": "slider",
                "MinValue": "0",
                "MaxValue": "100",
                "StepValue": "1",
                "translationId": "96cbdf37-4ffc-46d8-89d0-d24ece0b4fb7"
            },
            // ...
            "auxUse": {
                "canSet": "true",
                "valueType": "enum",
                "options": {
                    "PTZ": "PTZ Movement",
                    "Wiper": "Wiper/Washer Control"
                },
                "translationId": "b3ebed61-8e59-45f5-963d-1f271c1e5a0d"
            },
            // ...
        }
    }
}

In this example, the property auxUse has a current value of Wiper. In the definitions part, the auxUse property is defined to be an enumeration with two values: PTZ or Wiper.

Each property is defined in terms of:

  • canSet – boolean, true when this property can be changed
  • valueTypeenum, int, double, slider, bool, string, dateTime, date, time, path, pathList, progress, list, array
  • options – used for enums to list the set of values
  • translationId – id for display name in the translation array
  • minValue – lowest allowed value for an int, double or slider
  • maxValue – highest allowed value for an int, double or slider
  • stepValue – minimum interval on a slider, e.g. 5 would mean that 0, 5, 10, 15 etc are valid

Filters and pagination

Filters

You can add match filters to a resource URI to limit the amount of data returned.

For example, to return only hardware of specific model, include a filter like this:

GET /hardware?model='AXIS Q1725'

When no filter operator is included, the property value must match exactly.

To exclude specific objects, use the notEquals operator, like this:

GET /hardware?model=notEquals:'AXIS Q1725'

To evaluate numerical and date or time property values, use relational filter operators, like this:

GET /hardware?lastModified=gt:'2021-11-25'

To match part of a string property value, use match filter operators, like this:

GET /hardware?model=contains:'axis'

Available filter operators:

  • lt less than
  • gt greater than
  • notEquals not equals
  • startsWith string starts with
  • contains string that contains

Pagination

To limit the amount of data being returned, add these query parameters to the resource URI:

  • page=<number>
  • size=<number>

Pagination is available for collection resource URIs. For example, to get the first 10 hardware objects:

GET /hardware?page=0&size=10

Operations on objects

For basic configuration objects like hardware and cameras, the HTTP methods GET, PUT, DELETE, PATCH, and POST are used to manage these objects. Use of the POST may not be possible for some classic VMS objects, as they are created on the server side during discovery or registration.

For some objects, an entire set of objects are configured in one request – e.g. the GET will return an array of objects, and the PUT will need to provide a similar set of objects, e.g. when configuring usage of streams. In these cases, the JSON body will contain an array of elements.

For those resources where just one instance exists, and where there is no specific ID, the ID of the parent is re-used.

Here's a few examples related to cameras. A camera is identified as /cameras/{camera-id}, and these camera child resources re-use the parent ID:

  • /streams/{camera-id}
  • /motionDetections/{camera-id}
  • /settings/{camera-id}

These collection objects always exist, the DELETE HTTP request is not supported, and POST is not supported for motionDetections and settings.

As a streams object is actually an array of streams, these must be updated together. The POST method is supported for adding/removing a single stream definition with task=AddStream and task=RemoveStream, but the GET, PATCH, and PUT methods operate on the entire array of stream definitions in /streams/{camera-id}

By contrast, multiple instances of these camera objects can exist:

  • /cameras/{camera-id}/patrollingProfiles/{profile-id}
  • /cameras/{camera-id}/ptzPresets/{preset-id}

The POST and DELETE methods are supported on the respective resource IDs.

Creating an object

To create a new object, POST the required object properties to the appropriate collection URI, like this:

POST /analyticsEvents

{
  "name": "TodaysEvent"
}

If the request is succesful, the analyticsEvent is created server side, and the response is a 201 OK. The response body contains the ID of the new object:

HTTP/1.1 201 Created

{
    "result": {
        "id": "BCF7FE2B-D124-4639-8390-55E90B1C8B6F",
        "name": "TodaysEvent",
        "lastModified": "2021-11-30T08:42:57.6241547Z",
        "state": "Success",
        "path": {
            "type": "analyticsEvent",
            "id": "bcf7fe2b-d124-4639-8390-55e90b1c8b6f"
        }
    }
}

Note that the response body contains a result object rather than a data or array object.

Retrieving object representations

To retrieve a single hardware configuration:

GET /hardware/{id}

To retrieve all hardware on a recording server:

GET /recordingServers/{id}/hardware

To retrieve up to 100 of all enabled cameras, using paging:

GET /cameras?page=0&size=100

To retrieve up to 100 of all enabled and disabled cameras, using paging:

GET /cameras?page=0&size=100&disabled

Updating entire objects

To update all updatable properties of an object, submit a PUT request including (at least) all updatable properties in the request body:

PUT /hardware/{id}

{
    // all updateable properties
}

Updating parts of an object

To update some updatable properties of an existing object, submit a PATCH request, including just the properties to update in the request body:

PATCH /hardware/{id}

{
  "name": "TheNewHardwareName"
}

Deleting an object

To delete an object, submit a DELETE request with no request body:

DELETE /analyticsEvents/{id}

Note: Some objects cannot be deleted

Tasks

Tasks are used in two general areas:

  • For managing details on configuration objects
  • For managing non-configuration objects

Task invocation

When retrieving available tasks for a recordingServers object, the response looks like this:

GET /recordingServers/{id}?tasks
{
    "data": {
        // properties for this recording server
    },
    "tasks": [
        {
            "id": "AddHardware",
            "displayName": "Add new hardware"
        },
        {
            "id": "GetOtherWithMediaOnRecorder",
            "displayName": "Get devices with media on recording server"
        },
        {
            "id": "HardwareScan",
            "displayName": "Detect hardware driver"
        },
        {
            "id": "HardwareScanExpress",
            "displayName": "Detect hardware"
        }
    ]
}

The response above contains an array of tasks available for the object, here the recording server.

To create a task, the task id is added as a query parameter to the object URI, like this:

POST /recordingServers/{id}?task=HardwareScan

Parameters are supplied in the body of the request.

If no parameters are given, an error response will contain the minimal JSON content needed. For complex wizard-like editing / validation / creation of e.g. rules and alarmDefinitions, there will be a flow of JSON content going back and forth, until the entire content can be accepted.

A typical flow will look like this:

  1. POST /recordingServers/{id}?task=HardwareScan
  2. Response contains the missing parameters (name, description, password)
  3. POST /recordingServers/{id}?task=HardwareScan with body of 3 parameters
  4. Response with task id
  5. Loop getting status for /tasks/{id}
  6. When successful, GET the hardware and update and enable it

This is to support that it may be difficult to know what parameters are used for a given task, and it will also provide a way to be forward compatible when new parameters are needed.

Use POST HTTP method for all task invocations.

If the client only submitted this request:

POST /recordingServers/{id}?task=HardwareScan

The response will be a list of the properties to be filled:

{
  "params" : {
      "recordingServerPath" : "recordingServers/<guid>",
      "hardwareAddress" : "",
      "userName" : "",
      "password" : "",
      "hardwareDriverPath" : "hardwareDrivers/<guid>"
  },
}

For some tasks, the response will contain relevant default values or newly added properties.

The client can then fill in the property values and re-submit the request.

The response to invoking a task will be a HTTP response of 200 Success, with a JSON body containing a task. When new object created: objectId is something like hardware/{id} (for the newly added hardware).

Task progress and cleanup

For server-side processing that takes some time to process, a task request can queue the request and return a task identifier.

For example: when using the AddHardware task, it could look like:

POST /recordingServers/{id}?task=AddHardware

{
    "hardwareAddress": "10.10.16.90",
    "hardwareDriverPath": {
        "type": "hardwareDrivers",
        "id": "55f88254-dc3d-4735-acc6-73f21cca2402"
    },
    "userName": "root",
    "password": "pass",
    "customData": ""
}

If the task is succesfully created, the HTTP response code is 201 Created:

HTTP/1.1 201 Created

{
    "result": {
        "hardwareAddress": "10.10.16.90",
        "hardwareDriverPath": {
            "type": "hardwareDrivers",
            "id": "55f88254-dc3d-4735-acc6-73f21cca2402"
        },
        "userName": "root",
        "password": "pass",
        "customData": "",
        "state": "Idle",
        "path": {
            "type": "tasks",
            "id": "33"
        }
    }
}

To get an array of current tasks, submit a request like this:

GET /tasks

The client can periodically check for the progress and success of a specific task by submitting a request on the provided /tasks/{id} path:

GET /tasks/33

Not all properties in the response body are present at all times. The value of the progress property is an estimated percentage of task done. When progress is 100, the state property will contain Success or Error, and the task has completed. If state is Error, then errorCode and errorText will contain values.

Here's an example of an error response:

{
    "data" : {
        "displayName": "Adding hardware",
        "progress": 100,
        "errorCode": 60277,
        "errorText": "VMO60277: Could not add the hardware.\\n\\nUnable to connect to the recording server while setting up the hardware.",
        "state": "Error",
        "relations": {
            "parent": {
                "type": "sites",
                "id": "c9cef804-e600-4b4b-b5f9-be246bb49133"
            },
        "self": {
                "type": "tasks",
                "id": "33"
            }
        }
    }
}

The relations property may contain the resource link to the object that was the result of the entire task operation, for example added hardware.

Task cleanup

After a task has completed, it should be cleaned up.

Task objects have a TaskCleanup task:

GET tasks/33?tasks&noData
{
    "tasks": [
        {
            "id": "TaskCleanup",
            "displayName": "Finish"
        }
    ]
}

To clean up the task result, submit this request:

POST /tasks/33?task=TaskCleanup

And the response will be:

{
    "result": {
        "state": "Success"
    }
}

Encoding and formats

URI path segments and query

When building a request URI, use the syntax rules defined in RFC 3986 sections 3.3 and 3.4.

In short, percent-encode the subdelim characters !$&'()\*+,;=.

JSON data formats

Request and response body content consists of a JSON object that comply with the syntax rules defined in Introducing JSON, ECMA-404, or RFC 8259.

In short:

  • String values use UTF-8 encoding and are enclosed in double quotes ". Backslash-escape a double quote within a string like this: \".
  • Real numbers use . (dot) for decimal point.
  • Date and time values are represented as strings in ISO 8601 format in UTC: yyyy-MM-ddTHH:mm:ssZ, or yyyy-MM-ddTHH:mm:ss.fffZ when microseconds are relevant.
    For example: "2020-04-02T08:29:58.172Z"

Status and error codes

Please note that error response samples are generic, that is, not specific for each request.

  • 200 OK – Success: the request completed correctly
  • 201 Created – Success: an object was created
  • 4xx Client errors – The response body will contain a JSON object that describes one or more errors. Relevant for:
    • 400 Bad Request
    • 401 Unauthorized
    • 403 Forbiden
    • 404 Not Found
  • 5xx Server errors – The response body may contain one or more error descriptions
    • 500 Internal Server Error

If a request resource URI or body content is incorrect, the response body will contain the details of the error. Errors could be like:

  • Bad resource path
  • Parameter values out of range
  • Client is not authorized for request
  • Requested object not found
  • Operation not possible

Core

Core product information

Get array of all Basic Owner Information

Basic Owner Information

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get specific object of Basic Owner Information

Basic Owner Information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0ad19f5-3d26-4fde-a31f-92e8195f480a

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on Basic Owner Information

Basic Owner Information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0ad19f5-3d26-4fde-a31f-92e8195f480a

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on Basic Owner Information

Basic Owner Information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0ad19f5-3d26-4fde-a31f-92e8195f480a

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Perform a task

Basic Owner Information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0ad19f5-3d26-4fde-a31f-92e8195f480a

Id of the object

query Parameters
task
required
string
Example: task=RemoveBasicOwnerInfo

task=AddBasicOwnerInfo, or task=RemoveBasicOwnerInfo AddBasicOwnerInfo - Add basic owner information RemoveBasicOwnerInfo - Remove basic owner tag

Request Body schema: application/json
One of
tagType
string

Select tag type

tagValue
string

Value of selected tag. This property can contain any of the BasicInformation fields. The DisplayName contains the readable name, like Address, while the Key is prefixed with the group name, e.g. address.Address or admin.Address.

Responses

Request samples

Content type
application/json
Example
{
  • "tagType": "string",
  • "tagValue": "string"
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get array of all License information

License information

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get specific object of License information

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on License information

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on License information

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Perform a task

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the object

query Parameters
task
required
string
Example: task=StopAutomaticLicenseActivation

task=ActivateLicense, or task=RequestLicense, or task=ChangeLicense, or task=UpdateLicense, or task=StopAutomaticLicenseActivation ActivateLicense - Activate License RequestLicense - Request license for offline activation ChangeLicense - Change to a new license UpdateLicense - Update license

Request Body schema: application/json
One of
userName
string

User name

password
string <password>

Password

activationAutomatic
boolean

Enable automatic license activation

Responses

Request samples

Content type
application/json
Example
{
  • "userName": "string",
  • "password": "pa$$word",
  • "activationAutomatic": true
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get array of all licenseDetails

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the licenseInformation object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get array of all licenseInstalledProducts

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the licenseInformation object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get array of all licenseOverviewAll

License information

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: f0e83649-e1aa-4424-a5be-cd507d041cd6

Id of the licenseInformation object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get array of all enabled External IDP

External IDP. To include disabled items add ?disabled to the request.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Add new loginProviders

External IDP

Authorizations:
bearerAuth
Request Body schema: application/json
enabled
boolean
name
string

Name

clientId
string

Client ID. Client ID is retrieved as part of registering with the external IDP

clientSecret
string

Client secret. Client secret is retrieved as part of registering with the external IDP

authority
string

Authentication authority. Authentication authority for the external IDP

callbackPath
string

Callback path. Callback path for the identity provider

scopes
Array of strings

Scopes. Scopes to include in queries to external IDP

userNameClaimType
string

Preferred user name claim. The name of the claim used for generating unique user names for the local users

promptForLogin
boolean

Prompt for login. Determines whether users will be prompted for credentials every time they log on

object

Responses

Request samples

Content type
application/json
{
  • "enabled": true,
  • "name": "TA External Provider",
  • "clientId": "ms.idp",
  • "clientSecret": "string",
  • "callbackPath": "/signin-oidc",
  • "scopes": [
    ],
  • "userNameClaimType": "string",
  • "promptForLogin": true,
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get specific object of External IDP

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on External IDP

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

Request Body schema: application/json
enabled
boolean
name
string

Name

clientId
string

Client ID. Client ID is retrieved as part of registering with the external IDP

clientSecret
string

Client secret. Client secret is retrieved as part of registering with the external IDP

authority
string

Authentication authority. Authentication authority for the external IDP

callbackPath
string

Callback path. Callback path for the identity provider

scopes
Array of strings

Scopes. Scopes to include in queries to external IDP

userNameClaimType
string

Preferred user name claim. The name of the claim used for generating unique user names for the local users

promptForLogin
boolean

Prompt for login. Determines whether users will be prompted for credentials every time they log on

object

Responses

Request samples

Content type
application/json
{
  • "enabled": true,
  • "name": "TA External Provider",
  • "clientId": "ms.idp",
  • "clientSecret": "string",
  • "callbackPath": "/signin-oidc",
  • "scopes": [
    ],
  • "userNameClaimType": "string",
  • "promptForLogin": true,
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on External IDP

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

Request Body schema: application/json
enabled
boolean
name
string

Name

clientId
string

Client ID. Client ID is retrieved as part of registering with the external IDP

clientSecret
string

Client secret. Client secret is retrieved as part of registering with the external IDP

authority
string

Authentication authority. Authentication authority for the external IDP

callbackPath
string

Callback path. Callback path for the identity provider

scopes
Array of strings

Scopes. Scopes to include in queries to external IDP

userNameClaimType
string

Preferred user name claim. The name of the claim used for generating unique user names for the local users

promptForLogin
boolean

Prompt for login. Determines whether users will be prompted for credentials every time they log on

object

Responses

Request samples

Content type
application/json
{
  • "enabled": true,
  • "name": "TA External Provider",
  • "clientId": "ms.idp",
  • "clientSecret": "string",
  • "callbackPath": "/signin-oidc",
  • "scopes": [
    ],
  • "userNameClaimType": "string",
  • "promptForLogin": true,
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a loginProviders

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

Responses

Response samples

Content type
application/json
{
  • "state": "Success"
}

Get array of all registeredClaims

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the loginProvider object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Add a registeredClaims to a loginProviders

External IDP

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the loginProvider object

Request Body schema: application/json
name
string

Name

object

Responses

Request samples

Content type
application/json
{
  • "name": "vms_role",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get specific registeredClaims

External IDP

Authorizations:
bearerAuth
path Parameters
idParent
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of parent object

id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Remove a registeredClaims from a loginProviders

External IDP

Authorizations:
bearerAuth
path Parameters
idParent
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of parent object

id
required
string <guid>
Example: cb707285-8180-49d3-89c9-2916186be755

Id of the object

Responses

Response samples

Content type
application/json
{
  • "state": "Success"
}

Get array of all Matrix

Matrix

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Add new matrix

Matrix

Authorizations:
bearerAuth
Request Body schema: application/json
name
string

Name

description
string

Description

address
string

Address

port
integer

Port

password
string

Password

object

Responses

Request samples

Content type
application/json
{
  • "name": "MyMatrix",
  • "description": "Matrix may have a long description",
  • "address": "localhost",
  • "port": 12345,
  • "password": "string",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get specific object of Matrix

Matrix

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 4cb572c6-20af-4dba-a000-0b6104285607

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on Matrix

Matrix

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 4cb572c6-20af-4dba-a000-0b6104285607

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

address
string

Address

port
integer

Port

password
string

Password

object

Responses

Request samples

Content type
application/json
{
  • "name": "MyMatrix",
  • "description": "Matrix may have a long description",
  • "address": "localhost",
  • "port": 12345,
  • "password": "string",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on Matrix

Matrix

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 4cb572c6-20af-4dba-a000-0b6104285607

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

address
string

Address

port
integer

Port

password
string

Password

object

Responses

Request samples

Content type
application/json
{
  • "name": "MyMatrix",
  • "description": "Matrix may have a long description",
  • "address": "localhost",
  • "port": 12345,
  • "password": "string",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a matrix

Matrix

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 4cb572c6-20af-4dba-a000-0b6104285607

Id of the object

Responses

Response samples

Content type
application/json
{
  • "state": "Success"
}

Perform a task

Matrix

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 4cb572c6-20af-4dba-a000-0b6104285607

Id of the object

query Parameters
task
required
string
Example: task=MatrixCommand

task=ChangeSecurityPermissions, or task=MatrixCommand ChangeSecurityPermissions - Edit permissions MatrixCommand - Matrix command

Request Body schema: application/json
One of
userPath
string

User path. User path format: /User[SID]. SID can contain role ID.

Responses

Request samples

Content type
application/json
Example
{
  • "userPath": "string"
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get specific object of Patrolling profile

Patrolling profile

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 0592c885-be06-4b65-b058-0118c873b733

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on Patrolling profile

Patrolling profile

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 0592c885-be06-4b65-b058-0118c873b733

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

customizeTransitions
boolean

Customize transitions. Indicates if transition from one preset to another should to be configured

initSpeed
number <double>

Initial transition: Speed. A value between 0.0 and 1.0, where 1.0 is full speed

initTransitionTime
number <double>

Initial transition: Transition time. The number of seconds it is expected to take for the movement to complete

endPresetId
string
Enum: "217433ac-b773-4752-bd0c-d4dd35b4189f" "0a8ddaba-7f7e-4f71-8f2d-4ced72ab451d"

End position: Preset. . Value map to display names: 217433ac-b773-4752-bd0c-d4dd35b4189f=Ptz Preset 1
0a8ddaba-7f7e-4f71-8f2d-4ced72ab451d=Ptz Preset 2

endSpeed
number <double>

End position: Speed. A value between 0.0 and 1.0, where 1.0 is full speed

endTransitionTime
number <double>

End position: Transition time. The number of seconds it is expected to take for the movement to complete

Array of objects (patrollingEntry)
object

Responses

Request samples

Content type
application/json
{
  • "name": "Profile 1",
  • "description": "PatrollingProfile may have a long description",
  • "customizeTransitions": false,
  • "initSpeed": 1,
  • "initTransitionTime": 3,
  • "endPresetId": "217433ac-b773-4752-bd0c-d4dd35b4189f",
  • "endSpeed": 0,
  • "endTransitionTime": 0,
  • "patrollingEntry": [
    ],
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on Patrolling profile

Patrolling profile

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 0592c885-be06-4b65-b058-0118c873b733

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

customizeTransitions
boolean

Customize transitions. Indicates if transition from one preset to another should to be configured

initSpeed
number <double>

Initial transition: Speed. A value between 0.0 and 1.0, where 1.0 is full speed

initTransitionTime
number <double>

Initial transition: Transition time. The number of seconds it is expected to take for the movement to complete

endPresetId
string
Enum: "217433ac-b773-4752-bd0c-d4dd35b4189f" "0a8ddaba-7f7e-4f71-8f2d-4ced72ab451d"

End position: Preset. . Value map to display names: 217433ac-b773-4752-bd0c-d4dd35b4189f=Ptz Preset 1
0a8ddaba-7f7e-4f71-8f2d-4ced72ab451d=Ptz Preset 2

endSpeed
number <double>

End position: Speed. A value between 0.0 and 1.0, where 1.0 is full speed

endTransitionTime
number <double>

End position: Transition time. The number of seconds it is expected to take for the movement to complete

Array of objects (patrollingEntry)
object

Responses

Request samples

Content type
application/json
{
  • "name": "Profile 1",
  • "description": "PatrollingProfile may have a long description",
  • "customizeTransitions": false,
  • "initSpeed": 1,
  • "initTransitionTime": 3,
  • "endPresetId": "217433ac-b773-4752-bd0c-d4dd35b4189f",
  • "endSpeed": 0,
  • "endTransitionTime": 0,
  • "patrollingEntry": [
    ],
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Perform a task

Patrolling profile

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 0592c885-be06-4b65-b058-0118c873b733

Id of the object

query Parameters
task
required
string
Example: task=RemovePatrollingEntry

task=AddPatrollingEntry, or task=RemovePatrollingEntry AddPatrollingEntry - Add patrolling entry RemovePatrollingEntry - Remove patrolling entry

Request Body schema: application/json
One of
order
integer

Order. Defines the order in which the presets are used. Value from 0 to x.

presetId
string

Preset ID

waitTime
number <double>

Wait time. The number of seconds the camera should stay at this preset position

Responses

Request samples

Content type
application/json
Example
{
  • "order": 0,
  • "presetId": "string",
  • "waitTime": 0
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get array of all Child sites

Child sites

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get specific object of Child sites

Child sites

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 89b2eec5-8235-4382-8312-c55d87a7b510

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on Child sites

Child sites

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 89b2eec5-8235-4382-8312-c55d87a7b510

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on Child sites

Child sites

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 89b2eec5-8235-4382-8312-c55d87a7b510

Id of the object

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get array of all siteAddresses

Child sites

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 89b2eec5-8235-4382-8312-c55d87a7b510

Id of the childSite object

Responses

Response samples

Content type
application/json
{}

Get array of all childSites

Child sites

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 89b2eec5-8235-4382-8312-c55d87a7b510

Id of the childSite object

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get array of all Management Server

Management Server

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Perform a task

Management Server

Authorizations:
bearerAuth
query Parameters
task
required
string
Example: task=UploadFileChunk

task=LoadTasks, or task=ClientLogOnSupported, or task=UploadFileChunk LoadTasks - Load the tasks existing on the server ClientLogOnSupported - Client application login supported UploadFileChunk - Upload file chunk

Request Body schema: application/json
One of
clientApplicationType
string

Client application type. Specifies the type of client application

userName
string

User name. User name for the hardware

Responses

Request samples

Content type
application/json
Example
{
  • "clientApplicationType": "string",
  • "userName": "string"
}

Response samples

Content type
application/json
{
  • "result": {
    }
}

Get specific object of Management Server

Management Server

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 00645af0-db75-40c2-82cc-2ad2e820aca9

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on Management Server

Management Server

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 00645af0-db75-40c2-82cc-2ad2e820aca9

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

object

Responses

Request samples

Content type
application/json
{
  • "name": "DKTA-1113SK0025",
  • "description": "System may have a long description",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on Management Server

Management Server

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: 00645af0-db75-40c2-82cc-2ad2e820aca9

Id of the object

Request Body schema: application/json
name
string

Name

description
string

Description

object

Responses

Request samples

Content type
application/json
{
  • "name": "DKTA-1113SK0025",
  • "description": "System may have a long description",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get array of all Address

Address

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{}

Get array of all System options

System options

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "array": [
    ]
}

Get specific object of System options

System options

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: ec9c3acc-518e-4cfd-931b-7ee69925b82c

Id of the object

query Parameters
tasks
string

Get list of all tasks supported by this object

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "tasks": [
    ],
  • "resources": [
    ]
}

Update all fields on System options

System options

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: ec9c3acc-518e-4cfd-931b-7ee69925b82c

Id of the object

Request Body schema: application/json
ptzManualSessionTimeoutSec
integer

Timeout for manual PTZ sessions (sec). A value in seconds. Value need to be in hours: e.g. multiple of 3600, or in minutes: multiple of 60, or in seconds: with max value of 999

pausePatrollingTimeoutSec
integer

Timeout for pause patrolling sessions (sec). A value in seconds. Value need to be in hours: e.g. multiple of 3600, or in minutes: multiple of 60, or in seconds: with max value of 999

ptzReservedSessionTimeoutSec
integer

Timeout for reserved PTZ sessions (sec). A value in seconds. Value need to be in hours: e.g. multiple of 3600, or in minutes: multiple of 60, or in seconds: with max value of 999

ptzUseDefaultPresetAsPtzHome
boolean

Use default preset as PTZ home position.

deviceErrorTimeoutSec
string
Enum: "0" "5" "10" "15" "30" "45" "60" "120" "300"

Ignore device communication errors for. The number of seconds to pass before logging a device communication error. Legal values are 0,1,5,10,15,30,45,60,120,300. Value map to display names: 0=0
5=5
10=10
15=15
30=30
45=45
60=60
120=120
300=300

object

Responses

Request samples

Content type
application/json
{
  • "ptzManualSessionTimeoutSec": 15,
  • "pausePatrollingTimeoutSec": 600,
  • "ptzReservedSessionTimeoutSec": 3600,
  • "ptzUseDefaultPresetAsPtzHome": false,
  • "deviceErrorTimeoutSec": "0",
  • "relations": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update provided fields on System options

System options

Authorizations:
bearerAuth
path Parameters
id
required
string <guid>
Example: ec9c3acc-518e-4cfd-931b-7ee69925b82c

Id of the object

Request Body schema: application/json
ptzManualSessionTimeoutSec
integer

Timeout for manual PTZ sessions (sec). A value in seconds. Value need to be in hours: e.g. multiple of 3600, or in minutes: multiple of 60, or in seconds: with max value of 999

</