A modern, typed, and intuitive interface to the Netskope REST API v2. Auto-pagination, retries, and rich models — so you can focus on security, not HTTP plumbing.
pip install netskope-py-sdkEvery design decision optimized for discoverability, safety, and minimal surprise.
Navigate the entire API through autocomplete: client.alerts.list(), client.scim.users.create()
Just iterate. No page loops, no offset math. Works across all list endpoints with lazy fetching.
Pydantic v2 models for every response. Full py.typed support for mypy and pyright.
Exponential backoff with jitter. Respects Retry-After headers. Configurable per client.
Choose NetskopeClient for scripts or AsyncNetskopeClient for high-throughput.
Specific exception types with request IDs. Catch RateLimitError, NotFoundError precisely.
pip install netskope-py-sdkThe SDK has only two dependencies: httpx and pydantic. Python 3.11 or newer is required.
# Clone and install with test dependencies
git clone https://github.com/netSkopeoss/netskope-py-sdk.git
cd netskope-py-sdk
pip install -e ".[dev]"import netskope
print(netskope.__version__) # "1.0.3"from netskope import NetskopeClient
# Initialize — reads NETSKOPE_TENANT and NETSKOPE_API_TOKEN env vars
client = NetskopeClient()
# Or pass credentials explicitly
client = NetskopeClient(
tenant="mycompany.goskope.com",
api_token="your-v2-api-token",
)
# List alerts — pagination is completely automatic
for alert in client.alerts.list():
print(f"{alert.alert_name} — {alert.user} — {alert.app}")
# Query network events with JQL filtering
for event in client.events.list("application", page_size=50):
print(f"{event.user} → {event.app} ({event.activity})")
# Manage URL allow/block lists
blocklist = client.url_lists.create("threat-iocs", ["malware.example.com"])
client.url_lists.deploy()
# List publishers and their status
for pub in client.publishers.list():
print(f"{pub.publisher_name}: {pub.status} ({pub.apps_count} apps)")
# SCIM user provisioning
for user in client.scim.users.list():
print(f"{user.user_name} active={user.active}")
# Always close when done (or use context manager)
client.close()with NetskopeClient(tenant="mycompany.goskope.com", api_token="...") as client:
alerts = client.alerts.list().to_list(max_items=100)
print(f"Found {len(alerts)} alerts")
# Connection pool automatically closedfrom netskope import NetskopeClient
from datetime import datetime, timedelta
client = NetskopeClient()
end = datetime.now()
start = end - timedelta(hours=1)
# Stream all event types from the last hour
for event_type in ["application", "network", "page", "alert"]:
for event in client.events.list(event_type, start_time=start, end_time=end):
send_to_siem(event.model_dump(exclude_none=True))
client.close()from netskope import NetskopeClient
client = NetskopeClient()
# Get IOCs from your threat intel feed
malicious_urls = fetch_threat_intel() # → ["malware.com", "phish.org", ...]
# Create or update the blocklist
try:
blocklist = client.url_lists.create(
name="auto-threat-intel",
urls=malicious_urls,
list_type="exact",
)
except Exception:
# List already exists — find and update it
for ul in client.url_lists.list():
if ul.name == "auto-threat-intel":
client.url_lists.update(ul.id, urls=malicious_urls)
break
# Deploy immediately
client.url_lists.deploy()
print(f"Blocked {len(malicious_urls)} malicious URLs")from netskope import NetskopeClient
with NetskopeClient() as client:
publishers = client.publishers.list().to_list()
connected = [p for p in publishers if p.status == "connected"]
down = [p for p in publishers if p.status != "connected"]
print(f"Publishers: {len(connected)} connected, {len(down)} down")
for p in down:
print(f" ⚠ {p.publisher_name} is {p.status}")
apps = client.private_apps.list().to_list()
print(f"Private apps: {len(apps)}")from netskope import NetskopeClient
client = NetskopeClient()
# Onboard new employees from HR system
new_hires = [
{"email": "alice@company.com", "name": "Alice Smith"},
{"email": "bob@company.com", "name": "Bob Jones"},
]
for hire in new_hires:
user = client.scim.users.create(
user_name=hire["email"],
email=hire["email"],
display_name=hire["name"],
)
print(f"Provisioned {user.user_name} (id={user.id})")
# Offboard departing employees
for email in departing_employees:
users = client.scim.users.list(
filter_expr=f'userName eq "{email}"'
).to_list()
for user in users:
client.scim.users.update(user.id, active=False)
print(f"Deactivated {user.user_name}")import asyncio
from netskope import AsyncNetskopeClient
async def monitor_all_event_types():
async with AsyncNetskopeClient() as client:
event_types = ["application", "network", "page", "alert"]
# Fetch all event types concurrently
tasks = [
client.events.list(et, page_size=100).to_list(max_items=500)
for et in event_types
]
results = await asyncio.gather(*tasks)
for et, events in zip(event_types, results):
print(f"{et}: {len(events)} events")
asyncio.run(monitor_all_event_types())| Parameter | Type | Default | Description |
|---|---|---|---|
tenant | str | None | NETSKOPE_TENANT | Tenant hostname, e.g. "mycompany.goskope.com". Falls back to the NETSKOPE_TENANT environment variable. |
api_token | str | None | NETSKOPE_API_TOKEN | REST API v2 token from your Netskope admin console. Falls back to the NETSKOPE_API_TOKEN environment variable. |
timeout | float | 30.0 | HTTP request timeout in seconds. |
max_retries | int | 3 | Maximum automatic retries for transient errors (429, 5xx). |
backoff_factor | float | 0.5 | Exponential backoff base multiplier. Sleep = factor * 2^attempt, capped at 60s, plus jitter. |
retry_on_status | frozenset[int] | None | {429,500,502,503,504} | HTTP status codes that trigger automatic retry. |
Credentials resolve in priority order (inspired by boto3):
tenant=, api_token=)NETSKOPE_TENANT, NETSKOPE_API_TOKENIf neither source provides a value, a ValidationError is raised at construction time (fail fast).
# Set credentials via environment
export NETSKOPE_TENANT="mycompany.goskope.com"
export NETSKOPE_API_TOKEN="your-v2-token"
# Then just:
client = NetskopeClient() # reads from env automatically# Manage multiple tenants simultaneously
prod = NetskopeClient(tenant="prod.goskope.com", api_token=prod_token)
staging = NetskopeClient(tenant="staging.goskope.com", api_token=staging_token)
# Compare publisher counts across environments
prod_pubs = prod.publishers.list().to_list()
staging_pubs = staging.publishers.list().to_list()
print(f"Production: {len(prod_pubs)} publishers")
print(f"Staging: {len(staging_pubs)} publishers")client = NetskopeClient(tenant="mycompany.goskope.com", api_token="...")
client.version # "1.0.3"
client.tenant # "mycompany.goskope.com"
client.base_url # "https://mycompany.goskope.com"The AsyncNetskopeClient provides the exact same API as the sync client, but all methods are coroutines and list endpoints return async iterators.
import asyncio
from netskope import AsyncNetskopeClient
async def main():
async with AsyncNetskopeClient(tenant="mycompany.goskope.com", api_token="...") as client:
# Async iteration
async for alert in client.alerts.list(page_size=50):
print(alert.alert_name)
# Async to_list
publishers = await client.publishers.list().to_list(max_items=100)
# Async first
first_alert = await client.alerts.list().first()
# Async page-level access
async for page in client.alerts.list().pages():
print(f"Page: {len(page.items)} items")
# Async CRUD
url_list = await client.url_lists.create("blocklist", ["bad.com"])
await client.url_lists.deploy()
asyncio.run(main())NetskopeClient is also available on AsyncNetskopeClient with the same signature. The only difference is await for single-resource methods and async for for iterators.
client.alerts — Query and retrieve security alerts via /api/v2/events/datasearch/alert
.list() — List Alerts| Parameter | Type | Default | Description |
|---|---|---|---|
query | str | None | None | JQL filter expression, e.g. 'alert_type eq "DLP"' |
fields | list[str] | None | None | Specific fields to return (reduces response size) |
start_time | datetime | int | None | None | Start of time range (datetime object or Unix epoch int) |
end_time | datetime | int | None | None | End of time range |
group_by | str | None | None | Field to aggregate results by |
order_by | str | None | None | Field to sort by |
descending | bool | True | Sort order (True = newest first) |
page_size | int | 100 | Results per API call |
Returns: SyncPaginatedResponse[Alert] — a lazy iterator of Alert objects.
from datetime import datetime, timedelta
# List all alerts (auto-paginated)
for alert in client.alerts.list():
print(f"{alert.alert_name} — {alert.alert_type} — {alert.app}")
# Filter by JQL query
for alert in client.alerts.list(query='alert_type eq "DLP"'):
print(alert.alert_name)
# Time-range query (last 7 days)
alerts = client.alerts.list(
start_time=datetime.now() - timedelta(days=7),
end_time=datetime.now(),
page_size=200,
).to_list(max_items=1000)
print(f"Found {len(alerts)} alerts in the last 7 days")
# Get just the first alert
first = client.alerts.list().first()
# → Alert(alert_name="Password should be changed every 90 days", ...).get(alert_id) — Get Single AlertRetrieve a single alert by its _id. Raises NotFoundError if not found.
from netskope.exceptions import NotFoundError
try:
alert = client.alerts.get("44d8af1bcc1d7bd0fc8aa698")
print(f"Name: {alert.alert_name}")
print(f"Type: {alert.alert_type}")
print(f"App: {alert.app}")
except NotFoundError:
print("Alert not found")| Field | Type | Description |
|---|---|---|
id | str | None | Alert unique identifier (API field: _id) |
alert_name | str | None | Human-readable alert name |
alert_type | str | None | Alert category (DLP, malware, anomaly, Security Assessment, etc.) |
severity | str | None | Severity level (critical, high, medium, low) |
user | str | None | Affected user email |
app | str | None | Application name (e.g. "Workday", "Slack") |
activity | str | None | Activity that triggered the alert |
policy_name | str | None | Policy that generated the alert |
action | str | None | Action taken (alert, block, etc.) |
category | str | None | URL/app category |
cci | int | None | Cloud Confidence Index score |
ccl | str | None | Cloud Confidence Level |
access_method | str | None | How traffic was accessed (Client, API, etc.) |
traffic_type | str | None | Traffic classification |
timestamp | datetime | None | When the alert occurred (auto-parsed from epoch) |
client.events — Query security events across 10 event types via /api/v2/events/datasearch/{type}
.list(event_type, ...) — List EventsSame parameters as alerts.list(), plus the required event_type first argument. Returns type-specific models for network, page, and audit.
from netskope.models.events import EventType
# Application events — SaaS/cloud app access
for event in client.events.list(EventType.APPLICATION, page_size=50):
print(f"{event.user} → {event.app} ({event.activity})")
# → onasr+web@netskope.com → Amazon Systems Manager (View)
# Network events — returns NetworkEvent with src_ip, dst_ip, protocol
for event in client.events.list("network", page_size=20):
print(f"{event.src_ip} → {event.dst_ip} ({event.protocol})")
# Page events — returns PageEvent with url, domain, browser
for event in client.events.list("page"):
print(f"{event.url} — {event.domain}")
# Filter by JQL and time range
from datetime import datetime, timedelta
events = client.events.list(
"application",
query='user eq "alice@example.com"',
start_time=datetime.now() - timedelta(days=1),
end_time=datetime.now(),
).to_list(max_items=500)The SDK automatically returns the right model subclass based on event type:
| Event Type | Model | Extra Fields |
|---|---|---|
"network" | NetworkEvent | src_ip, dst_ip, src_port, dst_port, protocol, num_bytes, domain |
"page" | PageEvent | url, domain, page_id, page_duration, referer, browser, os, device |
"audit" | AuditEvent | audit_log_event, audit_category, supporting_data, organization_unit |
| All others | Event | Base fields: user, app, activity, action, site, category, severity, timestamp, etc. |
client.url_lists — Full CRUD for URL allow/block lists and policy deployment via /api/v2/policy/urllist
# List all URL lists
for url_list in client.url_lists.list():
print(f"[{url_list.id}] {url_list.name}: {len(url_list.urls)} URLs ({url_list.type})")
# → [1] Exceptions to prohibited sites: 5 URLs (exact)
# → [3] YouTube Allowed: 2 URLs (exact)
# → [5] malwareDomains: 26874 URLs (exact)
# Get a specific URL list by ID
url_list = client.url_lists.get(1)
# Create a new URL list
new_list = client.url_lists.create(
name="threat-intel-iocs",
urls=["malware.example.com", "phishing.bad.org"],
list_type="exact", # or "regex"
)
print(f"Created: id={new_list.id}, name={new_list.name}")
# Update — add more URLs
updated = client.url_lists.update(
new_list.id,
urls=["malware.example.com", "phishing.bad.org", "new-threat.evil.net"],
)
# Deploy all pending policy changes (required after create/update/delete)
client.url_lists.deploy()
# Delete
client.url_lists.delete(new_list.id)
client.url_lists.deploy()client.url_lists.deploy(). This matches the Netskope admin console behavior — create, update, or delete, then deploy all changes at once.
| Field | Type | Description |
|---|---|---|
id | int | None | Numeric identifier |
name | str | None | Human-readable name |
type | str | None | Matching strategy: "exact" or "regex" |
urls | list[str] | The URL entries |
pending | bool | None | Whether changes await deployment |
modify_by | str | None | Last modified by (admin email) |
client.publishers — Manage private-access gateway publishers via /api/v2/infrastructure/publishers
# List all publishers
for pub in client.publishers.list():
print(f"{pub.publisher_name}: {pub.status} ({pub.apps_count} apps)")
# → flonkerton-sedemo-publisher: connected (6 apps)
# → NPA-Unified-Pub-US-EAST-1: connected (18 apps)
# → NPA-Unified-Pub-US-WEST-1: connected (7 apps)
# Get by ID
pub = client.publishers.get(109)
print(f"{pub.publisher_name} — registered={pub.registered}")
# Create a new publisher
new_pub = client.publishers.create(name="aws-us-east-1-publisher")
# Update
client.publishers.update(new_pub.publisher_id, name="aws-us-east-1-primary")
# Delete
client.publishers.delete(new_pub.publisher_id)| Field | Type | Description |
|---|---|---|
publisher_id | int | None | Numeric identifier |
publisher_name | str | None | Human-readable name |
status | str | None | "connected" or "not_connected" |
apps_count | int | None | Number of apps assigned to this publisher |
registered | bool | None | Registration status |
sticky_ip_enabled | bool | None | Whether sticky IP is enabled |
client.private_apps — Manage zero-trust private applications via /api/v2/steering/apps/private
# List all private apps
for app in client.private_apps.list():
print(f"{app.app_name} → {app.host}:{app.port}")
# → [Portal Test] → npaportal.mynetskopedemo.com:443
# → [Finance MyNetskopeDemo] → finance.mynetskopedemo.com:443
# Get by ID
app = client.private_apps.get(110)
# Create a new private app
app = client.private_apps.create(
name="internal-dashboard",
host="10.0.0.5",
port="443",
protocols=["TCP"],
publisher_ids=[109, 126],
)
# Update
client.private_apps.update(app.app_id, app_name="internal-dashboard-v2")
# Delete
client.private_apps.delete(app.app_id)| Field | Type | Description |
|---|---|---|
app_id | int | None | Numeric identifier |
app_name | str | None | Application display name |
host | str | None | Target host (IP or hostname) |
port | str | None | Target port(s) |
protocols | list | None | Protocol configuration |
publishers | list[dict] | None | Assigned publishers |
use_publisher_dns | bool | None | Use publisher DNS resolution |
clientless_access | bool | None | Browser-based access enabled |
client.scim — SCIM 2.0 user and group provisioning via /api/v2/scim/Users and /api/v2/scim/Groups
client.scim.users# List all SCIM users
for user in client.scim.users.list():
print(f"{user.user_name} active={user.active} display={user.display_name}")
# Filter users with SCIM filter syntax
admins = client.scim.users.list(
filter_expr='userName co "admin"',
).to_list()
# Get a specific user
user = client.scim.users.get("user-uuid-here")
# Create a new user
user = client.scim.users.create(
user_name="alice@company.com",
email="alice@company.com",
display_name="Alice Smith",
given_name="Alice",
family_name="Smith",
active=True,
)
print(f"Created user: {user.id}")
# Update (PATCH) — only send changed fields
client.scim.users.update(user.id, active=False)
# Delete
client.scim.users.delete(user.id)client.scim.groups# List all groups
for group in client.scim.groups.list():
print(f"{group.display_name}: {len(group.members)} members")
# Create a group with members
group = client.scim.groups.create(
display_name="Engineering",
member_ids=["user-id-1", "user-id-2"],
)
# Update group (PUT — full replacement)
client.scim.groups.update(group.id, display_name="Platform Engineering")
# Delete
client.scim.groups.delete(group.id)| Field | Type | Description |
|---|---|---|
id | str | None | SCIM unique identifier |
user_name | str | None | Username (typically email) |
display_name | str | None | Display name |
active | bool | None | Account status |
emails | list[ScimEmail] | Email addresses (each has value, primary, type) |
groups | list[dict] | Group memberships |
client.incidents — View incidents, update status, get risk scores, DLP forensics, and UBA anomalies
# List incidents with JQL filtering
for incident in client.incidents.list(query='severity eq "critical"'):
print(f"{incident.incident_id} — {incident.severity} — {incident.status}")
# Update an incident (with optimistic locking)
client.incidents.update(
incident_id="INC-001",
field="status",
old_value="open",
new_value="in_progress",
user="analyst@company.com",
)
# Get User Confidence Index (risk score)
uci = client.incidents.get_uci("bob@company.com")
print(f"Risk score: {uci.score}, severity: {uci.severity}")
# Get UBA anomalies for specific users
anomalies = client.incidents.get_anomalies(
users=["bob@company.com", "alice@company.com"],
timeframe=30, # days
severity="high",
)
for a in anomalies:
print(f"{a.user}: {a.anomaly_type} — {a.risk_level}")
# Get DLP forensics for an incident
forensics = client.incidents.get_forensics("dlp-incident-id")client.steering — Steering configuration, PoPs, and IPSec tunnels
# Get NPA steering configuration
config = client.steering.get_config("npa")
print(config.data)
# Update steering configuration
client.steering.update_config("npa", some_setting="value")
# List Points of Presence (PoPs)
for pop in client.steering.list_pops():
print(f"{pop.name} — {pop.region} ({pop.country})")
# List IPSec tunnels
for tunnel in client.steering.list_tunnels():
print(f"{tunnel.name}: {tunnel.status}")
# Get specific tunnel
tunnel = client.steering.get_tunnel(42)Every .list() method returns a SyncPaginatedResponse (or AsyncPaginatedResponse) that handles pagination transparently. You never write page loops.
Pages are fetched on demand as you iterate. Memory-efficient for large result sets.
# Fetches pages automatically as needed
for alert in client.alerts.list(page_size=100):
process(alert) # Each alert is a typed Alert objectUse .pages() when you need page metadata (total count, page size).
for page in client.alerts.list(page_size=50).pages():
print(f"Page at offset {page.offset}: {len(page.items)} items (total={page.total})")
for alert in page.items:
process(alert).to_list())Fetch everything into a list. Always specify max_items as a safety limit.
# Collect up to 5000 alerts
all_alerts = client.alerts.list().to_list(max_items=5000)
print(f"Got {len(all_alerts)} alerts").first())Fetch just the first result without iterating further. Returns None for empty results.
latest = client.alerts.list(order_by="timestamp").first()
if latest:
print(f"Latest: {latest.alert_name}")
else:
print("No alerts found")| Field | Type | Description |
|---|---|---|
items | list[T] | Model instances on this page |
total | int | None | Total items across all pages (if provided by API) |
offset | int | Offset used for this page |
limit | int | Page size |
NetskopeError # Base — catch everything
├── APIError # Any non-2xx HTTP response
│ ├── AuthenticationError # 401 — invalid or expired token
│ ├── ForbiddenError # 403 — token lacks required scope
│ ├── NotFoundError # 404 — resource does not exist
│ ├── ConflictError # 409 — duplicate resource
│ ├── RateLimitError # 429 — rate limit exceeded (.retry_after available)
│ └── ServerError # 5xx — Netskope server-side failure
├── ValidationError # Bad input caught before sending request
├── ConnectionError # Network-level failure
└── TimeoutError # Request timeout exceededAll API errors carry rich context for debugging and support escalation:
| Attribute | Type | Description |
|---|---|---|
status_code | int | HTTP status code (e.g. 401, 404, 429) |
request_id | str | None | Server-assigned request ID — use this for Netskope support tickets |
message | str | Human-readable error message |
body | dict | None | Parsed JSON response body |
from netskope.exceptions import (
NetskopeError,
AuthenticationError,
ForbiddenError,
NotFoundError,
RateLimitError,
ServerError,
)
try:
alert = client.alerts.get("nonexistent-id")
except NotFoundError as e:
print(f"Not found: {e.message}")
print(f"Request ID: {e.request_id}") # for support escalation
except AuthenticationError:
print("Token is invalid or expired — check NETSKOPE_API_TOKEN")
except ForbiddenError:
print("Token lacks the required scope for this endpoint")
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after} seconds")
except ServerError as e:
print(f"Netskope server error ({e.status_code}): {e.message}")
except NetskopeError as e:
print(f"SDK error: {e}") # catch-all for any SDK errorfrom netskope.exceptions import APIError
try:
result = client.publishers.create(name="test")
except APIError as e:
print(f"API returned HTTP {e.status_code}: {e.message}")
if e.request_id:
print(f"Include this in support tickets: {e.request_id}")The SDK automatically retries transient failures with exponential backoff and jitter. No configuration required for sensible defaults.
429, 500, 502, 503, 5040.5 * 2^attempt (capped at 60s) + random jitterRetry-After headers from the server# Aggressive retry for batch jobs
client = NetskopeClient(
tenant="mycompany.goskope.com",
api_token="...",
max_retries=5,
backoff_factor=1.0, # longer waits: 1s, 2s, 4s, 8s, 16s
timeout=60.0, # longer timeout for slow queries
)
# No retries (fail fast)
client = NetskopeClient(
tenant="mycompany.goskope.com",
api_token="...",
max_retries=0,
)The SDK uses Python's standard logging module under the "netskope" logger. Tokens are never logged.
import logging
# See request/response at INFO level
logging.getLogger("netskope").setLevel(logging.INFO)
# → ← GET https://mycompany.goskope.com/api/v2/events/datasearch/alert → 200 (request_id=abc123)
# Full debug output (request URLs, retry decisions)
logging.getLogger("netskope").setLevel(logging.DEBUG)
# → → GET /api/v2/events/datasearch/alert
# → Netskope API returned 429, retrying in 1.2s (attempt 1/3)
# Silence the SDK entirely
logging.getLogger("netskope").setLevel(logging.CRITICAL)Netskope's JSON Query Language (JQL) is used in alerts.list(query=...), events.list(query=...), and incidents.list(query=...) to filter results server-side.
| Operator | Meaning | Example |
|---|---|---|
eq | Equals | severity eq "high" |
ne | Not equals | alert_type ne "policy" |
gt / lt | Greater/less than | timestamp gt 1709913600 |
ge / le | Greater/less or equal | cci ge 50 |
in | In list | activity in ("Upload", "Download") |
contains | Substring match | alert_name contains "DLP" |
AND / OR | Logical operators | severity eq "high" AND app eq "Slack" |
# Simple equality
client.alerts.list(query='alert_type eq "DLP"')
# Compound query
client.alerts.list(query='severity eq "high" AND app eq "Slack"')
# User-specific events
client.events.list("application", query='user eq "alice@company.com"')
# Activity filter
client.events.list("application", query='activity in ("Upload", "Download", "Delete")')All response models are Pydantic v2 objects with full serialization support. They are frozen (immutable) and forward-compatible (unknown API fields are silently ignored, so new fields added by the API won't break existing code).
alert = client.alerts.list().first()
# Access fields with dot notation
alert.alert_name # "Sensitive data should be masked in output"
alert.app # "Workday"
alert.alert_type # "Security Assessment"
# Serialize to dict
d = alert.model_dump()
# → {'id': '44d8af1b...', 'alert_name': 'Sensitive data...', 'app': 'Workday', ...}
# Serialize to JSON string
json_str = alert.model_dump_json()
# → '{"id": "44d8af1b...", "alert_name": "Sensitive data...", ...}'
# Exclude None fields
clean = alert.model_dump(exclude_none=True)
# Import models directly for type annotations
from netskope.models import Alert, Publisher, UrlList, ScimUser
def process_alert(alert: Alert) -> None:
print(f"{alert.alert_name} — {alert.severity}")Alert — Security alertsEvent — Generic eventsNetworkEvent — Network-layer eventsPageEvent — Web page eventsAuditEvent — Audit trail eventsIncident — Security incidentsAnomaly — UBA anomaliesUserConfidenceIndex — UCI risk scoresPublisher — Private access publishersPrivateApp — ZTNA applicationsUrlList — URL allow/block listsScimUser — SCIM usersScimGroup — SCIM groupsPop — Points of PresenceIPSecTunnel — VPN tunnelsSteeringConfig — Steering configfrom netskope.models.alerts import AlertSeverity, AlertType
from netskope.models.events import EventType
from netskope.models.incidents import IncidentStatus
from netskope.models.publishers import PublisherStatus
from netskope.models.url_lists import UrlListType
AlertSeverity.CRITICAL # "critical"
AlertSeverity.HIGH # "high"
EventType.NETWORK # "network"
EventType.APPLICATION # "application"
IncidentStatus.OPEN # "open"
PublisherStatus.CONNECTED # "connected"
UrlListType.EXACT # "exact"
UrlListType.REGEX # "regex"Every resource namespace and its methods at a glance:
| Namespace | Methods | API Endpoint |
|---|---|---|
client.alerts | list(), get(id) | /api/v2/events/datasearch/alert |
client.events | list(type) | /api/v2/events/datasearch/{type} |
client.url_lists | list(), get(), create(), update(), delete(), deploy() | /api/v2/policy/urllist |
client.publishers | list(), get(), create(), update(), delete() | /api/v2/infrastructure/publishers |
client.private_apps | list(), get(), create(), update(), delete() | /api/v2/steering/apps/private |
client.scim.users | list(), get(), create(), update(), delete() | /api/v2/scim/Users |
client.scim.groups | list(), get(), create(), update(), delete() | /api/v2/scim/Groups |
client.incidents | list(), update(), get_uci(), get_anomalies(), get_forensics() | /api/v2/events/datasearch/incident |
client.steering | get_config(), update_config(), list_pops(), list_tunnels(), get_tunnel() | /api/v2/steering/* |