Summary and recommendation
Netskope REST API v2 exposes user lifecycle operations via a SCIM 2.0 endpoint at https://<tenant>.goskope.com/api/v2/scim. Authentication uses a static Bearer token passed via the Netskope-Api-Token header; no OAuth 2.0 flow is documented.
Two distinct token types exist and are not interchangeable: REST API v2 tokens (generated under Settings > Tools > REST API v2) cover data and event endpoints, while SCIM tokens (generated under Settings > Security Cloud Platform > SCIM) cover provisioning operations. Presenting the wrong token type returns a 403 without a descriptive error.
The identity graph in Netskope is anchored to the username field (email address) as the human-readable identifier, but all SCIM operations against individual resources require the internal id field - a Netskope-assigned SCIM UUID that is not the email.
Callers must resolve username to id via GET /Users?filter=userName eq "user@example.com" before issuing PUT, PATCH, or DELETE against a specific user. The groups array on the user object reflects group membership, which propagates to policy enforcement asynchronously - allow for propagation lag before asserting policy state in automated workflows.
Pagination is inconsistent across the API surface: SCIM endpoints use SCIM 2.0 startIndex/count parameters, while the audit events endpoint uses skip/limit. Mixing parameter styles across endpoint types will produce silent failures or empty result sets.
API quick reference
| Has user API | Yes |
| Auth method | API Token (Bearer token passed via Authorization header or v1 token query param; no OAuth 2.0 named in official docs) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Included (all plans; SSO/IdP integration is a prerequisite) |
Authentication
Auth method: API Token (Bearer token passed via Authorization header or v1 token query param; no OAuth 2.0 named in official docs)
Setup steps
- Log in to the Netskope tenant admin console.
- Navigate to Settings > Tools > REST API v2.
- Click 'New Token', assign a name, select required endpoint scopes, and set an expiry.
- Copy the generated token; it is shown only once.
- Pass the token in the Authorization header: 'Netskope-Api-Token:
' for v2 endpoints.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| infrastructure | Access to infrastructure-related endpoints. | General tenant infrastructure queries |
| user_data | Read/write access to user-related data and user management endpoints. | Listing, creating, updating, and deleting users via REST API |
| scim | Enables SCIM 2.0 provisioning operations. | SCIM user and group provisioning from an IdP |
| events | Access to event and alert data streams. | Pulling audit/event logs related to user activity |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| username | string | User's email address used as the unique identifier. | required | immutable | Must match the IdP identity. |
| user_id | string | Internal Netskope unique user ID. | system-generated | read-only | Used as path parameter in user-specific API calls. |
| first_name | string | User's first name. | optional | optional | Populated via SCIM or directory sync. |
| last_name | string | User's last name. | optional | optional | |
| string | Primary email; typically same as username. | required | optional | ||
| groups | array[string] | List of group names the user belongs to. | optional | optional | Used for policy assignment. |
| profile | string | User profile/role assigned within Netskope. | optional | optional | |
| status | string | Account status: active, inactive. | optional | optional | Deprovisioning sets status to inactive. |
| created_at | timestamp | ISO 8601 timestamp of user creation. | system-generated | read-only | |
| last_modified | timestamp | ISO 8601 timestamp of last modification. | system-generated | system-generated | |
| department | string | User's department, synced from IdP or directory. | optional | optional | Used in policy conditions. |
| location | string | User's geographic location attribute. | optional | optional |
Core endpoints
List Users
- Method: GET
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users - Watch out for: Uses SCIM-style pagination (startIndex/count), not skip/limit used in other v2 endpoints.
Request example
GET /api/v2/scim/Users?startIndex=1&count=100
Authorization: Netskope-Api-Token <token>
Response example
{
"totalResults": 250,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [{"id":"uid-123","userName":"alice@corp.com"}]
}
Get User by ID
- Method: GET
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users/{id} - Watch out for: ID is the Netskope internal SCIM id, not the email address.
Request example
GET /api/v2/scim/Users/uid-123
Authorization: Netskope-Api-Token <token>
Response example
{
"id": "uid-123",
"userName": "alice@corp.com",
"active": true,
"groups": [{"value":"grp-1","display":"Engineering"}]
}
Create User
- Method: POST
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users - Watch out for: User must not already exist; duplicate userName returns 409 Conflict.
Request example
POST /api/v2/scim/Users
Content-Type: application/json
{
"userName": "bob@corp.com",
"name": {"givenName":"Bob","familyName":"Smith"},
"active": true
}
Response example
{
"id": "uid-456",
"userName": "bob@corp.com",
"active": true
}
Update User (full replace)
- Method: PUT
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users/{id} - Watch out for: PUT replaces the full resource; omitting fields may clear them. Use PATCH for partial updates.
Request example
PUT /api/v2/scim/Users/uid-456
Content-Type: application/json
{
"userName": "bob@corp.com",
"active": false
}
Response example
{
"id": "uid-456",
"userName": "bob@corp.com",
"active": false
}
Update User (partial)
- Method: PATCH
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users/{id} - Watch out for: Follows SCIM 2.0 patch syntax (RFC 7644). Not all attributes support patch operations.
Request example
PATCH /api/v2/scim/Users/uid-456
{
"Operations": [{"op":"replace","path":"active","value":false}]
}
Response example
{
"id": "uid-456",
"active": false
}
Delete (Deprovision) User
- Method: DELETE
- URL:
https://<tenant>.goskope.com/api/v2/scim/Users/{id} - Watch out for: Deleting a user removes them from Netskope; this does not revoke IdP sessions. Consider deactivating (active=false) instead of deleting for audit trail retention.
Request example
DELETE /api/v2/scim/Users/uid-456
Authorization: Netskope-Api-Token <token>
Response example
HTTP 204 No Content
List Groups
- Method: GET
- URL:
https://<tenant>.goskope.com/api/v2/scim/Groups - Watch out for: Group membership changes propagate to policy enforcement asynchronously; allow up to a few minutes.
Request example
GET /api/v2/scim/Groups?startIndex=1&count=50
Authorization: Netskope-Api-Token <token>
Response example
{
"totalResults": 10,
"Resources": [{"id":"grp-1","displayName":"Engineering"}]
}
Get Audit Events (User Activity)
- Method: GET
- URL:
https://<tenant>.goskope.com/api/v2/events/data/audit - Watch out for: Audit endpoint uses skip/limit pagination, not SCIM startIndex/count. Token must have 'events' scope.
Request example
GET /api/v2/events/data/audit?limit=100&skip=0
Authorization: Netskope-Api-Token <token>
Response example
{
"ok": 1,
"data": [{"timestamp":1700000000,"user":"alice@corp.com","action":"login"}]
}
Rate limits, pagination, and events
- Rate limits: Netskope enforces per-token rate limits on REST API v2. Official docs note limits but do not publish exact per-plan numbers publicly. Commonly observed: 300 requests/minute per token for most endpoints.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when the limit is exceeded. Official docs recommend exponential backoff. Exact header names (e.g., X-RateLimit-Remaining) are not fully documented publicly.
- Pagination method: offset
- Default page size: 100
- Max page size: 5000
- Pagination pointer: skip / limit
| Plan | Limit | Concurrent |
|---|---|---|
| All plans (per token) | ~300 requests/minute (observed; not officially published) | 0 |
- Webhooks available: No
- Webhook notes: Netskope does not expose a native outbound webhook system for user lifecycle events as of the latest official documentation.
- Alternative event strategy: Use the REST API v2 events/audit endpoints with polling, or configure Netskope's Cloud Exchange (CE) platform to forward events to SIEM/SOAR systems via connectors.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Included (all plans; SSO/IdP integration is a prerequisite)
Endpoint: https://
.goskope.com/api/v2/scim Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, GET /Groups/{id}, POST /Groups, PUT /Groups/{id}, PATCH /Groups/{id}, DELETE /Groups/{id}
Limitations:
- SSO must be configured before SCIM provisioning can be enabled.
- SCIM token is separate from the general REST API v2 token; generated under Settings > Security Cloud Platform > SCIM.
- Supported IdPs with documented integration: Okta, Azure AD (Entra ID). Other IdPs may work but are not officially documented.
- Bulk provisioning operations are not supported; resources must be created individually.
- Custom SCIM schema extensions are not documented as supported.
- Group membership propagation to policies is asynchronous.
Common scenarios
Three integration patterns cover the primary lifecycle operations against Netskope's API.
For IdP-driven provisioning (Okta or Entra ID), the canonical path is SCIM 2.0: configure SSO first, generate a SCIM token, set the SCIM base URL to https://
For programmatic deprovisioning, prefer PATCH /api/v2/scim/Users/{id} with active=false over DELETE. DELETE is irreversible and removes the user record from Netskope entirely; PATCH deactivation preserves audit history and incident records referencing that user. The PATCH body must follow SCIM 2.0 RFC 7644 patch syntax: {"Operations":[{"op":"replace","path":"active","value":false}]}.
For audit and compliance pulls, use GET /api/v2/events/data/audit with a token scoped to events. Paginate via skip/limit (not startIndex/count). Filter by the user field to isolate per-user activity. This endpoint requires a REST API v2 token, not a SCIM token.
Provision a new user via SCIM from Okta
- Configure SSO (SAML) between Okta and Netskope tenant.
- In Netskope admin console, navigate to Settings > Security Cloud Platform > SCIM and generate a SCIM token.
- In Okta, add the Netskope app from the OIN catalog and enter the SCIM base URL (https://
.goskope.com/api/v2/scim) and the SCIM token. - Enable provisioning features in Okta: Push New Users, Push Profile Updates, Push Groups.
- Assign the Okta app to a user or group; Okta sends POST /Users to Netskope SCIM endpoint.
- Verify user appears in Netskope admin console under Users.
Watch out for: SSO must be active before SCIM provisioning works. If SSO is not configured, SCIM calls will fail silently or return errors.
Deprovision a user when they leave the organization
- Unassign the user from the Netskope app in the IdP (Okta/Entra).
- IdP sends PATCH /Users/{id} with active=false (or DELETE depending on IdP config) to Netskope SCIM endpoint.
- Alternatively, call PATCH /api/v2/scim/Users/{id} directly with {"Operations":[{"op":"replace","path":"active","value":false}]}.
- Confirm user status is inactive in Netskope admin console.
- Netskope will block the user's traffic based on policy enforcement against inactive users.
Watch out for: Prefer PATCH active=false over DELETE to retain audit logs. DELETE is irreversible and removes the user record.
Audit user login activity via REST API
- Generate a REST API v2 token with the 'events' scope in Netskope admin console.
- Call GET /api/v2/events/data/audit?limit=100&skip=0 with header 'Netskope-Api-Token:
'. - Filter results by the 'user' field to isolate activity for a specific user.
- Paginate through results by incrementing skip by limit until totalResults is exhausted.
- Forward results to SIEM or store for compliance reporting.
Watch out for: Audit events endpoint uses skip/limit pagination, not SCIM startIndex/count. Token scope must include 'events'; a SCIM-only token will return 403.
Why building this yourself is a trap
The most operationally dangerous assumption in Netskope's API is that a single token covers all operations. It does not.
SCIM provisioning tokens and REST API v2 tokens are generated in different console locations, have different scope models, and return 403 errors when used against the wrong endpoint class - without indicating which token type is expected. Any integration that conflates these two token types will fail in non-obvious ways.
A second trap is the PUT vs. PATCH distinction on user updates. PUT /Users/{id} performs a full resource replacement: any field omitted from the request body may be cleared.
For attribute updates (department, status, group membership), always use PATCH with explicit RFC 7644 operation syntax. Not all attributes are documented as supporting PATCH operations, so callers should validate behavior against a non-production user before applying at scale.
Rate limiting adds a third operational risk. Netskope enforces approximately 300 requests per minute per token (observed; not officially published). HTTP 429 is returned on breach, but no Retry-After header is included in the response.
Callers must implement exponential backoff independently. For integrations built on an MCP server with 60+ deep IT/identity integrations, token-per-integration rate limit exhaustion is a realistic failure mode if multiple systems poll the same Netskope tenant concurrently - use dedicated tokens per integration and monitor 429 frequency proactively.
Automate Netskope workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.