Summary and recommendation
Sisense exposes a REST API at `https://{your-sisense-host}/api/v1` covering full user lifecycle: create, read, update, delete, and role/group assignment.
Authentication is Bearer token (JWT) obtained via `POST /api/v1/authentication/login`;
tokens must be refreshed on 401 since expiry is not publicly documented.
All entity IDs - `_id`, `roleId`, `groupId` - are MongoDB ObjectIds scoped to the specific instance, making them non-portable across environments.
For teams building identity graph pipelines, the user object exposes `lastLogin`, `active`, `roleId`, and `groups` fields that map cleanly to downstream access review and joiner-mover-leaver workflows.
API quick reference
| Has user API | Yes |
| Auth method | Bearer token (JWT). Obtain via POST /api/v1/authentication/login with username+password; token returned in response body. |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: Bearer token (JWT). Obtain via POST /api/v1/authentication/login with username+password; token returned in response body.
Setup steps
- POST to /api/v1/authentication/login with JSON body {"username": "...", "password": "..."}
- Extract the 'access_token' field from the response.
- Include header 'Authorization: Bearer
' on all subsequent requests. - Tokens expire; re-authenticate to obtain a fresh token when a 401 is returned.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| _id | string | Unique internal user ID (MongoDB ObjectId) | auto-generated | immutable | Used as path param for single-user operations. |
| userName | string | Unique username / login identifier | required | optional | Must be unique across the instance. |
| string | User email address | required | optional | Used for notifications and SSO matching. | |
| firstName | string | User first name | optional | optional | |
| lastName | string | User last name | optional | optional | |
| roleId | string | ID of the assigned system role | required | optional | Retrieve valid role IDs via GET /api/roles. |
| groups | array[string] | Array of group IDs the user belongs to | optional | optional | Group membership controls data access. |
| preferences | object | User UI preferences (language, etc.) | optional | optional | |
| active | boolean | Whether the user account is active | optional (defaults true) | optional | Set false to deactivate without deleting. |
| lastLogin | string (ISO 8601) | Timestamp of last successful login | read-only | read-only | |
| created | string (ISO 8601) | Account creation timestamp | auto-generated | read-only | |
| password | string | User password (write-only) | required (non-SSO) | optional | Never returned in GET responses. |
Core endpoints
List users
- Method: GET
- URL:
/api/v1/users - Watch out for: Returns all users visible to the authenticated user's role. Admins see all; non-admins may see a filtered list.
Request example
GET /api/v1/users?skip=0&limit=50
Authorization: Bearer <token>
Response example
[
{
"_id": "5f3e...",
"userName": "jdoe",
"email": "jdoe@example.com",
"roleId": "5f1a...",
"active": true
}
]
Get single user
- Method: GET
- URL:
/api/v1/users/{id} - Watch out for: Use the internal _id, not userName, as the path parameter.
Request example
GET /api/v1/users/5f3e...
Authorization: Bearer <token>
Response example
{
"_id": "5f3e...",
"userName": "jdoe",
"email": "jdoe@example.com",
"firstName": "John",
"lastName": "Doe",
"roleId": "5f1a..."
}
Create user
- Method: POST
- URL:
/api/v1/users - Watch out for: password is required for non-SSO users. For SSO-only deployments, omit password but ensure email matches IdP attribute.
Request example
POST /api/v1/users
Authorization: Bearer <token>
Content-Type: application/json
{"userName":"jdoe","email":"jdoe@example.com","roleId":"5f1a...","password":"Str0ng!"}
Response example
{
"_id": "5f3e...",
"userName": "jdoe",
"email": "jdoe@example.com",
"roleId": "5f1a..."
}
Update user
- Method: PATCH
- URL:
/api/v1/users/{id} - Watch out for: Only fields included in the body are updated. Omitting a field leaves it unchanged.
Request example
PATCH /api/v1/users/5f3e...
Authorization: Bearer <token>
Content-Type: application/json
{"firstName":"Jane","roleId":"5f2b..."}
Response example
{
"_id": "5f3e...",
"firstName": "Jane",
"roleId": "5f2b..."
}
Delete user
- Method: DELETE
- URL:
/api/v1/users/{id} - Watch out for: Deletion is permanent. Consider setting active=false via PATCH to deactivate instead of hard-delete.
Request example
DELETE /api/v1/users/5f3e...
Authorization: Bearer <token>
Response example
HTTP 200 OK
{}
Authenticate / get token
- Method: POST
- URL:
/api/v1/authentication/login - Watch out for: Token lifetime is not publicly documented; implement re-auth on 401 responses.
Request example
POST /api/v1/authentication/login
Content-Type: application/json
{"username":"admin","password":"adminpass"}
Response example
{
"access_token": "eyJ...",
"token_type": "bearer"
}
List roles
- Method: GET
- URL:
/api/v1/roles - Watch out for: roleId values required for user create/update must be fetched from this endpoint; they are instance-specific.
Request example
GET /api/v1/roles
Authorization: Bearer <token>
Response example
[
{"_id": "5f1a...", "name": "Admin"},
{"_id": "5f1b...", "name": "Viewer"}
]
List groups
- Method: GET
- URL:
/api/v1/groups - Watch out for: Group IDs are instance-specific. Group membership drives dashboard and data access permissions.
Request example
GET /api/v1/groups
Authorization: Bearer <token>
Response example
[
{"_id": "6a2c...", "name": "Sales Team"}
]
Rate limits, pagination, and events
Rate limits: Sisense does not publicly document specific rate-limit thresholds or headers in its official REST API docs.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: No official rate-limit documentation found. Behavior may vary by deployment (cloud vs. self-hosted) and server resources.
Pagination method: offset
Default page size: 50
Max page size: Not documented
Pagination pointer: skip / limit (e.g., ?skip=0&limit=50)
Webhooks available: No
Webhook notes: Sisense does not expose a native outbound webhook system for user lifecycle events in its official documentation.
Alternative event strategy: Poll GET /api/v1/users on a schedule, or use SCIM provisioning events triggered by the IdP (Okta, Entra ID) for near-real-time sync.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: https://{your-sisense-host}/api/scim/v2
Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, POST /Groups, PATCH /Groups/{id}, DELETE /Groups/{id}
Limitations:
- Requires SSO to be configured and active before SCIM can be enabled.
- Available on Enterprise plan only.
- SCIM token is generated within Sisense Admin > Security and must be provided as Bearer token to the IdP connector.
- Tested integrations documented for Okta and Azure AD (Entra ID); other IdPs may require manual SCIM connector configuration.
- Group provisioning maps to Sisense groups, not roles; role assignment may require supplemental REST API calls.
Common scenarios
Three integration patterns cover the primary automation use cases.
For provisioning, the sequence is: fetch a Bearer token → resolve roleId from GET /api/v1/roles → resolve groupId from GET /api/v1/groups → POST /api/v1/users with the resolved IDs;
hardcoding IDs across instances will break.
For bulk deactivation, paginate GET /api/v1/users using ?skip=0&limit=50, filter client-side on lastLogin and active (no server-side date filter exists), then PATCH /api/v1/users/{id} with {"active": false} prefer this over DELETE, which is irreversible.
For SCIM with Okta or Entra ID on Enterprise, the SCIM 2.0 endpoint is https://{your-sisense-host}/api/scim/v2;
SSO must be fully active before SCIM can be enabled, and group push maps to Sisense groups rather than roles, so role assignment requires supplemental REST calls post-provisioning.
Provision a new user with role and group assignment
- POST /api/v1/authentication/login to obtain Bearer token.
- GET /api/v1/roles to retrieve the target roleId by name.
- GET /api/v1/groups to retrieve the target groupId by name.
- POST /api/v1/users with userName, email, password (if non-SSO), roleId, and groups array.
- Verify creation by GET /api/v1/users/{new_id}.
Watch out for: roleId and groupId are instance-specific; always look them up dynamically rather than hardcoding.
Bulk deactivate users who have not logged in for 90 days
- GET /api/v1/users?skip=0&limit=50 (paginate through all users using skip/limit).
- Filter results client-side where lastLogin < (now - 90 days) AND active == true.
- For each matching user, PATCH /api/v1/users/{id} with body {"active": false}.
Watch out for: There is no server-side filter for lastLogin via query param; filtering must be done client-side after fetching all users.
Set up SCIM provisioning with Okta
- Confirm Enterprise plan and that SSO (SAML or OIDC) is already configured and working.
- In Sisense Admin > Security, enable SCIM and copy the generated SCIM Bearer token.
- In Okta, add the Sisense application and navigate to Provisioning > Integration.
- Set SCIM connector base URL to https://{your-sisense-host}/api/scim/v2 and paste the Bearer token.
- Enable supported provisioning features: Push New Users, Push Profile Updates, Push Groups, Deactivate Users.
- Assign users/groups in Okta to trigger initial provisioning sync.
Watch out for: SCIM group push maps to Sisense groups, not roles. Role assignment still requires manual configuration or supplemental REST API calls post-provisioning.
Why building this yourself is a trap
Several API behaviors create silent failure modes worth flagging explicitly. Rate limits are undocumented - no published thresholds, no rate-limit headers, no Retry-After support - so bulk operations against cloud or under-resourced self-hosted instances should include conservative backoff logic.
The base URL path varies by deployment: Linux instances use /api/v1, while legacy Windows deployments may use /api/v0.9; confirm before building integrations. Sisense does not expose native outbound webhooks for user lifecycle events, so identity graph synchronization must rely on scheduled polling of GET /api/v1/users or on IdP-side SCIM event triggers.
Finally, cloud and self-hosted instances do not guarantee endpoint parity - validate API availability against your specific deployment type before committing to an integration pattern.
Automate Sisense 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.