Summary and recommendation
Ivanti Neurons for ITSM exposes user data through an OData v4 REST API under the businessobject endpoint family. Authentication is credential-based: POST username and password to /api/rest/authentication/login to receive a proprietary session token, then pass it as a Bearer token on subsequent requests.
There is no OAuth 2.0 flow and no refresh token; re-authentication is required when the session expires.
The primary user object is the Employee record, accessible at /api/odata/businessobject/employees. Standard OData query options ($filter, $select, $top, $skip, $orderby, $expand) are supported, but not all combinations are guaranteed stable across tenant configurations. Pagination uses $top/$skip with a default page size of 100 and a maximum of 1,000 records per request.
SCIM 2.0 is not available. Webhooks are not exposed as a native subscription API. Change detection must be implemented via scheduled polling using the LastModDateTime field as a filter.
This API surface is the integration layer for any identity graph that needs to reflect Ivanti analyst and user state.
API quick reference
| Has user API | Yes |
| Auth method | API Token (Bearer Token via session token obtained from /api/rest/authentication/login) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: API Token (Bearer Token via session token obtained from /api/rest/authentication/login)
Setup steps
- Navigate to Ivanti Neurons for ITSM admin console and enable REST API access for the tenant.
- Create or identify a service account with appropriate roles (e.g., Administrator or API User role).
- POST credentials to /api/rest/authentication/login with JSON body {"UserName":"...","Password":"...","tenant":"..."} to receive a session token.
- Include the token in subsequent requests as HTTP header: Authorization: Bearer {token}.
- Tokens expire after a configurable session timeout; re-authenticate to obtain a new token.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| RecId | string (GUID) | Unique record identifier | auto-generated | immutable | Primary key for Employee/User business object |
| LoginID | string | User login name / username | required | optional | Must be unique within tenant |
| FirstName | string | User first name | required | optional | |
| LastName | string | User last name | required | optional | |
| string | Primary email address | required | optional | Used for notifications | |
| Phone | string | Primary phone number | optional | optional | |
| Department | string | Department name or reference | optional | optional | May be a linked business object |
| Title | string | Job title | optional | optional | |
| Manager | string (GUID ref) | Reference to manager Employee record | optional | optional | Linked object reference |
| Status | string (enum) | Account status (Active, Inactive) | optional | optional | Controls login access |
| Role | string | Assigned ITSM role (e.g., Analyst, Self Service) | optional | optional | Determines feature access |
| Team | string (GUID ref) | Team membership reference | optional | optional | Linked object |
| Location | string | Physical or organizational location | optional | optional | |
| CreatedDateTime | datetime | Record creation timestamp | auto-generated | immutable | ISO 8601 format |
| LastModDateTime | datetime | Last modification timestamp | auto-generated | auto-updated |
Core endpoints
Authenticate / Get Session Token
- Method: POST
- URL:
https://{tenant}.ivanticloud.com/api/rest/authentication/login - Watch out for: Session tokens expire based on tenant session timeout settings. There is no refresh token; re-POST credentials to get a new token.
Request example
POST /api/rest/authentication/login
Content-Type: application/json
{
"UserName": "svc_api",
"Password": "secret",
"tenant": "mytenant"
}
Response example
{
"SessionToken": "abc123xyz...",
"UserName": "svc_api"
}
List Users (Employee records)
- Method: GET
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees - Watch out for: OData $filter, $select, $orderby are supported but complex filters may time out on large datasets. Use $top/$skip for pagination.
Request example
GET /api/odata/businessobject/employees?$top=50&$skip=0
Authorization: Bearer {token}
Response example
{
"value": [
{
"RecId": "guid-1",
"LoginID": "jdoe",
"FirstName": "Jane",
"LastName": "Doe",
"Email": "jdoe@example.com",
"Status": "Active"
}
]
}
Get Single User by RecId
- Method: GET
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees('{RecId}') - Watch out for: RecId must be the GUID string, not the LoginID. Use $filter=LoginID eq 'jdoe' on the collection endpoint to look up by username.
Request example
GET /api/odata/businessobject/employees('guid-1')
Authorization: Bearer {token}
Response example
{
"RecId": "guid-1",
"LoginID": "jdoe",
"FirstName": "Jane",
"LastName": "Doe",
"Email": "jdoe@example.com",
"Status": "Active"
}
Create User (Employee record)
- Method: POST
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees - Watch out for: Creating an Employee record does not automatically provision login credentials or assign a license role. Role assignment requires a separate update or is handled via SAML auto-provisioning rules.
Request example
POST /api/odata/businessobject/employees
Authorization: Bearer {token}
Content-Type: application/json
{
"LoginID": "newuser",
"FirstName": "New",
"LastName": "User",
"Email": "newuser@example.com"
}
Response example
{
"RecId": "guid-new",
"LoginID": "newuser",
"FirstName": "New",
"LastName": "User",
"Email": "newuser@example.com",
"Status": "Active"
}
Update User (Employee record)
- Method: PATCH
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees('{RecId}') - Watch out for: PATCH performs a partial update. Sending null for a field may clear it depending on field configuration. Test in a non-production tenant first.
Request example
PATCH /api/odata/businessobject/employees('guid-1')
Authorization: Bearer {token}
Content-Type: application/json
{
"Status": "Inactive",
"Title": "Senior Analyst"
}
Response example
{
"RecId": "guid-1",
"Status": "Inactive",
"Title": "Senior Analyst"
}
Delete User (Employee record)
- Method: DELETE
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees('{RecId}') - Watch out for: Hard-deleting employee records may break historical ticket associations. Prefer setting Status=Inactive to deactivate users rather than deleting records.
Request example
DELETE /api/odata/businessobject/employees('guid-1')
Authorization: Bearer {token}
Response example
HTTP 204 No Content
Search Users by Filter
- Method: GET
- URL:
https://{tenant}.ivanticloud.com/api/odata/businessobject/employees?$filter=LoginID eq '{loginid}' - Watch out for: OData string filters are case-sensitive by default on some deployments. Use tolower() function if case-insensitive matching is needed.
Request example
GET /api/odata/businessobject/employees?$filter=LoginID eq 'jdoe'&$select=RecId,LoginID,Email,Status
Authorization: Bearer {token}
Response example
{
"value": [
{
"RecId": "guid-1",
"LoginID": "jdoe",
"Email": "jdoe@example.com",
"Status": "Active"
}
]
}
Logout / Invalidate Session Token
- Method: POST
- URL:
https://{tenant}.ivanticloud.com/api/rest/authentication/logout - Watch out for: Always explicitly logout service account sessions to avoid exhausting concurrent session limits on the tenant.
Request example
POST /api/rest/authentication/logout
Authorization: Bearer {token}
Response example
HTTP 200 OK
{"Message": "Logged out successfully"}
Rate limits, pagination, and events
Rate limits: Ivanti does not publicly document specific rate limit tiers or numeric thresholds in official documentation. Rate limiting behavior is enforced at the platform/infrastructure level and may vary by deployment (cloud vs. on-premises) and tenant configuration.
Rate-limit headers: Unknown
Retry-After header: Unknown
Rate-limit notes: No publicly documented rate limit headers or retry-after semantics found in official docs. Contact Ivanti support for tenant-specific limits.
Pagination method: offset
Default page size: 100
Max page size: 1000
Pagination pointer: $skip / $top (OData query parameters)
Webhooks available: No
Webhook notes: Ivanti Neurons for ITSM does not expose a native outbound webhook system for user/employee record events in its documented REST API. Event-driven integrations are typically handled via Ivanti's internal workflow automation (Business Rules / Workflow Designer) which can call external HTTP endpoints, but this is not a standard webhook subscription API.
Alternative event strategy: Use Ivanti Workflow Designer to trigger HTTP POST actions on business object events (e.g., Employee record created/updated). Alternatively, poll the employees OData endpoint using LastModDateTime filter for change detection.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- Ivanti Neurons for ITSM does not provide a native SCIM 2.0 endpoint as of available documentation.
- User provisioning from IdPs (Okta, Entra ID) is handled via SAML/OIDC Just-In-Time (JIT) auto-provisioning, not SCIM.
- Automated deprovisioning via SCIM is not supported; deactivation must be performed via REST API or manual process.
- Enterprise plan and SSO configuration are prerequisites for IdP-based auto-provisioning.
Common scenarios
Deprovisioning on offboarding: resolve the user's RecId by filtering on LoginID, then PATCH Status to Inactive. Setting Status=Inactive disables login but does not release the named license seat; that step requires a separate action in the admin console. Open ticket reassignment is not triggered automatically and must be handled via separate PATCH calls on incident or request business objects.
Bulk employee import from an HR system: POST each employee record individually to /api/odata/businessobject/employees - there is no batch endpoint. Role and team assignment requires a follow-up PATCH per record. Handle HTTP 409 conflicts (duplicate LoginID) by falling back to a PATCH on the existing record. Implement retry logic with exponential backoff; large imports will be slow given the per-record request requirement.
Directory sync from an IdP for profile updates: query changed users from the IdP (e.g., Entra ID delta query), resolve each Ivanti RecId via LoginID filter, then PATCH changed fields (Department, Title, Phone, Manager). Because SCIM is absent, this must run as a scheduled polling job. Records not found in Ivanti should be flagged for creation via POST if JIT provisioning is not active for that user population.
For teams building an identity graph across the stack, Ivanti employee records carry Department, Manager (GUID ref), Team, Role, and Status fields that map cleanly to organizational hierarchy and access-state nodes. The absence of event-driven triggers means the graph refresh cadence is bounded by polling frequency, not real-time events.
Deprovision a user when they leave the organization
- POST to /api/rest/authentication/login to obtain a session token.
- GET /api/odata/businessobject/employees?$filter=LoginID eq '{username}'&$select=RecId to resolve the user's RecId.
- PATCH /api/odata/businessobject/employees('{RecId}') with body {"Status": "Inactive"} to disable the account.
- Optionally reassign open tickets from this user via separate incident/request business object PATCH calls.
- POST to /api/rest/authentication/logout to invalidate the session token.
Watch out for: Setting Status=Inactive disables login but does not release the named license seat automatically; license management must be done in the admin console separately.
Bulk-import new employees from an HR system
- Authenticate via POST /api/rest/authentication/login.
- For each new employee record from HR feed, POST to /api/odata/businessobject/employees with required fields (LoginID, FirstName, LastName, Email).
- Capture the returned RecId for each created record.
- If role or team assignment is needed, PATCH each record with Role and Team fields.
- Handle HTTP 409 conflicts (duplicate LoginID) by falling back to a PATCH update on the existing record.
Watch out for: Ivanti does not support a bulk/batch OData endpoint; each employee must be created in a separate POST request, which can be slow for large imports. Implement retry logic with exponential backoff.
Sync user profile updates from an IdP directory
- Authenticate via POST /api/rest/authentication/login.
- Query changed users from the IdP directory (e.g., Entra ID delta query).
- For each changed user, GET /api/odata/businessobject/employees?$filter=LoginID eq '{upn}' to find the Ivanti RecId.
- PATCH /api/odata/businessobject/employees('{RecId}') with changed fields (e.g., Department, Title, Phone, Manager).
- Log RecIds of records not found (new users) and create them via POST if JIT provisioning is not enabled.
Watch out for: Since SCIM is not available, this sync must be implemented as a scheduled polling job. There is no event-driven trigger from Ivanti when records change externally.
Why building this yourself is a trap
The session token model is the primary operational risk for long-running integrations. Tokens are proprietary session identifiers, not OAuth 2.0 access tokens, and they expire based on tenant session timeout settings with no refresh mechanism.
Service accounts must re-authenticate on expiration, and concurrent session limits per account may apply - always call the logout endpoint after completing a batch to avoid exhausting session capacity.
Field names and available fields are not standardized across deployments. The internal business object name (e.g., 'employees') and the fields it exposes vary by tenant configuration and Ivanti product version (ISM vs. Neurons for ITSM).
Always retrieve /api/odata/businessobject/employees/$metadata to confirm the field surface for a specific tenant before building field mappings.
Creating an Employee record via API does not provision login credentials or assign a named license seat. License assignment is managed separately in the admin console and is not exposed through the REST API.
On-premises ISM deployments may also run older API versions with a different base URL structure and reduced capability set compared to the cloud offering - validate the target environment before assuming cloud API behavior applies.
Automate Ivanti 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.