⚠️ SCIM is available in Enterprise subscription.
Qase SCIM API is used by SSO partners to provision, manage, and de-provision users and groups
The SCIM API is based on the Open standard: System for Cross-domain Identity Management 2. Our SCIM implementation uses the 2.0 version of the protocol.
Our SCIM implementation supports only two types of resources:
Users: users in a company plan.
Groups: teams (groups of users) in the workspace.
With SCIM you can:
- Get all users in a company. Update, activate, or deactivate users.
- Create, update, and delete groups. Add or remove members from groups.
User lifecycle management with SCIM
Any organization that grants access to its services and that uses permissions to control how users engage must manage users and their access. This lifecycle starts when a company onboards its users and continues until they leave the company. Managing users and their access involves various systems and can become challenging.
The increasing use of APIs for nearly every system has enabled organizations to automate the provisioning and management of users, often using the System for Cross-domain Identity Management (SCIM) as a standard. SCIM provides API methods and JSON objects that define users and groups, so identity providers and integration tools can manage users across systems.
This article looks into the Qase SCIM API, its capabilities, and some standard processes to consider when implementing automatic provisioning and management of users and groups in Qase.
Qase SCIM API overview
The Qase SCIM API enables organizations to manage user and group access automatically. It uses an identity provider, and it includes an interface for other identity providers that support the SCIM protocol. The documentation already features several walkthroughs for configuring an Okta or Azure Active Directory (AD) instance. An Okta or AD instance enables the automatic provisioning of users and groups, and it controls access for teams aligned with the two identity providers.
Additionally, you can call the SCIM API independently for greater control and customization. Independently calling the SCIM API allows middleware to create, update, and delete users and groups.
User lifecycle management with the Qase SCIM API
Understanding the information a company uses for onboarding and as users transition into new roles enables you to use your systems and data efficiently. Let's explore some common scenarios organizations encounter when implementing automated user management. We can then understand how the Qase SCIM API can assist with automating the user journey.
Suppose an organization has connected a single sign-on (SSO) capability for Qase logins, but uses an integration platform to perform the SCIM actions. This example demonstrates how to use the API in standard processes, such as onboarding new users and offboarding users.
New user onboarding
When discussing automated user management, one of the first topics tends to be creating new users in an application. Here, the ideal user experience is one in which account creation provides immediate access to all necessary resources.
For this example organization, when a company adds a new user to the `qaseUsers` group, the integration layer first calls the SCIM Users API to look up the user, using filters to ensure that the user doesn't already exist in the system. For a user with the email alex.smith@example.com, the lookup would look like this:
https://app.qase.io/scim/v2/Users?attributes=name,userName&filter=(userName eq "alex.smith@example.com")
If the user doesn't exist, the integration layer calls the create method with the user's details. This method only requires the username (the Qase email address), a family name, and a given name. You can also save the user ID with a property in your user directory to ensure that you have correctly linked the users.
User offboarding and deletion
Finally, when a user leaves your organization or no longer requires Qase, you must clean up their accounts. Of course, you can use the Delete User API to delete the account. However, in cases where the user no longer requires Qase, or if policies require that user accounts remain, you can also set the user’s status to inactive using the Update user API.
Group management
Groups in Qase map to workspace teams. Using the SCIM Groups API, you can automate the creation and membership management of teams. When your identity provider provisions a group, Qase creates a corresponding team in the workspace. Members can be assigned at creation time or added later using the PATCH endpoint. When a group is no longer needed, it can be deleted via the API.
The Qase SCIM API provides all the necessary components for managing your organization's users and groups through the entire lifecycle. Using existing user information and security groups or roles can make Qase's user and group management almost entirely automated.
Enable SCIM
SCIM API is enabled for all customers with Enterprise subscription by default. To manage users with SCIM in your Qase Enterprise account you will need to create a new API token:
1. Navigate to Workspace > SCIM page:
2. Now you can create a new SCIM API Token.
3. To ensure that everything is working as expected you can make the following request:
GET: https://app.qase.io/scim/v2/Users
Request Headers:
Accept application/scim+json
Content-Type application/json
Authorization Bearer + API Token from the previous step
⚠️ Base URL and Authorization type
As you can see from the previous example the base URL for SCIM API is https://app.qase.io/scim/v2/.
The API token must be included in every call to SCIM via Authorization header with type Bearer
🚧 HTTPS protocol
We support HTTPS requests only. Requests to HTTP protocol are redirected to HTTPS - please note that this redirection response can be handled incorrectly by certain tools.
curl Example:
curl https://app.qase.io/scim/v2/Users \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>"
Users
With SCIM API you can manage users in your Enterprise account. You can get the full list of users, filter by attribute, add new users, update user's attributes, activate or deactivate users and delete users completely.
User attributes
We support the following user attributes:
IDP attribute name | Qase attribute | Description |
| User email. Mandatory field. | |
Name |
| Attribute is used if the value is not empty. Maximum: 60 characters. |
|
| Attribute is used if the |
User type |
| Supported values:
When |
Active |
| Supported value: |
⚠️ Qase attribute namespace
'urn:ietf:params:scim:schemas:core:2.0:User' is a default SCIM urn for basic fields. If your identity provider does not require defining namespace, the default namespace must be avoided.
User Methods
Get users
GET: https://app.qase.io/scim/v2/Users
Retrieves the list of users in your organization. Use startIndex and count query parameters to receive paginated results. Supports sorting and the filter parameter.
Response:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 1,
"itemsPerPage": 1,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"userName": "john@doe.com",
"name": {
"familyName": "John",
"givenName": "Doe"
},
"active": true,
"userType": "regular",
"title": "CEO",
"emails": [
{
"value": "john@doe.com",
"primary": true
}
],
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
}
}
]
}
Sorting
Sorting allows you to specify the order in which resources are returned by specifying a combination of sortBy and sortOrder URL parameters. The sortBy parameter specifies the attribute whose value will be used to order the returned responses. The sortOrder parameter defines the order in which the sortBy parameter is applied. Allowed values are ascending and descending.
Filters
You can request a subset of resources by specifying the filter query parameter containing a filter expression. Attribute names and attribute operators used in filters are case insensitive. The filter parameter must contain at least one valid expression. Each expression must contain an attribute name followed by an attribute operator and an optional value.
eq | equal |
ne | not equal |
co | contains |
sw | starts with |
ew | ends with |
pr | preset (has value) |
gt | greater than |
ge | greater than or equal to |
lt | less than |
le | less than or equal to |
and | logical "and" |
or | logical "or" |
not | "not" function |
( ) | precedence grouping |
Example of complex request:
GET: https://app.qase.io/scim/v2/Users?attributes=name,userName&filter=NOT(name.familyName eq "Green")&sortBy=name.givenName&sortOrder=ascending&startIndex=2&count=5
Get user by ID
GET: https://app.qase.io/scim/v2/Users/1
Retrieves a single user resource
Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"userName": "john@doe.com",
"name": {
"familyName": "John",
"givenName": "Doe"
},
"active": true,
"userType": "regular",
"title": "CEO",
"emails": [
{
"value": "john@doe.com",
"primary": true
}
],
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
}
}
Create a new user
POST: https://app.qase.io/scim/v2/Users
Creates a new user. Payload must include userName attribute populated with an email address, familyName, and givenName attribute.
⚠️ All newly provisioned users are added with a default role.
Request:
{
"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName":"john@doe.com",
"name":{
"familyName":"John",
"givenName":"Doe"
}
}Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
},
"userName": "john@doe.com",
"name": {
"familyName": "John",
"givenName": "Doe"
},
"active": true,
"emails": [
{
"value": "john@doe.com",
"primary": true
}
]
}
Replace user by ID
PUT: https://app.qase.io/scim/v2/Users/1
Updates an existing user resource. This is the easiest way to replace the user information.
Request:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
},
"userName": "replace@example.com",
"name": {
"familyName": "Replace",
"givenName": "Me"
},
"active": true,
"userType": "regular",
"emails": [
{
"value": "replace@example.com",
"primary": true
}
]
}Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
},
"userName": "replace@example.com",
"name": {
"familyName": "Replace",
"givenName": "Me"
},
"active": true,
"userType": "regular",
"emails": [
{
"value": "replace@example.com",
"primary": true
}
]
}
Update user attribute by ID
PATCH: https://app.qase.io/scim/v2/Users/1
Updates an existing user resource, overwriting values for specified attributes. Attributes that are not provided will remain unchanged. PATCH only updates the fields provided.
The body of a PATCH request must contain the attribute Operations, whose value is an array of one or more PATCH operations. Each PATCH operation object must have exactly one op member.
Request to deactivate user:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Replace",
"path": "active",
"value": false
}
]
}Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "1",
"meta": {
"resourceType": "User",
"location": "https://app.qase.io/scim/v2/Users/1"
},
"userName": "john@doe.com",
"name": {
"familyName": "John",
"givenName": "Doe"
},
"active": true,
"userType": "regular",
"emails": [
{
"value": "john@doe.com",
"primary": true
}
]
}
Request to rename user:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Replace",
"path": "name.givenName",
"value": "New Given Name"
}
]
}
Request to upgrade user license to regular:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Replace",
"path": "userType",
"value": "regular"
}
]
}
Request to update user email (userName):
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Replace",
"path": "userName",
"value": "new@email.com"
}
]
}
Delete user
DELETE: https://app.qase.io/scim/v2/Users/1
Deletes a single user from the organization.
⚠️ User removing restrictions:
A user who is the workspace owner cannot be deleted. If you try to delete such user, the API returns a 409 error code.
Groups
With SCIM API you can manage groups (teams) in your Enterprise workspace. You can get the full list of groups, filter by name, create new groups with members, update group names and membership, and delete groups.
Group attributes
We support the following group attributes:
SCIM attribute | Qase attribute | Description |
displayName | Group title | The display name of the group. Mandatory field. Must be unique within the workspace |
members | Group members | An array of member objects. Each member has a `value` (the user's internal ID) and a `type` (always `"User"`). Only existing workspace members can be added. |
Qase attribute namespace:
'urn:ietf:params:scim:schemas:core:2.0:Group' is the default SCIM urn for Group fields. If your identity provider does not require defining namespace, the default namespace must be avoided.
Group Methods:
Get groups
GET: https://app.qase.io/scim/v2/Groups
Retrieves the list of groups in your workspace. Use `startIndex` and `count` query parameters to receive paginated results. Supports sorting and the filter parameter.
Response:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 2,
"itemsPerPage": 2,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "Regression Team",
"members": [
{
"type": "User",
"value": 1
},
{
"type": "User",
"value": 2
}
],
"meta": {
"resourceType": "Group",
"location": "https://app.qase.io/scim/v2/Groups/{hash}"
}
}
]
}
Sorting:
Sorting works the same as for Users. Use sortBy and sortOrder URL parameters. Allowed values for sortOrder are ascending and descending.
Filters:
You can filter groups by displayName using the filter query parameter. The following filter operators are supported:
eq | equal |
ne | not equal |
co | contains |
sw | starts with |
ew | ends with |
pr | preset (has value) |
gt | greater than |
ge | greater than or equal to |
lt | less than |
le | less than or equal to |
and | logical "and" |
or | logical "or" |
***⚠️*** Group filter limitations
Unlike Users, Groups do not support the not operator in filter expressions. Only the displayName attribute can be used for filtering.
Example of a filter request:
GET: https://app.qase.io/scim/v2/Groups?filter=displayName
Example with pagination:
GET: https://app.qase.io/scim/v2/Groups?startIndex=1&count=10
Get group by ID
GET: https://app.qase.io/scim/v2/Groups/{hash}Retrieves a single group resource by its hash ID.
Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "Regression Team",
"members": [
{
"type": "User",
"value": 1
},
{
"type": "User",
"value": 2
}
],
"meta": {
"resourceType": "Group",
"location": "https://app.qase.io/scim/v2/Groups/{hash}"
}
}
Create a new group
POST: https://app.qase.io/scim/v2/Groups
Creates a new group. Payload must include the schemas array and the displayName attribute. The members array is optional — you can create an empty group and add members later.
***⚠️***
Only existing workspace members can be added to a group. Member value must be set to the user's internal ID (as returned by the Users endpoint). Members that do not exist in the workspace are silently skipped.
Request (with members):
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "QA Engineers",
"members": [
{
"value": "1",
"type": "User"
},
{
"value": "2",
"type": "User"
}
]
}
Request (without members):
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "QA Engineers"
}
Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "QA Engineers",
"members": [
{
"type": "User",
"value": 1
},
{
"type": "User",
"value": 2
}
],
"meta": {
"resourceType": "Group",
"location": "https://app.qase.io/scim/v2/Groups/{hash}"
}
}
Replace group by ID
PUT: https://app.qase.io/scim/v2/Groups/{id}Fully replaces an existing group resource. This operation updates the displayName and completely replaces the member list, all existing members are removed and replaced with the members provided in the request.
***⚠️***
PUT is a full replacement. If you omit the members array, all existing members will be removed from the group.
Request:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "Regression Team (Updated)",
"members": [
{
"value": "21",
"type": "User"
},
{
"value": "22",
"type": "User"
}
]
}
Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "Regression Team (Updated)",
"members": [
{
"type": "User",
"value": 21
},
{
"type": "User",
"value": 22
}
],
"meta": {
"resourceType": "Group",
"location": "https://app.qase.io/scim/v2/Groups/{hash}"
}
}
Update group members by ID
PATCH: https://app.qase.io/scim/v2/Groups/{id}Partially updates a group resource. The body must contain the Operations array with one or more PATCH operations.
***⚠️*** PATCH limitations
Currently, PATCH only supports the Add operation on the members path. Other operations (e.g., Replace, Remove) or other paths will return an error. If you need to remove members or rename a group, use the PUT endpoint for a full replacement.
Request to add members:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Add",
"path": "members",
"value": [
{
"value": "5",
"type": "User"
},
{
"value": "8",
"type": "User"
}
]
}
]
}
Response:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "{hash}",
"displayName": "Regression Team",
"members": [
{
"type": "User",
"value": 21
},
{
"type": "User",
"value": 22
},
{
"type": "User",
"value": 5
},
{
"type": "User",
"value": 6
}
],
"meta": {
"resourceType": "Group",
"location": "https://app.qase.io/scim/v2/Groups/{hash}"
}
}
Delete group
DELETE: https://app.qase.io/scim/v2/Groups/{id}Deletes a single group from the workspace. Returns a 204 No Content response on success.
Discovery Features
ServiceProviderConfig
GET: https://app.qase.io/scim/v2/ServiceProviderConfig
Returns supported operations and SCIM API basic configuration.
ResourceTypes
GET: https://app.qase.io/scim/v2/ResourceTypes
Returns information about which resources are supported. Currently, we support Users only.
GET: https://app.qase.io/scim/v2/ResourceTypes/User
Will return metadata for User resource type.
Schemas
GET: https://app.qase.io/scim/v2/Schemas
Will return metadata about Users attributes that are currently supported.
GET: https://app.qase.io/scim/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User
Will provide information on how users are formatted.
Errors
Interacting with our APIs may result in an error instead of the expecting result. Qase tries to respond with a detailed error message that will help you figure out what went wrong and how to fix it.
Error response example:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:Error"
],
"status": "400",
"scimType": "invalidValue",
"detail": "User name 'email@example.com' is invalid: 'not unique'"
}
Possible errors:
Code | Status | Description |
400 | Bad Request | Unexpected request. The |
401 | Unauthorized | Qase cannot authorize the organization with the authorization token. |
403 | Forbidden | SCIM integration is disabled. |
404 | Not Found | The requested resource wasn't found by looking up its ID. |
405 | Method not allowed | Qase doesn't support the requested method. |
409 | Conflict | Qase cannot update a resource because of a business logic conflict. The logic conflict can vary, depending on the real-life scenario. |
413 | Payload too large | The payload exceeds the maximum payload of 800000 bytes. |
415 | Unsupported Media Type | The endpoint doesn't support the provided media type. |
429 | Too many requests. | - |
500 | Internal Server Error. | An unexpected error of application. Please, contact Qase support to clarify the reason for such an error. |


