Skip to main content

ZPA API Cheat Sheet

· 7 min read
Joie Llantero
Security Engineer

A quick reference for the Zscaler Private Access (ZPA) API. ZPA provides a RESTful interface for managing private application access — app segments, server groups, app connectors, access policies, and identity providers. Skim the quick-reference table if you just need a reminder, scroll down for full examples.

API Overview

ItemValue
Base URLhttps://config.private.zscaler.com/mgmtconfig/v1/admin/customers/<customerId>
AuthOAuth 2.0 Bearer token
Token endpointhttps://config.private.zscaler.com/signin

Quick Reference

ActionMethodEndpoint
List app segmentsGET/application
List server groupsGET/serverGroup
List app connectorsGET/connector
List connector groupsGET/connectorGroup
List segment groupsGET/segmentGroup
List access policiesGET/policySet/rules
List service edgesGET/serviceEdge
List service edge groupsGET/serviceEdgeGroup
List provisioning keysGET/provisioningKey
List certificatesGET/certificate
List IdPsGET/idp
List SCIM groupsGET/scimgroup/idpId/<idpId>

Authentication

OAuth 2.0 (Client Credentials)

# Set your ZPA base URL
ZPA_BASE="https://config.private.zscaler.com"
CUSTOMER_ID="<your_customer_id>"
ZPA="$ZPA_BASE/mgmtconfig/v1/admin/customers/$CUSTOMER_ID"

# Get Bearer token
ZPA_TOKEN=$(curl -s -X POST "$ZPA_BASE/signin" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=<client_id>&client_secret=<client_secret>" | \
python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

# Use Bearer token in subsequent requests
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application"

Common Patterns

Copy-paste recipes for everyday scenarios.

# ZPA: List all app segments with their server groups
curl -s -H "Authorization: Bearer $ZPA_TOKEN" \
"$ZPA/application?page=1&pagesize=500" | python3 -m json.tool

# ZPA: Search for an app segment by name
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?search=wiki"

# ZPA: Get all connectors in a connector group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/connector?connectorGroupId=<group_id>"

Application Segments

# List all application segments
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application"

# Get a specific application segment
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application/<app_id>"

# Create an application segment
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/application" \
-H "Content-Type: application/json" \
-d '{
"name": "Internal Wiki",
"description": "Company wiki behind ZPA",
"enabled": true,
"domainNames": ["wiki.internal.example.com"],
"tcpPortRanges": ["443", "443"],
"segmentGroupId": "<segment_group_id>",
"serverGroups": [{"id": "<server_group_id>"}],
"bypassType": "NEVER",
"healthCheckType": "DEFAULT",
"isCnameEnabled": false,
"ipAnchored": false
}'

# Update an application segment
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X PUT "$ZPA/application/<app_id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Internal Wiki",
"domainNames": ["wiki.internal.example.com", "wiki2.internal.example.com"],
"tcpPortRanges": ["443", "443", "8443", "8443"]
}'

# Delete an application segment
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X DELETE "$ZPA/application/<app_id>"

Server Groups and Servers

# List server groups
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/serverGroup"

# Get a specific server group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/serverGroup/<group_id>"

# Create a server group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/serverGroup" \
-H "Content-Type: application/json" \
-d '{
"name": "DC Servers",
"description": "Data center servers",
"enabled": true,
"dynamicDiscovery": false,
"servers": [{"id": "<server_id>"}],
"appConnectorGroups": [{"id": "<connector_group_id>"}]
}'

# List application servers
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/server"

# Create an application server
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/server" \
-H "Content-Type: application/json" \
-d '{
"name": "wiki-server-01",
"address": "10.0.1.50",
"enabled": true
}'

Segment Groups

# List segment groups
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/segmentGroup"

# Create a segment group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/segmentGroup" \
-H "Content-Type: application/json" \
-d '{
"name": "Corporate Apps",
"description": "Segment group for corporate applications",
"enabled": true
}'

App Connectors and Connector Groups

# List connector groups
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/connectorGroup"

# Get a specific connector group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/connectorGroup/<group_id>"

# List connectors in a connector group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/connector?connectorGroupId=<group_id>"

# Create a connector group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/connectorGroup" \
-H "Content-Type: application/json" \
-d '{
"name": "DC East Connectors",
"description": "App connectors in East DC",
"enabled": true,
"latitude": "40.7128",
"longitude": "-74.0060",
"location": "New York, NY",
"countryCode": "US"
}'

# Delete a connector (decommission)
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X DELETE "$ZPA/connector/<connector_id>"

# Bulk delete connectors
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/connector/bulkDelete" \
-H "Content-Type: application/json" \
-d '{"ids": ["<id1>", "<id2>"]}'

Access Policies

# Get the access policy set (contains the policy set ID)
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/policySet/policyType/ACCESS_POLICY"

# List access policy rules
POLICY_SET_ID="<policy_set_id>"
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/policySet/$POLICY_SET_ID/rules"

# Get a specific access policy rule
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/policySet/$POLICY_SET_ID/rules/<rule_id>"

# Create an access policy rule
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/policySet/$POLICY_SET_ID/rules" \
-H "Content-Type: application/json" \
-d '{
"name": "Allow Engineering to Internal Apps",
"action": "ALLOW",
"operator": "AND",
"conditions": [
{
"operands": [
{
"objectType": "APP",
"values": ["<app_segment_id>"]
}
]
},
{
"operands": [
{
"objectType": "SCIM_GROUP",
"values": ["<scim_group_id>"],
"idpId": "<idp_id>"
}
]
}
]
}'

Provisioning Keys

# List provisioning keys (for connector enrollment)
curl -s -H "Authorization: Bearer $ZPA_TOKEN" \
"$ZPA/provisioningKey?associationType=CONNECTOR_GRP"

# Create a provisioning key
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST \
"$ZPA/provisioningKey" \
-H "Content-Type: application/json" \
-d '{
"name": "DC East Key",
"associationType": "CONNECTOR_GRP",
"maxUsage": "10",
"enrollmentCertId": "<cert_id>",
"zcomponentId": "<connector_group_id>"
}'

Service Edges

# List service edges
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/serviceEdge"

# List service edge groups
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/serviceEdgeGroup"

# Create a service edge group
curl -s -H "Authorization: Bearer $ZPA_TOKEN" -X POST "$ZPA/serviceEdgeGroup" \
-H "Content-Type: application/json" \
-d '{
"name": "Branch Office Edges",
"description": "Service edges for branch offices",
"enabled": true,
"latitude": "34.0522",
"longitude": "-118.2437",
"location": "Los Angeles, CA",
"countryCode": "US"
}'

Identity Providers and SCIM

# List identity providers
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/idp"

# List SCIM groups for an IdP
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/scimgroup/idpId/<idp_id>"

# List SCIM attributes for an IdP
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/scimattributeHeader/idpId/<idp_id>"

# List enrollment certificates
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/certificate"

Pagination

# ZPA pagination (page + pagesize)
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?page=1&pagesize=20"
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?page=2&pagesize=20"

# Get total pages from response
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?page=1&pagesize=20" | \
python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Total: {d[\"totalPages\"]} pages')"

# Loop through all pages
PAGE=1
while true; do
RESULT=$(curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?page=$PAGE&pagesize=100")
COUNT=$(echo "$RESULT" | python3 -c "import sys,json; print(len(json.load(sys.stdin).get('list', [])))")
echo "Page $PAGE: $COUNT app segments"
[[ "$COUNT" -lt 100 ]] && break
((PAGE++))
done

Rate Limits

LimitValue
Requests20 per 10 seconds
ScopePer OAuth client
# Respect rate limits with a sleep between requests
for id in app1 app2 app3 app4 app5; do
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application/$id"
sleep 1
done

Error Handling

Common HTTP status codes across Zscaler APIs:

CodeMeaning
200Success
201Created
204Deleted (no content)
400Bad request (check your JSON)
401Unauthorized (expired session/token)
403Forbidden (insufficient permissions)
404Resource not found
409Conflict (duplicate name, etc.)
429Rate limit exceeded
# Check for errors in response
RESPONSE=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application/bad-id")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')

if [[ "$HTTP_CODE" -ne 200 ]]; then
echo "Error $HTTP_CODE: $BODY"
fi

Useful Tips

# Use search parameter to filter results
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?search=wiki"

# Pretty-print any JSON response
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application" | python3 -m json.tool

# Export all app segments to a JSON file
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application?page=1&pagesize=500" | \
python3 -m json.tool > app_segments.json

# Token refresh — ZPA tokens typically expire in 3600 seconds
# Re-run the signin request before expiry

# Find which app segment a domain belongs to
curl -s -H "Authorization: Bearer $ZPA_TOKEN" "$ZPA/application" | \
python3 -c "
import sys, json
apps = json.load(sys.stdin).get('list', [])
for app in apps:
if 'wiki' in ','.join(app.get('domainNames', [])).lower():
print(f\"{app['name']}: {app['domainNames']}\")
"