This guide shows a complete, real-world workflow to manage a connector using SSW APIs: create it, get the command that deploys it on your host, change its settings, and delete it.
What You Will Do
- Authenticate API key → get
sdp_token - Pick an edge and a network → get
edge_idand the network name - Create a connector (or look up an existing one) → get
site_id - Get the deploy command for Docker / Helm / Linux / Windows / macOS
- Update the connector settings
- Clean up by deleting the connector
Auth requirement
All/ztna/v1/...API calls require:Authorization: Bearer <sdp_token>
💡 Tip
In the API, a connector is called a site.site_idis the connector ID.
Prerequisites
Required
API key that can obtain an SDP token. The user who owns the key needs these roles:
| Operation | Minimum role |
|---|---|
| Create / update a connector | Network Manager |
| Get the deploy command | Admin |
| Delete a connector | Any role (non-managers can only delete connectors they created) |
To run every step in this guide, use a key owned by an Admin or Super Admin.
SSW base URL, for example:
https://<your-ssw-host>
A free connector seat in your license. Creating a connector fails once the license limit is reached.
Tools
- curl
- jq (recommended)
Step 1: Get sdp_token
Request
SSW_HOST="<your-ssw-host>"
APIKEY="YOUR_API_KEY"
curl -s -X POST "https://${SSW_HOST}/iam/v1/apikey/authenticate" \
-H "Content-Type: application/json" \
-d "{\"apikey\":\"${APIKEY}\"}" \
-o sdp_iam_token.json
Extract Token
SDP_TOKEN="$(jq -r '.data.sdp_token' sdp_iam_token.json)"
echo "$SDP_TOKEN"
Step 2: Pick an Edge and a Network
Pick an Edge
Each connector connects to one edge. Pick the edge closest to the network the connector will serve.
curl -s -X GET "https://${SSW_HOST}/ztna/v1/edge?connector_support=true&show_position=connector&page_size=10000" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o edges.json
jq '.data.list[] | {edge_id, name, location}' edges.json
Example output:
{ "edge_id": "8fdfcf14-...", "name": "San Francisco, California", "location": "US" }
{ "edge_id": "5ec20361-...", "name": "Singapore, Singapore", "location": "SG" }
Choose one and save its edge_id:
EDGE_NAME="San Francisco, California"
EDGE_ID="$(jq -r --arg n "$EDGE_NAME" '.data.list[] | select(.name == $n) | .edge_id' edges.json)"
echo "EDGE_ID=$EDGE_ID"
⚠️ Important
The edge cannot be changed after the connector is created. To move a connector to another edge, delete it and create a new one.
Pick a Network
Every connector belongs to a network. Network names differ between organizations, so look yours up instead of assuming a name.
curl -s -X GET "https://${SSW_HOST}/ztna/v1/network?workspace_type=1" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o networks.json
jq '.data.list[] | {network_id, name}' networks.json
NETWORK_NAME="$(jq -r '.data.list[0].name' networks.json)" # or pick one by name
echo "NETWORK_NAME=$NETWORK_NAME"
Step 3: Create a Connector
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Connector name, unique within the organization, max 40 characters. Cannot be changed later. |
display_name |
string | No | Name shown in the console. Defaults to name. Max 40 characters. |
edge_id |
string | Yes | Edge from Step 2. |
network_name |
string | One of the two | Network from Step 2. |
network_id |
string | One of the two | Use instead of network_name. |
allow_remote_control |
boolean | Yes | Set to true. A connector with false cannot be edited in the console. |
conn_category |
integer | No | 0 = connector (default). This guide covers 0 only. |
cluster_mode |
boolean | No | Run the connector as a cluster of instances. Cannot be turned off once enabled. |
auto_bandwidth_detection |
boolean | No | Default false. |
enable_shell |
boolean | No | Default false. |
auto_upgrade |
boolean | No | Omit to follow the organization setting. true / false overrides it for this connector. |
is_scan |
boolean | No | Enable network discovery scanning. Default false. |
scan_targets |
string | No | Comma-separated IPs or CIDRs to scan. |
scan_ports |
string | No | Comma-separated ports to scan. |
scan_interval |
integer | No | Scan interval. Default 20. |
Create Request
CONNECTOR_NAME="dev-qa-api-connector"
curl -s -X POST "https://${SSW_HOST}/ztna/v1/site" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"${CONNECTOR_NAME}\",
\"display_name\": \"${CONNECTOR_NAME}\",
\"edge_id\": \"${EDGE_ID}\",
\"network_name\": \"${NETWORK_NAME}\",
\"allow_remote_control\": true,
\"conn_category\": 0,
\"cluster_mode\": false,
\"auto_bandwidth_detection\": false,
\"enable_shell\": false,
\"is_scan\": false,
\"scan_interval\": 20
}" \
-o create_result.json
Validate Create Result
CREATE_CODE="$(jq -r '.code' create_result.json)"
if [ "$CREATE_CODE" != "0" ]; then
echo "Create failed:"
jq '{code, message}' create_result.json
exit 1
fi
Extract site_id
SITE_ID="$(jq -r '.data.site_id' create_result.json)"
echo "SITE_ID=$SITE_ID"
Alternative: Look Up an Existing Connector
If the connector already exists, find its site_id by name:
curl -s -X GET "https://${SSW_HOST}/ztna/v1/site/all?workspace_type=0&conn_category=0" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o connectors.json
SITE_ID="$(jq -r --arg n "$CONNECTOR_NAME" '.data.list[] | select(.name == $n) | .site_id' connectors.json)"
echo "SITE_ID=$SITE_ID"
Step 4: Get the Deploy Command
This returns ready-to-run commands that install the connector and register it with SSW. Run one of them on the host where the connector should run.
Deploy Command Request
curl -s -X GET "https://${SSW_HOST}/ztna/v1/connectorToken/${SITE_ID}/organization?type=All" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o deploy.json
Response
{
"code": 0,
"data": {
"name": "<deployment_name>",
"token": "<deploy_token>",
"all_token": {
"docker": "docker pull ... && docker run ...",
"helm": "helm repo add ... && helm install ...",
"linux": "export SSW_CONNECTOR=... ",
"desktop": "<deploy_token>",
"darwin": "bash -c 'export SSW_CONNECTOR=... '",
"windows": "$env:SSW_CONNECTOR_TOKEN=\"...\" ..."
},
"cli": {
"linux": "bash -c 'arch=$(uname -m) && ... '",
"darwin": "bash -c 'arch=$(uname -m) && ... '",
"windows": "$CONNECTOR_DOWNLOAD_URL=\"...\" ..."
}
},
"message": "Success"
}
| Field | Description |
|---|---|
all_token.docker |
Run the connector as a Docker container |
all_token.helm |
Install the connector into Kubernetes with Helm |
all_token.linux |
Install on a Linux host |
all_token.windows / all_token.darwin |
Install on Windows (PowerShell) / macOS |
all_token.desktop |
The raw deploy token, for the desktop connector app |
cli.* |
Command-line installers for Linux / macOS / Windows |
token |
The raw deploy token, for building your own install command |
name |
Service name used by the deployment. This is not the connector name. |
Extract a Command (Example: Docker)
DEPLOY_CMD="$(jq -r '.data.all_token.docker' deploy.json)"
echo "$DEPLOY_CMD"
⚠️ Important
- The deploy token expires after 24 hours. If you deploy later, call this API again to get a fresh command. This does not affect a connector that is already running.
- The command contains a credential. Treat it like a secret and do not commit it to source control or share it in logs.
- Do not call this API for the same connector in parallel. Concurrent calls are rejected with "Do not generate token so frequently".
Step 5: Update the Connector
The update API replaces the connector settings with the request body. It is not a partial update.
⚠️ Important
Sending only{"display_name": "new-name"}also setsallow_remote_controltofalse, turns off scanning, clearsscan_targets/scan_ports, and setsscan_intervalto0.
Always read the current settings first, change what you need, and send the whole object back.
What Can Be Changed
| Field | Updatable | Notes |
|---|---|---|
display_name |
Yes | Max 40 characters |
network_id / network_name |
Yes | Moves the connector to another network |
allow_remote_control, auto_bandwidth_detection, enable_shell |
Yes | |
is_scan, scan_targets, scan_ports, scan_interval |
Yes | |
supported_functions |
Yes | Send back the value of supported_functions_config from the GET response |
cluster_mode |
false → true only |
Turning cluster mode off is rejected |
auto_upgrade |
Yes | Omit = keep the current setting; null = follow the organization setting; true / false = override |
name, edge_id, conn_category |
No | Fixed at creation |
Read the Current Settings
curl -s -X GET "https://${SSW_HOST}/ztna/v1/site/${SITE_ID}" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o connector.json
jq '.data | {name, display_name, network_id, allow_remote_control, enable_shell, is_scan, scan_targets, scan_ports, scan_interval, supported_functions_config}' connector.json
Build the Update Body
Copy the current settings, then change what you need. This example renames the connector and turns on shell access:
jq '.data | {
name,
display_name,
network_id,
allow_remote_control,
auto_bandwidth_detection,
enable_shell,
cluster_mode,
is_scan,
scan_interval,
scan_targets,
scan_ports,
supported_functions: .supported_functions_config
}
| .display_name = "dev-qa-api-connector-renamed"
| .enable_shell = true' \
connector.json > update_body.json
cat update_body.json
Send the Update
curl -s -X PUT "https://${SSW_HOST}/ztna/v1/site/${SITE_ID}" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-H "Content-Type: application/json" \
--data @update_body.json \
-o update_result.json
jq '{code, message}' update_result.json
Read the current settings again to confirm the change.
Step 6: Cleanup — Delete the Connector
⚠️ Important
Deleting a connector also deletes every application that uses it. List them before you delete.
List Applications Using the Connector
curl -s -X GET "https://${SSW_HOST}/ztna/v1/site/${SITE_ID}/app" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" | jq .data
Delete Request
curl -s -X DELETE "https://${SSW_HOST}/ztna/v1/site/${SITE_ID}" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${SDP_TOKEN}" \
-o delete_result.json
jq '{code, message}' delete_result.json
Verify Deletion
After deletion, reading the connector returns 40001 Record not found:
curl -s -X GET "https://${SSW_HOST}/ztna/v1/site/${SITE_ID}" \
-H "Authorization: Bearer ${SDP_TOKEN}" | jq '{code, message}'
{ "code": 40001, "message": "Record not found" }
Common Pitfalls
- ❌ Using the API key directly to call
/ztna/v1/...APIs
→ Always usesdp_token - ❌ Checking only the HTTP status
→ Business errors come back as HTTP 200 with a non-zerocode(for example40001 Record not found). Always check.code;0means success. - ❌ Getting a permission error on Step 4 with a Network Manager key
→ Getting the deploy command requires an Admin or Super Admin key - ❌ Sending only the changed fields to the update API
→ Omitted fields are reset, includingallow_remote_control. Always read first and send the full object. - ❌ Hard-coding a network name such as
Default
→ Network names differ per organization. Look them up in Step 2. - ❌ Running a deploy command that is more than 24 hours old
→ Call Step 4 again for a fresh command - ❌ Reusing a connector name
→ Names must be unique within the organization, including connectors created in the console - ❌ Deleting a connector that applications still use
→ Those applications are deleted too