Skip to main content

PTZ control WebSocket

The VAPIX® PTZ control WebSocket API provides Pan-Tilt-Zoom control API through a persistent WebSocket connection. This API enables clients to control continuous camera movements.

The API uses a JSON-RPC style communication protocol over WebSocket, established through an HTTP upgrade request. Once connected, clients can send continuous PTZ control commands and receive responses confirming command execution.

A client can use Device Data Hub to subscribe to PTZ specific data hub topics and stream PTZ status. The PTZ control over WebSocket API itself does not support PTZ data polling and instead provides PTZ data streaming over the data hub. The topics provided are:

  • com.axis.ptz.pan-tilt-state.v1 to stream pan tilt data
  • com.axis.ptz.optical-zoom-state.v1 to stream optical zoom data

For more information, see Device Data Hub.

Identification​

API discovery​

  • API Discovery: id=ptz-control-websocket

WebSocket​

  • WebSocket Endpoint: /vapix/ws/v1?apis=ptz-control-ws

Limitations​

This API supports cameras with Artpec7 (excluding V59xx) and Artpec9, not Artpec8.

Use cases​

Control PTZ over WebSocket​

Establish WebSocket connection for PTZ control​

To control PTZ operations, a WebSocket connection must first be established using the endpoint: /vapix/ws/v1?apis=ptz-control-ws.

The WebSocket connection starts with an HTTP handshake and upgrades to the WebSocket protocol. The connection authenticates using Digest authentication.

Initial HTTP handshake Request​
GET /vapix/ws/v1?apis=ptz-control-ws HTTP/1.1
Host: 192.168.0.90
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Authorization: Digest username="root", realm="AXIS_ACCC8EC43707",
nonce="JrMSij/TBQA=646b1c2c4c0a80a7feb4e34ef9e3422180924c37",
uri="/vapix/ws/v1?apis=ptz-control-ws",
algorithm=MD5, response="683f06da91f927fa1772c42f16597"
Upgrade: websocket
Origin: chrome-extension://cbcbkhdmedgianpaifchdaddpnmgnknn
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: 1L91ICBqd8iwa0I0e6Wgzg==

Successful response:

HTTP/1.1 101 Switching Protocols
Date: Thu, 21 Nov 2025 10:15:30 GMT
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: kZ1kuOZMJmrfKnY8FvL7Tjwb0iw=
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits=15

Query supported API versions​

Before sending control commands, query which API versions are supported by the device.

Request:

{
"jsonrpc": "2.0",
"id": "ExampleContext",
"method": "ptz-control-ws_v1:getSupportedVersions",
"params": {}
}

Response:

{
"jsonrpc": "2.0",
"id": "ExampleContext",
"method": "ptz-control-ws_v1:getSupportedVersions",
"data": {
"versions": ["1.0"]
}
}

Query capabilities​

Send a control command to a mechanical PTZ camera. This method can be used to look up PTZ ranges and mechanical channel numbers, along with their supported methods and parameters.

Request:

{
"jsonrpc": "2.0",
"id": "ExampleContext",
"method": "ptz-control-ws_v1:getCapabilities",
"params": {}
}

Response:

{
"jsonrpc": "2.0",
"id": "ExampleContext",
"method": "ptz-control-ws_v1:getCapabilities",
"data": {
"channels": [
{
"channel": 1,
"methods": [
{
"name": "continuousMove",
"description": "Initiates continuous movement for the channel",
"parameters": [
{
"name": "channel",
"type": "integer",
"required": true
},
{
"name": "panSpeedDeg",
"type": "number",
"required": false,
"range": {
"min": -180.0,
"max": 180.0
}
},
{
"name": "tiltSpeedDeg",
"type": "number",
"required": false,
"range": {
"min": -180.0,
"max": 180.0
}
},
{
"name": "zoomSpeedNormalized",
"type": "number",
"required": false,
"range": {
"min": -1.0,
"max": 1.0
}
}
]
}
]
}
]
}
}

Perform continuous PTZ movement​

Control camera pan, tilt, and zoom in a continuous motion. Continuous moves will stop automatically after 3 minutes to prevent unnecessary wear of the mechanics as long as no further commands are sent. A command must contain at least one of the three before it can be sent.

Request:

{
"jsonrpc": "2.0",
"id": "ptz",
"method": "ptz-control-ws_v1:continuousMove",
"params": {
"channel": 1,
"panSpeedDeg": -20.0,
"zoomSpeedNormalized": 1.0
}
}

Response:

{
"jsonrpc": "2.0",
"id": "ptz",
"method": "ptz-control-ws_v1:continuousMove",
"data": {}
}

API specification​

WebSocket connection establishment​

PTZ control over WebSocket is performed with the following WebSocket endpoint:

ws(s)://<device-ip>/vapix/ws/v1?apis=ptz-control-ws

  • Security level: Admin and Operator. PTZ control is not required.

Authentication​

Users need to authenticate themselves in order to use this API. Authentication can be performed in one of two ways:

  1. Digest Digest authentication can be achieved by following the standard Digest authentication process. When authentication is performed the connection will be upgraded to a WebSocket connection.

  2. Session token As an alternative to Digest authentication it is possible to generate a session token and use the generated token for authentication. This approach can be useful when the client tools don't support Digest authentication.

    A session token can be generated by making a GET request to the following URL: http(s)://<device>/axis-cgi/wssession.cgi. This request requires standard Digest authentication.

    The device will respond with the session token in the payload. This token is valid for 15 seconds and will then expire. The token shall be used in the WebSocket connection URL as a parameter (wssession) as shown below:

    ws(s)://\<device\>/vapix/ws/v1?wssession=\<session-token\>&apis=ptz-control-ws

Connection lifecycle​

  1. Client initiates a HTTP GET request with WebSocket upgrade headers
  2. Server responds with 101 Switching Protocols on a successful authentication
  3. Connection is upgraded to WebSocket protocol
  4. Client can now send JSON-RPC style messages as text packages
  5. Connection remains open until explicitly closed by either party

Access rights​

This API can be used by admin and operator users. The account doesn't require explicit PTZ permissions.

getSupportedVersions​

Query the API versions supported by the device.

  • Security level: Admin and Operator. PTZ control is not required.

Request

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "ptz-control-ws_v1:getSupportedVersions",
"params": {}
}

Parameters:

FieldTypeRequiredDescription
apiVersionstringYesThe API version to use for the request.
contextstringNoContext identifier for request-response correlation.
methodstringYesMust be ptz-control-ws_v1:getSupportedVersions.
paramsobjectYesEmpty object.

Response - Success

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "ptz-control-ws_v1:getSupportedVersions",
"data": {
"versions": ["1.0"]
}
}

Response fields:

FieldTypeDescription
apiVersionstringThe API version used by the device.
contextstringEchoed context from the request.
methodstringEchoed method name.
dataobjectResponse data containing supported versions.

getCapabilities​

The getCapabilities method allows clients to discover mechanical channel numbers, API methods and their supported parameters.

  • Security level: Admin and Operator. PTZ control is not required.

Request

{
"jsonrpc": "2.0",
"id": "APD",
"method": "ptz-control-ws_v1:getCapabilities",
"params": {}
}

Parameters:

FieldTypeRequiredDescription
apiVersionstringYesThe API version to use for the request.
contextstringNoAPI context identifier.
methodstringYesMust be ptz-control-ws_v1:getCapabilities.
paramsobjectYesParameters object.

Response - Success

{
"jsonrpc": "2.0",
"id": "ExampleContext",
"method": "ptz-control-ws_v1:getCapabilities",
"data": {
"channels": [
{
"channel": 1,
"methods": [
{
"name": "continuousMove",
"description": "Initiates continuous movement for the channel",
"parameters": [
{
"name": "channel",
"type": "integer",
"required": true
},
{
"name": "panSpeedDeg",
"type": "number",
"required": false,
"default": 0.0,
"range": {
"min": -180.0,
"max": 180.0
}
},
{
"name": "tiltSpeedDeg",
"type": "number",
"required": false,
"default": 0.0,
"range": {
"min": -180.0,
"max": 180.0
}
},
{
"name": "zoomSpeedNormalized",
"type": "number",
"required": false,
"default": 0.0,
"range": {
"min": -1.0,
"max": 1.0
}
}
]
}
]
}
]
}
}

Response fields:

FieldTypeDescription
apiVersionstringAPI version used by the device.
contextstringEchoed context from the request.
methodstringEchoed method name.
dataobjectResponse data object containing channels and supported methods.
data.channelsarrayArray of channel objects.
data.channels[].channelintegerChannel number.
data.channels[].methodsarrayArray of method objects available on the channel.
data.channels[].methods[].namestringMethod name.
data.channels[].methods[].descriptionstringDescription of the method.
data.channels[].methods[].parametersarrayArray of parameter objects for the method.
data.channels[].methods[].parameters[].namestringParameter name.
data.channels[].methods[].parameters[].typestringParameter data type (e.g., integer, number, string, enum, boolean, object).
data.channels[].methods[].parameters[].requiredbooleanWhether the parameter is required.
data.channels[].methods[].parameters[].defaultnumber/string/booleanDefault value if parameter is not provided (optional). For enum types this must be one of the allowed enum values.
data.channels[].methods[].parameters[].rangeobjectValid range for numeric parameters (optional).
data.channels[].methods[].parameters[].range.minnumberMinimum allowed value.
data.channels[].methods[].parameters[].range.maxnumberMaximum allowed value.
data.channels[].methods[].parameters[].enumarrayList of valid values when type is "enum" (optional).
data.channels[].methods[].parameters[].enum[]stringIndividual allowed enum value.

continuousMove​

Execute continuous PTZ movement at specified pan, tilt, and zoom speeds. The movement persists until a stop command is issued (using a continuousMove command with a speed of 0.0 to halt the movement, e.g., panSpeedDeg), a new command is given, or a 3-minute timeout occurs to prevent unnecessary mechanical wear.

  • Security level: Admin and Operator. PTZ control is not required.

Request

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "ptz-control-ws_v1:continuousMove",
"params": {
"channel": 1,
"panSpeedDeg": -10.0,
"tiltSpeedDeg": -10.0,
"zoomSpeedNormalized": 1.0
}
}

Parameters:

FieldTypeRequiredValid valuesDescription
apiVersionstringYes"1"The API version to use for the request.
contextstringNoAny stringContext identifier for request-response correlation.
methodstringYes"ptz-control-ws:continuousMove"Must be ptz-control-ws_v1:continuousMove.
paramsobjectYes-Parameter object.
params.channelnumberYesDevice dependentThe camera channel number. Retrieves available channels from param.cgi.
params.panSpeedDegnumberNoDevice dependentThe pan speed, measured in degrees per second.
params.tiltSpeedDegnumberNoDevice dependentThe tilt speed, measured in degrees per second.
params.zoomSpeedNormalizednumberNo-1.0 to 1.0The normalized zoom speed. Negative values = zoom out, positive values = zoom in.

Response - Success

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "ptz-control-ws_v1:continuousMove",
"data": {}
}

Response fields:

FieldTypeDescription
apiVersionstringThe API version used by the device.
contextstringEchoed context from the request.
methodstringEchoed method name.
dataobjectEmpty object indicating success.

Response - Error

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "ptz-control-ws_v1:continuousMove",
"error": {
"code": 2104,
"message": "Invalid parameter value specified"
}
}

Error handling​

All errors follow a consistent JSON-RPC error structure:

{
"jsonrpc": "2.0",
"id": "<string>",
"method": "<string>",
"error": {
"code": "<integer>",
"message": "<string>"
}
}

General error codes:

CodeDescription
1100Internal error
1200PTZ not ready
2100API version not supported
2101Invalid JSON
2102Method not supported
2103Required parameter missing
2104Invalid parameter value specified
2105Authorization failed
2106Authentication failed
2107Transport level error