ZIA API Cheat Sheet
· 7 min read
A quick reference for the Zscaler Internet Access (ZIA) API. ZIA provides a RESTful interface for managing URL filtering, firewall policies, DLP, sandbox, users, and traffic forwarding. Skim the quick-reference table if you just need a reminder, scroll down for full examples.
API Overview
| Base URL | Cloud |
|---|---|
https://zsapi.zscaler.net/api/v1 | zscaler.net |
https://zsapi.zscalerone.net/api/v1 | zscalerone.net |
https://zsapi.zscalertwo.net/api/v1 | zscalertwo.net |
https://zsapi.zscloud.net/api/v1 | zscloud.net |
https://zsapi.zscalerthree.net/api/v1 | zscalerthree.net |
https://zsapi.zscalergov.net/api/v1 | zscalergov.net |
Quick Reference
| Action | Method | Endpoint |
|---|---|---|
| Authenticate | POST | /authenticatedSession |
| List URL categories | GET | /urlCategories |
| List URL filter rules | GET | /urlFilteringRules |
| List firewall rules | GET | /webApplicationRules |
| List DLP dictionaries | GET | /dlpDictionaries |
| List locations | GET | /locations |
| List users | GET | /users |
| List departments | GET | /departments |
| List groups | GET | /groups |
| List VPN credentials | GET | /vpnCredentials |
| Activate changes | POST | /status/activate |
| Get activation status | GET | /status |
| End session | DELETE | /authenticatedSession |
Authentication
Session-Based Auth
# Set your cloud base URL
ZIA="https://zsapi.zscaler.net/api/v1"
# Authenticate (returns JSESSIONID cookie)
curl -s -c zia_cookies.txt -X POST "$ZIA/authenticatedSession" \
-H "Content-Type: application/json" \
-d '{
"apiKey": "<obfuscated_api_key>",
"username": "admin@example.com",
"password": "<password>",
"timestamp": "<timestamp>"
}'
# Use session cookie in subsequent requests
curl -s -b zia_cookies.txt "$ZIA/users?page=1&pageSize=100"
# End session when done
curl -s -b zia_cookies.txt -X DELETE "$ZIA/authenticatedSession"
API Key Obfuscation
ZIA requires an obfuscated API key derived from the raw key and the current timestamp. Here is a Python example:
import time
def obfuscate_api_key(api_key: str) -> tuple[str, str]:
"""Returns (obfuscated_key, timestamp) for ZIA auth."""
now = str(int(time.time() * 1000))
n = now[-6:]
r = str(int(n) >> 1).zfill(6)
key = ""
for i in range(len(n)):
key += api_key[int(n[i])]
for i in range(len(r)):
key += api_key[int(r[i]) + 2]
return key, now
obfuscated, timestamp = obfuscate_api_key("YOUR_RAW_API_KEY")
Common Patterns
Copy-paste recipes for everyday scenarios.
# ZIA: Authenticate → make request → activate → logout
curl -s -c cookies.txt -X POST "$ZIA/authenticatedSession" \
-H "Content-Type: application/json" \
-d "{\"apiKey\":\"$KEY\",\"username\":\"$USER\",\"password\":\"$PASS\",\"timestamp\":\"$TS\"}"
curl -s -b cookies.txt -X POST "$ZIA/urlFilteringRules" \
-H "Content-Type: application/json" \
-d '{"name":"Block Gambling","order":1,"state":"ENABLED","action":"BLOCK","urlCategories":["GAMBLING"]}'
curl -s -b cookies.txt -X POST "$ZIA/status/activate"
curl -s -b cookies.txt -X DELETE "$ZIA/authenticatedSession"
# Search for a specific user in ZIA
curl -s -b cookies.txt "$ZIA/users?name=joie@example.com"
# List all locations with pagination
curl -s -b cookies.txt "$ZIA/locations?page=1&pageSize=1000"
URL Filtering
# List all URL categories (predefined + custom)
curl -s -b cookies.txt "$ZIA/urlCategories"
# List only custom URL categories
curl -s -b cookies.txt "$ZIA/urlCategories?customOnly=true"
# Get a specific URL category by ID
curl -s -b cookies.txt "$ZIA/urlCategories/CUSTOM_01"
# Create a custom URL category
curl -s -b cookies.txt -X POST "$ZIA/urlCategories" \
-H "Content-Type: application/json" \
-d '{
"configuredName": "Blocked Sites",
"superCategory": "USER_DEFINED",
"urls": ["badsite.com", "malware.example.com"],
"dbCategorizedUrls": [],
"type": "URL_CATEGORY"
}'
# Add URLs to an existing custom category
curl -s -b cookies.txt -X PUT "$ZIA/urlCategories/CUSTOM_01" \
-H "Content-Type: application/json" \
-d '{
"configuredName": "Blocked Sites",
"urls": ["badsite.com", "malware.example.com", "newbad.example.com"],
"dbCategorizedUrls": []
}'
# Look up the category of a URL
curl -s -b cookies.txt -X POST "$ZIA/urlLookup" \
-H "Content-Type: application/json" \
-d '["example.com", "google.com"]'
# List URL filtering rules
curl -s -b cookies.txt "$ZIA/urlFilteringRules"
# Create a URL filtering rule
curl -s -b cookies.txt -X POST "$ZIA/urlFilteringRules" \
-H "Content-Type: application/json" \
-d '{
"name": "Block Social Media",
"order": 1,
"state": "ENABLED",
"action": "BLOCK",
"urlCategories": ["SOCIAL_NETWORKING"],
"locations": [{"id": 12345}],
"groups": [{"id": 67890}]
}'
Firewall Policies
# List firewall rules
curl -s -b cookies.txt "$ZIA/webApplicationRules"
# List network services
curl -s -b cookies.txt "$ZIA/networkServices"
# List network application groups
curl -s -b cookies.txt "$ZIA/networkApplicationGroups"
# Create a firewall rule
curl -s -b cookies.txt -X POST "$ZIA/webApplicationRules" \
-H "Content-Type: application/json" \
-d '{
"name": "Block BitTorrent",
"order": 1,
"state": "ENABLED",
"action": "BLOCK_RESET",
"networkApplications": ["BITTORRENT"]
}'
Locations and Sub-Locations
# List all locations
curl -s -b cookies.txt "$ZIA/locations"
# Search locations by name
curl -s -b cookies.txt "$ZIA/locations?search=headquarters"
# Get a specific location
curl -s -b cookies.txt "$ZIA/locations/12345"
# Create a location
curl -s -b cookies.txt -X POST "$ZIA/locations" \
-H "Content-Type: application/json" \
-d '{
"name": "Branch Office NYC",
"ipAddresses": ["203.0.113.10"],
"country": "UNITED_STATES",
"state": "ENABLED"
}'
# List sub-locations for a parent location
curl -s -b cookies.txt "$ZIA/locations/12345/sublocations"
Users and Groups
# List users (paginated)
curl -s -b cookies.txt "$ZIA/users?page=1&pageSize=100"
# Search for a user by name
curl -s -b cookies.txt "$ZIA/users?name=joie@example.com"
# Get a specific user
curl -s -b cookies.txt "$ZIA/users/12345"
# List departments
curl -s -b cookies.txt "$ZIA/departments"
# List groups
curl -s -b cookies.txt "$ZIA/groups"
# Create a user
curl -s -b cookies.txt -X POST "$ZIA/users" \
-H "Content-Type: application/json" \
-d '{
"name": "Joie Lantero",
"email": "joie@example.com",
"password": "TempPass123!",
"groups": [{"id": 67890}],
"department": {"id": 11111}
}'
DLP
# List DLP dictionaries
curl -s -b cookies.txt "$ZIA/dlpDictionaries"
# Get a specific DLP dictionary
curl -s -b cookies.txt "$ZIA/dlpDictionaries/1"
# List DLP notification templates
curl -s -b cookies.txt "$ZIA/dlpNotificationTemplates"
# List DLP engines
curl -s -b cookies.txt "$ZIA/dlpEngines"
# List web DLP rules
curl -s -b cookies.txt "$ZIA/webDlpRules"
VPN Credentials and Traffic Forwarding
# List VPN credentials
curl -s -b cookies.txt "$ZIA/vpnCredentials"
# Create VPN credentials (UFQDN type)
curl -s -b cookies.txt -X POST "$ZIA/vpnCredentials" \
-H "Content-Type: application/json" \
-d '{
"type": "UFQDN",
"fqdn": "branch01@example.com",
"preSharedKey": "YourPSK123!"
}'
# List GRE tunnels
curl -s -b cookies.txt "$ZIA/greTunnels"
# List static IPs
curl -s -b cookies.txt "$ZIA/staticIP"
# Create a static IP
curl -s -b cookies.txt -X POST "$ZIA/staticIP" \
-H "Content-Type: application/json" \
-d '{
"ipAddress": "203.0.113.50",
"comment": "Branch NYC egress"
}'
Sandbox and Security
# Submit a file for sandbox analysis
curl -s -b cookies.txt -X POST "$ZIA/sandbox/submit" \
-H "Content-Type: application/octet-stream" \
--data-binary @suspicious_file.exe
# Get sandbox submission quota
curl -s -b cookies.txt "$ZIA/sandbox/report/quota"
# Get sandbox report by MD5 hash
curl -s -b cookies.txt "$ZIA/sandbox/report/md5/<md5_hash>"
# List security policy rules (advanced threat protection)
curl -s -b cookies.txt "$ZIA/advancedThreatSettings"
Activate Changes
ZIA uses a staging/activation model. Changes are not live until activated.
# Check activation status
curl -s -b cookies.txt "$ZIA/status"
# Activate pending changes
curl -s -b cookies.txt -X POST "$ZIA/status/activate"
Pagination
# ZIA pagination (page + pageSize)
curl -s -b cookies.txt "$ZIA/users?page=1&pageSize=100"
curl -s -b cookies.txt "$ZIA/users?page=2&pageSize=100"
# Loop through all pages
PAGE=1
```bash
# ZIA pagination (page + pageSize)
curl -s -b cookies.txt "$ZIA/users?page=1&pageSize=100"
curl -s -b cookies.txt "$ZIA/users?page=2&pageSize=100"
# Loop through all pages
PAGE=1
while true; do
RESULT=$(curl -s -b cookies.txt "$ZIA/users?page=$PAGE&pageSize=100")
COUNT=$(echo "$RESULT" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))")
echo "Page $PAGE: $COUNT users"
[[ "$COUNT" -lt 100 ]] && break
((PAGE++))
done
Rate Limits
| Method | Rate Limit | Window |
|---|---|---|
| GET | 2 requests/second | Per session |
| POST / PUT / DELETE | 1 request/second | Per session |
# Respect rate limits with a simple sleep between requests
for id in 1001 1002 1003 1004 1005; do
curl -s -b cookies.txt "$ZIA/users/$id"
sleep 1
done
Error Handling
Common HTTP status codes across Zscaler APIs:
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
204 | Deleted (no content) |
400 | Bad request (check your JSON) |
401 | Unauthorized (expired session/token) |
403 | Forbidden (insufficient permissions) |
404 | Resource not found |
409 | Conflict (duplicate name, etc.) |
429 | Rate limit exceeded |
# Check for errors in response
RESPONSE=$(curl -s -w "\n%{http_code}" -b cookies.txt "$ZIA/users/99999")
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
# ZIA: Always activate after making changes — they won't take effect otherwise
curl -s -b cookies.txt -X POST "$ZIA/status/activate"
# ZIA: Check what's pending before activating
curl -s -b cookies.txt "$ZIA/status"
# Pretty-print any JSON response
curl -s -b cookies.txt "$ZIA/urlCategories" | python3 -m json.tool
# Export all locations to a JSON file
curl -s -b cookies.txt "$ZIA/locations" | python3 -m json.tool > locations.json
