Stitchflow
Zscaler logo

Zscaler User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 17, 2026

Summary and recommendation

The ZIA REST API uses a proprietary session-based authentication model, not OAuth 2.0.

Callers must implement a client-side API key obfuscation algorithm - combining the raw API key with a millisecond-precision Unix timestamp - before POSTing to /api/v1/authenticatedSession.

The response sets a JSESSIONID cookie that must accompany every subsequent request;

there is no bearer token alternative for the native REST API.

The base URL is cloud-instance-specific (e.g., zsapi.zscaler.net vs.

zsapi.zscalerone.net vs.

zsapi.zscalertwo.net).

Using the wrong hostname produces authentication failures with no descriptive error.

Rate limits cap at 1,000 requests/hour per admin session for most endpoints, with write endpoints limited to 400 requests/hour;

HTTP 429 responses carry no Retry-After header, so exponential backoff must be implemented manually.

API quick reference

Has user APIYes
Auth methodAPI Key + Session Cookie (ZIA proprietary auth). Caller POSTs credentials and API key to /authenticatedSession to obtain a JSESSIONID cookie used on subsequent requests.
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise

Authentication

Auth method: API Key + Session Cookie (ZIA proprietary auth). Caller POSTs credentials and API key to /authenticatedSession to obtain a JSESSIONID cookie used on subsequent requests.

Setup steps

  1. In the ZIA Admin Portal, navigate to Administration > API Key Management and generate an API key (obfuscated key + timestamp are combined to form the auth payload).
  2. Construct the authentication payload: combine the API key with a Unix timestamp (milliseconds) to produce an obfuscated password per Zscaler's documented algorithm.
  3. POST to https://.zscaler.net/api/v1/authenticatedSession with JSON body {"apiKey": "", "username": "", "password": "", "timestamp": }.
  4. Extract the JSESSIONID cookie from the response and include it as a Cookie header on all subsequent API requests.
  5. Call DELETE /authenticatedSession to log out and invalidate the session when done.

User object / data model

Field Type Description On create On update Notes
id integer Unique user ID assigned by ZIA. system-assigned required (in URL) Read-only after creation.
name string Full display name of the user. required optional Max 64 characters.
email string User's email address; used as login identifier. required optional Must be unique within the tenant.
password string User password (write-only). required optional Never returned in GET responses.
groups array[object] List of group objects {id, name} the user belongs to. optional optional Groups must exist before assignment.
department object Department object {id, name} the user is assigned to. optional optional Department must exist before assignment.
comments string Free-text notes about the user. optional optional
tempAuthEmail string Temporary authentication email for the user. optional optional
authMethods array[string] Authentication methods enabled for the user (e.g., BASIC, DIGEST). optional optional
type string User type: SUPERADMIN, ADMIN, AUDITOR, GUEST, REPORT_USER, UNAUTH. optional optional Defaults to standard user if omitted.
adminUser boolean Indicates if the user has admin privileges. optional optional
isNonEditable boolean If true, user cannot be edited via the API. system-assigned read-only Set by system for certain built-in accounts.
deleted boolean Indicates if the user is soft-deleted. system-assigned read-only Use DELETE endpoint to remove users.

Core endpoints

List Users

  • Method: GET
  • URL: /api/v1/users?page=1&pageSize=100&name=<filter>
  • Watch out for: Pagination is 1-indexed. Omitting pageSize defaults to 100; max is 1000. Filter by name, dept, or group using query params.

Request example

GET /api/v1/users?pageSize=100&page=1
Cookie: JSESSIONID=<session_id>

Response example

[
  {
    "id": 12345,
    "name": "Jane Doe",
    "email": "jane@example.com",
    "groups": [{"id": 1, "name": "Engineering"}],
    "department": {"id": 10, "name": "R&D"}
  }
]

Get User by ID

  • Method: GET
  • URL: /api/v1/users/{userId}
  • Watch out for: Returns 404 if user does not exist or has been hard-deleted.

Request example

GET /api/v1/users/12345
Cookie: JSESSIONID=<session_id>

Response example

{
  "id": 12345,
  "name": "Jane Doe",
  "email": "jane@example.com",
  "adminUser": false,
  "deleted": false
}

Create User

  • Method: POST
  • URL: /api/v1/users
  • Watch out for: Password is required on creation and must meet complexity requirements. Groups and department objects must reference existing IDs.

Request example

POST /api/v1/users
Content-Type: application/json

{"name":"John Smith","email":"john@example.com",
 "password":"Str0ng!Pass","groups":[{"id":1}],
 "department":{"id":10}}

Response example

{
  "id": 12346,
  "name": "John Smith",
  "email": "john@example.com",
  "groups": [{"id": 1, "name": "Engineering"}]
}

Update User

  • Method: PUT
  • URL: /api/v1/users/{userId}
  • Watch out for: ZIA uses full PUT (not PATCH); omitting optional fields may reset them. Always include the user id in the request body matching the URL parameter.

Request example

PUT /api/v1/users/12346
Content-Type: application/json

{"id":12346,"name":"John A. Smith",
 "email":"john@example.com","groups":[{"id":2}]}

Response example

{
  "id": 12346,
  "name": "John A. Smith",
  "email": "john@example.com",
  "groups": [{"id": 2, "name": "DevOps"}]
}

Delete User

  • Method: DELETE
  • URL: /api/v1/users/{userId}
  • Watch out for: Deletion is permanent (hard delete). There is no soft-delete toggle via this endpoint.

Request example

DELETE /api/v1/users/12346
Cookie: JSESSIONID=<session_id>

Response example

HTTP 204 No Content

Bulk Delete Users

  • Method: POST
  • URL: /api/v1/users/bulkDelete
  • Watch out for: Maximum of 500 IDs per bulk delete request. Exceeding the limit returns an error.

Request example

POST /api/v1/users/bulkDelete
Content-Type: application/json

{"ids": [12345, 12346, 12347]}

Response example

HTTP 204 No Content

Activate Configuration Changes

  • Method: POST
  • URL: /api/v1/status/activate
  • Watch out for: CRITICAL: All create/update/delete operations in ZIA are staged and do not take effect until /status/activate is called. Forgetting this step means changes are not applied to the live policy.

Request example

POST /api/v1/status/activate
Cookie: JSESSIONID=<session_id>

Response example

{
  "status": "ACTIVE"
}

Create Authenticated Session

  • Method: POST
  • URL: /api/v1/authenticatedSession
  • Watch out for: The API key obfuscation algorithm is documented by Zscaler and must be implemented client-side. Using the raw API key directly will result in authentication failure.

Request example

POST /api/v1/authenticatedSession
Content-Type: application/json

{"apiKey":"<obfuscated_key>",
 "username":"admin@example.com",
 "password":"<obfuscated_pw>",
 "timestamp":1700000000000}

Response example

HTTP 200 OK
Set-Cookie: JSESSIONID=abc123; Path=/; HttpOnly

{"obfuscateApiKey": true}

Rate limits, pagination, and events

  • Rate limits: ZIA enforces per-hour and per-minute API rate limits. Limits vary by endpoint category. Exceeding limits returns HTTP 429.
  • Rate-limit headers: No
  • Retry-After header: No
  • Rate-limit notes: Official docs note that bulk operations (e.g., updating many users) should include delays between requests. Exact per-endpoint limits are documented in the ZIA API rate limits help article. No standard rate-limit response headers are documented.
  • Pagination method: offset
  • Default page size: 100
  • Max page size: 1000
  • Pagination pointer: pageSize / page
Plan Limit Concurrent
ZIA (all tiers) 1000 requests/hour per admin session; some write endpoints limited to 400 requests/hour 0
  • Webhooks available: No
  • Webhook notes: Zscaler ZIA does not offer outbound webhooks for user management events. Changes must be polled via the API.
  • Alternative event strategy: Use SCIM provisioning from an IdP (Okta, Azure AD) to push user lifecycle events into ZIA automatically, or poll /api/v1/users on a schedule.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise

  • Endpoint: https://.zscaler.net/scim

  • Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, POST /Groups, PUT /Groups/{id}, PATCH /Groups/{id}, DELETE /Groups/{id}

Limitations:

  • SCIM endpoint URL and bearer token are generated within the ZIA Admin Portal under Administration > Authentication > SCIM; the token is shown only once at generation time.
  • SSO (SAML) must be configured and enabled before SCIM provisioning can be activated.
  • Supported IdPs with documented integration guides: Okta, Azure AD (Entra ID), Ping Identity. Google Workspace and OneLogin are not officially documented.
  • SCIM is recommended by Zscaler over SAML Just-In-Time provisioning for full lifecycle management (including deprovisioning).
  • SCIM changes in ZIA also require the /status/activate call if made via the native API; however, SCIM-provisioned changes may be applied differently - consult IdP-specific integration guides.
  • Available on Enterprise tier; not available on lower ZIA tiers.

Common scenarios

Provisioning a new user requires four discrete API calls: authenticate → verify department/group IDs exist → POST /api/v1/users → POST /api/v1/status/activate.

Skipping the activate call leaves the user staged but non-functional;

they cannot authenticate through ZIA until activation completes.

Deprovisioning via the API issues a hard DELETE with no soft-delete toggle and no recovery path.

For teams building an identity graph across SaaS applications, this means the ZIA user record is permanently destroyed on DELETE - any downstream reconciliation must capture the user object before deletion.

SCIM-based deprovisioning via Okta or Azure AD handles the DELETE and activation automatically, removing the need for manual API orchestration.

The update endpoint uses full PUT semantics;

partial updates are not supported.

Omitting optional fields in a PUT body may silently reset existing values.

Bulk deletion accepts a maximum of 500 user IDs per request to /api/v1/users/bulkDelete.

Provision a new employee in ZIA

  1. Authenticate: POST /api/v1/authenticatedSession with obfuscated API key and admin credentials to obtain JSESSIONID.
  2. Verify the target department and group IDs exist: GET /api/v1/departments and GET /api/v1/groups.
  3. Create the user: POST /api/v1/users with name, email, password, groups array, and department object.
  4. Activate changes: POST /api/v1/status/activate to push the new user to live policy.
  5. Log out: DELETE /api/v1/authenticatedSession.

Watch out for: Skipping the /status/activate call means the user is staged but not active. The user will not be able to authenticate through ZIA until activation.

Deprovision a terminated employee

  1. Authenticate and obtain JSESSIONID.
  2. Look up the user by email: GET /api/v1/users?name= to retrieve the user ID.
  3. Delete the user: DELETE /api/v1/users/{userId}.
  4. Activate changes: POST /api/v1/status/activate.
  5. Log out.

Watch out for: Deletion via the ZIA API is a hard delete with no recovery. If using SCIM via Okta or Azure AD, deprovisioning the user in the IdP will trigger the DELETE automatically without requiring manual API calls or activation.

Set up SCIM provisioning via Okta

  1. Ensure SAML SSO is configured and active in ZIA (prerequisite for SCIM).
  2. In ZIA Admin Portal, go to Administration > Authentication > SCIM and enable SCIM provisioning.
  3. Copy the generated SCIM endpoint URL and bearer token (token is shown only once - store securely).
  4. In Okta, open the Zscaler app integration, navigate to the Provisioning tab, and enter the SCIM base URL and bearer token.
  5. Enable provisioning features: Create Users, Update User Attributes, Deactivate Users.
  6. Assign users or groups in Okta to trigger initial provisioning to ZIA.

Watch out for: If the SCIM bearer token is lost or regenerated, the Okta integration must be updated with the new token immediately or provisioning will fail silently. SCIM requires Enterprise tier.

Why building this yourself is a trap

The activation requirement is the primary integration trap. Every write operation - create, update, delete - is staged in a pending state. A pipeline that provisions users without calling POST /api/v1/status/activate will appear to succeed (HTTP 200 responses throughout) while producing zero effect on live policy.

This is not surfaced as an error at the write endpoints.

The SCIM bearer token is a secondary trap: it is displayed exactly once at generation time in the Admin Portal. If the token is lost or a new one is regenerated, the existing IdP integration breaks silently - provisioning failures may not surface immediately depending on IdP sync frequency.

Teams integrating ZIA into an identity graph via an MCP server with 60+ deep IT/identity integrations should treat token rotation as a breaking change requiring immediate IdP reconfiguration.

Webhooks are not available in ZIA. User lifecycle events cannot be pushed outbound; all change detection requires polling /api/v1/users on a schedule or relying on SCIM push from a supported IdP.

Automate Zscaler 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.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 17, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen