Python 3.11+ • Typed • Sync + Async • Pydantic v2

The Netskope
Python SDK

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-sdk
Get Started →

Built for Developers & AI Agents

Every design decision optimized for discoverability, safety, and minimal surprise.

NS

Hierarchical Namespaces

Navigate the entire API through autocomplete: client.alerts.list(), client.scim.users.create()

AP

Automatic Pagination

Just iterate. No page loops, no offset math. Works across all list endpoints with lazy fetching.

TS

Full Type Safety

Pydantic v2 models for every response. Full py.typed support for mypy and pyright.

RT

Automatic Retries

Exponential backoff with jitter. Respects Retry-After headers. Configurable per client.

SA

Sync + Async

Choose NetskopeClient for scripts or AsyncNetskopeClient for high-throughput.

EX

Rich Exceptions

Specific exception types with request IDs. Catch RateLimitError, NotFoundError precisely.

Documentation

Installation

pip install netskope-py-sdk

The SDK has only two dependencies: httpx and pydantic. Python 3.11 or newer is required.

Development Installation

# Clone and install with test dependencies git clone https://github.com/netSkopeoss/netskope-py-sdk.git cd netskope-py-sdk pip install -e ".[dev]"

Verify Installation

import netskope print(netskope.__version__) # "1.0.3"

Quick Start

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()

Context Manager (Recommended)

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 closed

Real-World Examples

SIEM Integration — Ship Events to Splunk/Sentinel

from 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()

Automated Threat Response — Block IOCs from Feed

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")

Infrastructure Health Check

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)}")

User Lifecycle Automation

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}")

High-Throughput Async Processing

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())

Configuration

NetskopeClient Constructor

ParameterTypeDefaultDescription
tenantstr | NoneNETSKOPE_TENANTTenant hostname, e.g. "mycompany.goskope.com". Falls back to the NETSKOPE_TENANT environment variable.
api_tokenstr | NoneNETSKOPE_API_TOKENREST API v2 token from your Netskope admin console. Falls back to the NETSKOPE_API_TOKEN environment variable.
timeoutfloat30.0HTTP request timeout in seconds.
max_retriesint3Maximum automatic retries for transient errors (429, 5xx).
backoff_factorfloat0.5Exponential backoff base multiplier. Sleep = factor * 2^attempt, capped at 60s, plus jitter.
retry_on_statusfrozenset[int] | None{429,500,502,503,504}HTTP status codes that trigger automatic retry.

Credential Resolution Chain

Credentials resolve in priority order (inspired by boto3):

1Explicit constructor parameters (tenant=, api_token=)
2Environment variables: NETSKOPE_TENANT, NETSKOPE_API_TOKEN

If neither source provides a value, a ValidationError is raised at construction time (fail fast).

Environment Variables

# 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

Multiple Tenants

# 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 Properties

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"

Async Usage

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())
Note: Every method available on NetskopeClient is also available on AsyncNetskopeClient with the same signature. The only difference is await for single-resource methods and async for for iterators.

Alerts

client.alerts — Query and retrieve security alerts via /api/v2/events/datasearch/alert

.list() — List Alerts

ParameterTypeDefaultDescription
querystr | NoneNoneJQL filter expression, e.g. 'alert_type eq "DLP"'
fieldslist[str] | NoneNoneSpecific fields to return (reduces response size)
start_timedatetime | int | NoneNoneStart of time range (datetime object or Unix epoch int)
end_timedatetime | int | NoneNoneEnd of time range
group_bystr | NoneNoneField to aggregate results by
order_bystr | NoneNoneField to sort by
descendingboolTrueSort order (True = newest first)
page_sizeint100Results 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 Alert

Retrieve 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")

Alert Model Fields

FieldTypeDescription
idstr | NoneAlert unique identifier (API field: _id)
alert_namestr | NoneHuman-readable alert name
alert_typestr | NoneAlert category (DLP, malware, anomaly, Security Assessment, etc.)
severitystr | NoneSeverity level (critical, high, medium, low)
userstr | NoneAffected user email
appstr | NoneApplication name (e.g. "Workday", "Slack")
activitystr | NoneActivity that triggered the alert
policy_namestr | NonePolicy that generated the alert
actionstr | NoneAction taken (alert, block, etc.)
categorystr | NoneURL/app category
cciint | NoneCloud Confidence Index score
cclstr | NoneCloud Confidence Level
access_methodstr | NoneHow traffic was accessed (Client, API, etc.)
traffic_typestr | NoneTraffic classification
timestampdatetime | NoneWhen the alert occurred (auto-parsed from epoch)

Events

client.events — Query security events across 10 event types via /api/v2/events/datasearch/{type}

Supported Event Types

application
network
page
alert
incident
audit
infrastructure
clientstatus
epdlp
transaction

.list(event_type, ...) — List Events

Same 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)

Type-Specific Models

The SDK automatically returns the right model subclass based on event type:

Event TypeModelExtra Fields
"network"NetworkEventsrc_ip, dst_ip, src_port, dst_port, protocol, num_bytes, domain
"page"PageEventurl, domain, page_id, page_duration, referer, browser, os, device
"audit"AuditEventaudit_log_event, audit_category, supporting_data, organization_unit
All othersEventBase fields: user, app, activity, action, site, category, severity, timestamp, etc.

URL Lists

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()
Important: Changes to URL lists are staged until you call client.url_lists.deploy(). This matches the Netskope admin console behavior — create, update, or delete, then deploy all changes at once.

UrlList Model Fields

FieldTypeDescription
idint | NoneNumeric identifier
namestr | NoneHuman-readable name
typestr | NoneMatching strategy: "exact" or "regex"
urlslist[str]The URL entries
pendingbool | NoneWhether changes await deployment
modify_bystr | NoneLast modified by (admin email)

Publishers

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)

Publisher Model Fields

FieldTypeDescription
publisher_idint | NoneNumeric identifier
publisher_namestr | NoneHuman-readable name
statusstr | None"connected" or "not_connected"
apps_countint | NoneNumber of apps assigned to this publisher
registeredbool | NoneRegistration status
sticky_ip_enabledbool | NoneWhether sticky IP is enabled

Private Apps (ZTNA)

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)

PrivateApp Model Fields

FieldTypeDescription
app_idint | NoneNumeric identifier
app_namestr | NoneApplication display name
hoststr | NoneTarget host (IP or hostname)
portstr | NoneTarget port(s)
protocolslist | NoneProtocol configuration
publisherslist[dict] | NoneAssigned publishers
use_publisher_dnsbool | NoneUse publisher DNS resolution
clientless_accessbool | NoneBrowser-based access enabled

SCIM Users & Groups

client.scim — SCIM 2.0 user and group provisioning via /api/v2/scim/Users and /api/v2/scim/Groups

Users — 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)

Groups — 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)

ScimUser Model Fields

FieldTypeDescription
idstr | NoneSCIM unique identifier
user_namestr | NoneUsername (typically email)
display_namestr | NoneDisplay name
activebool | NoneAccount status
emailslist[ScimEmail]Email addresses (each has value, primary, type)
groupslist[dict]Group memberships

Incidents

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")

Steering & Infrastructure

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)

Pagination

Every .list() method returns a SyncPaginatedResponse (or AsyncPaginatedResponse) that handles pagination transparently. You never write page loops.

Iterate Items (Lazy)

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 object

Page-Level Access

Use .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)

Collect All (.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")

Get First (.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")

Page Object Fields

FieldTypeDescription
itemslist[T]Model instances on this page
totalint | NoneTotal items across all pages (if provided by API)
offsetintOffset used for this page
limitintPage size

Error Handling

Exception Hierarchy

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 exceeded

APIError Attributes

All API errors carry rich context for debugging and support escalation:

AttributeTypeDescription
status_codeintHTTP status code (e.g. 401, 404, 429)
request_idstr | NoneServer-assigned request ID — use this for Netskope support tickets
messagestrHuman-readable error message
bodydict | NoneParsed JSON response body

Catching Specific Errors

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 error

Catching All API Errors

from 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}")

Retries & Backoff

The SDK automatically retries transient failures with exponential backoff and jitter. No configuration required for sensible defaults.

Default Behavior

Custom Configuration

# 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, )

Logging

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)

JQL Query Syntax

Netskope's JSON Query Language (JQL) is used in alerts.list(query=...), events.list(query=...), and incidents.list(query=...) to filter results server-side.

Operators

OperatorMeaningExample
eqEqualsseverity eq "high"
neNot equalsalert_type ne "policy"
gt / ltGreater/less thantimestamp gt 1709913600
ge / leGreater/less or equalcci ge 50
inIn listactivity in ("Upload", "Download")
containsSubstring matchalert_name contains "DLP"
AND / ORLogical operatorsseverity eq "high" AND app eq "Slack"

Examples

# 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")')

Model Serialization

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}")

All Available Models

Security

  • Alert — Security alerts
  • Event — Generic events
  • NetworkEvent — Network-layer events
  • PageEvent — Web page events
  • AuditEvent — Audit trail events
  • Incident — Security incidents
  • Anomaly — UBA anomalies
  • UserConfidenceIndex — UCI risk scores

Infrastructure & Identity

  • Publisher — Private access publishers
  • PrivateApp — ZTNA applications
  • UrlList — URL allow/block lists
  • ScimUser — SCIM users
  • ScimGroup — SCIM groups
  • Pop — Points of Presence
  • IPSecTunnel — VPN tunnels
  • SteeringConfig — Steering config

Enums

from 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"

Complete API Map

Every resource namespace and its methods at a glance:

NamespaceMethodsAPI Endpoint
client.alertslist(), get(id)/api/v2/events/datasearch/alert
client.eventslist(type)/api/v2/events/datasearch/{type}
client.url_listslist(), get(), create(), update(), delete(), deploy()/api/v2/policy/urllist
client.publisherslist(), get(), create(), update(), delete()/api/v2/infrastructure/publishers
client.private_appslist(), get(), create(), update(), delete()/api/v2/steering/apps/private
client.scim.userslist(), get(), create(), update(), delete()/api/v2/scim/Users
client.scim.groupslist(), get(), create(), update(), delete()/api/v2/scim/Groups
client.incidentslist(), update(), get_uci(), get_anomalies(), get_forensics()/api/v2/events/datasearch/incident
client.steeringget_config(), update_config(), list_pops(), list_tunnels(), get_tunnel()/api/v2/steering/*