SCIM 2.0
Automate user provisioning and group management using the SCIM 2.0 standard. Connect Showpad with identity providers like Okta, Azure AD, or OneLogin to keep users in sync automatically.
What you'll learn
- How to configure SCIM endpoints for your identity provider
- How to map SCIM attributes to Showpad user fields
- How to manage users and groups via SCIM
- Base endpoint:
https://{{subdomain}}.showpad.biz/api/Users/scim/v2 - Create users? Use
POST /Users - List users? Use
GET /Users - Update users? Use
PUT /Users/\{id\} - Manage groups? Use
/Groupsendpoints
When to use the API
| Identity Provider Integration | Automated Provisioning | Group Management | Enterprise SSO |
|---|---|---|---|
| Connect Okta, Azure AD, OneLogin, or other SCIM-compatible identity providers. | Automatically create and deactivate users based on your directory. | Sync user group memberships from your identity provider. | Combine with SSO for seamless enterprise authentication. |
- Plan: Ultimate with Enterprise add-on | Advanced or Expert
- Permissions: Administrator access to Showpad's Admin App
- Authentication: Valid OAuth 2.0 access token (learn more)
- Config: A SCIM-compatible identity management system
Resources
Base Endpoint
All SCIM requests use this base URL:
https://{{subdomain}}.showpad.biz/api/Users/scim/v2
Append resource paths (e.g., /Users, /Groups) to this base endpoint.
Mapping
User maps SCIM attributes to a Showpad User. You can list, filter, add, edit or remove users.
A new user will be automatically assigned to the "All Users" group. This is a default group that you can't unassign from
the user. If you want to assign the user to another group, it should exist already or be created via the groups
endpoint.
| SCIM attribute | Showpad Field | Attribute Type | Required | Default | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | id | Singular | True | |||||||||||||||||||||
userName | userName | Singular | True | |||||||||||||||||||||
name.givenName | firstName | Singular | True | |||||||||||||||||||||
name.familyName | lastName | Singular | True | |||||||||||||||||||||
emails[0].value | email | Singular | True | |||||||||||||||||||||
active | isActive | Singular | False | |||||||||||||||||||||
timezone | timezone | Singular | False | |||||||||||||||||||||
locale | language Supported values:
| Singular | False | en | ||||||||||||||||||||
title | companyRole | Singular | False | "" | ||||||||||||||||||||
externalID | scimId | Singular | False | "" | ||||||||||||||||||||
enterprise.organization | companyName | Singular | False | Current organization | ||||||||||||||||||||
phoneNumbers[0].value | phone | Singular | False | "" | ||||||||||||||||||||
phoneNumbers[0].type | -- | Singular | False | "work" (read-only) | ||||||||||||||||||||
emails[0].type | -- | Singular | False | "work" (read-only) | ||||||||||||||||||||
emails[0].primary | -- | Singular | False | True (read-only) | ||||||||||||||||||||
roles[0].value ORroles.^[primary==‘true’].value | userType | Singular | False | "tablet" | ||||||||||||||||||||
groups | usergroups | Multi-Valued | False | "All users" group | ||||||||||||||||||||
groups.value | usergroups.id | Singular | False | "All users" group ID | ||||||||||||||||||||
groups.display | usergroups.name | Singular | False | "All users" | ||||||||||||||||||||
entitlements | managedUsergroups | Multi-Valued | False | |||||||||||||||||||||
entitlements.type | -- | Singular | False | |||||||||||||||||||||
entitlements.value | managedUsergroups.id | Singular | False | |||||||||||||||||||||
manager.value | managerId | Singular | False |
Attributes
User
User attributes are multi-valued in SCIM but singular in Showpad. When you're creating or replacing the user and specify multiple values, the primary value will be mapped and the other values discarded. If there is no primary, the first value will be used.
| Attribute | Description |
|---|---|
phoneNumbers | |
emails | |
roles | A means of grouping users with similar permissions, each group of users has access to the information intended for them according to rules that have been pre-defined by an administrator. When changing this value, be aware that only certain roles are supported:
|
groups | Read-only attribute. This allows you to see to which user groups a user belongs. Modifying a user's membership to a group should be handled through the Usergroup resource. |
enterprise | In the table corresponds to enterprise schema urn:ietf:params:scim:schemas:extension:enterprise:2.0:User |
emails[0].value | Should follow email pattern. Must be unique in the system. Otherwise you will get an uniquenesserror. |
username | This must be unique in the system, otherwise you'll get a uniquenesserror. |
manager.value | This value should be either the Showpad ID or the email address of an existing Showpad user. |
Entitlements Example
When a user has the manager role, they can have groups assigned for which they can coach other users. Assigning these
groups can happen via the entitlements section using:
"entitlements": [
{
"value": "22b3d7f8eea74c37d3d140642ccbaeba",
"type": "coach_for_group"
}
]
This is the only entitlement currently supported by Showpad. Be sure to verify that entitlements are supported for managers and/or users by your identity provider.
Groups
| SCIM attribute | Showpad field | Attribute Type | Required | Default |
|---|---|---|---|---|
ID | id | Singular | True | |
displayName | name | Singular | True | |
members | users | Multi-Valued | False | |
members.value | users.id | Singular | False | |
members.display | users.username | Singular | False |
Pagination
You can paginate through results by using startIndex and count query parameters.
For example, the following code will output the second page of a 10-paged result:
User
/Users?startIndex=11&count=10
Groups
/Groups?startIndex=11&count=10
Filtering
You can filter for users by fields following the specs. Currently, only the EQ operator on username is supported.
User
The following code will result in a list of users whose username is "john.doe@showpad.com":
/Users?filter=username%20eq%20"john.doe@showpad.com"
Groups
Filtering for groups has not been implemented in Showpad's SCIM 2.0 version.
POST
Users
Create a new user in Showpad.
- cURL
- JavaScript
- Python
curl -X POST "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "john.doe@showpad.com",
"name": {
"givenName": "John",
"familyName": "Doe"
},
"emails": [{"value": "john.doe@showpad.com", "primary": true, "type": "work"}],
"active": true,
"locale": "en",
"timezone": "Europe/Brussels"
}'
const response = await fetch('https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users', {
method: 'POST',
headers: {
Authorization: 'Bearer {access_token}',
'Content-Type': 'application/json',
},
body: JSON.stringify({
schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
userName: 'john.doe@showpad.com',
name: { givenName: 'John', familyName: 'Doe' },
emails: [{ value: 'john.doe@showpad.com', primary: true, type: 'work' }],
active: true,
locale: 'en',
timezone: 'Europe/Brussels',
}),
});
const user = await response.json();
import requests
response = requests.post(
'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users',
headers={
'Authorization': 'Bearer {access_token}',
'Content-Type': 'application/json'
},
json={
'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User'],
'userName': 'john.doe@showpad.com',
'name': {'givenName': 'John', 'familyName': 'Doe'},
'emails': [{'value': 'john.doe@showpad.com', 'primary': True, 'type': 'work'}],
'active': True,
'locale': 'en',
'timezone': 'Europe/Brussels'
}
)
user = response.json()
Groups
Create a new user group in Showpad.
- cURL
- JavaScript
- Python
curl -X POST "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Sales Team",
"members": [
{"value": "{user_id_1}"},
{"value": "{user_id_2}"}
]
}'
const response = await fetch('https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups', {
method: 'POST',
headers: {
Authorization: 'Bearer {access_token}',
'Content-Type': 'application/json',
},
body: JSON.stringify({
schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],
displayName: 'Sales Team',
members: [{ value: '{user_id_1}' }, { value: '{user_id_2}' }],
}),
});
const group = await response.json();
import requests
response = requests.post(
'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups',
headers={
'Authorization': 'Bearer {access_token}',
'Content-Type': 'application/json'
},
json={
'schemas': ['urn:ietf:params:scim:schemas:core:2.0:Group'],
'displayName': 'Sales Team',
'members': [
{'value': '{user_id_1}'},
{'value': '{user_id_2}'}
]
}
)
group = response.json()
GET
Schemas
Retrieve SCIM schema definitions:
| Endpoint | Description |
|---|---|
/Schemas | Retrieves all configuration details. |
/Schemas/urn:ietf:params:scim:schemas:core:2.0:User | Retrieves user configuration details. |
/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group | Retrieves group configuration details. |
/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User | Retrieves enterprise user extensions. |
ResourceTypes
Retrieve available resource types:
| Endpoint | Description |
|---|---|
/ResourceTypes | Outputs types of resources. |
/ResourceTypes/User | User resource type details. |
/ResourceTypes/Group | Group resource type details. |
ServiceProviderConfig
Retrieve supported operations:
| Endpoint | Description |
|---|---|
/ServiceProviderConfig | Returns a list of operations supported in the current implementation. |
Users
List users with optional pagination and filtering (100 per page by default).
- cURL
- JavaScript
- Python
curl -X GET "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users?startIndex=1&count=25" \
-H "Authorization: Bearer {access_token}"
const response = await fetch('https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users?startIndex=1&count=25', {
headers: { Authorization: 'Bearer {access_token}' },
});
const users = await response.json();
import requests
response = requests.get(
'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users',
headers={'Authorization': 'Bearer {access_token}'},
params={'startIndex': 1, 'count': 25}
)
users = response.json()
Users/{Id}
Retrieve a specific user by ID.
- cURL
- JavaScript
- Python
curl -X GET "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}" \
-H "Authorization: Bearer {access_token}"
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/${userId}`, {
headers: { Authorization: 'Bearer {access_token}' },
});
const user = await response.json();
import requests
response = requests.get(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}',
headers={'Authorization': 'Bearer {access_token}'}
)
user = response.json()
Groups
List groups (100 per page by default).
- cURL
- JavaScript
- Python
curl -X GET "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups?startIndex=1&count=25" \
-H "Authorization: Bearer {access_token}"
const response = await fetch('https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups?startIndex=1&count=25', {
headers: { Authorization: 'Bearer {access_token}' },
});
const groups = await response.json();
import requests
response = requests.get(
'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups',
headers={'Authorization': 'Bearer {access_token}'},
params={'startIndex': 1, 'count': 25}
)
groups = response.json()
Groups/{id}
Retrieve a specific group by ID.
- cURL
- JavaScript
- Python
curl -X GET "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}" \
-H "Authorization: Bearer {access_token}"
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/${groupId}`, {
headers: { Authorization: 'Bearer {access_token}' },
});
const group = await response.json();
import requests
response = requests.get(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}',
headers={'Authorization': 'Bearer {access_token}'}
)
group = response.json()
PUT
Users/{id}
Replace all attributes of a user.
- cURL
- JavaScript
- Python
curl -X PUT "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "john.doe@showpad.com",
"name": {"givenName": "John", "familyName": "Smith"},
"emails": [{"value": "john.doe@showpad.com", "primary": true}],
"active": true
}'
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/${userId}`, {
method: 'PUT',
headers: {
Authorization: 'Bearer {access_token}',
'Content-Type': 'application/json',
},
body: JSON.stringify({
schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
userName: 'john.doe@showpad.com',
name: { givenName: 'John', familyName: 'Smith' },
emails: [{ value: 'john.doe@showpad.com', primary: true }],
active: true,
}),
});
const user = await response.json();
import requests
response = requests.put(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}',
headers={
'Authorization': 'Bearer {access_token}',
'Content-Type': 'application/json'
},
json={
'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User'],
'userName': 'john.doe@showpad.com',
'name': {'givenName': 'John', 'familyName': 'Smith'},
'emails': [{'value': 'john.doe@showpad.com', 'primary': True}],
'active': True
}
)
user = response.json()
Groups/{id}
Replace all attributes of a group.
- cURL
- JavaScript
- Python
curl -X PUT "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Updated Sales Team",
"members": [{"value": "{user_id_1}"}, {"value": "{user_id_2}"}]
}'
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/${groupId}`, {
method: 'PUT',
headers: {
Authorization: 'Bearer {access_token}',
'Content-Type': 'application/json',
},
body: JSON.stringify({
schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],
displayName: 'Updated Sales Team',
members: [{ value: '{user_id_1}' }, { value: '{user_id_2}' }],
}),
});
const group = await response.json();
import requests
response = requests.put(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}',
headers={
'Authorization': 'Bearer {access_token}',
'Content-Type': 'application/json'
},
json={
'schemas': ['urn:ietf:params:scim:schemas:core:2.0:Group'],
'displayName': 'Updated Sales Team',
'members': [{'value': '{user_id_1}'}, {'value': '{user_id_2}'}]
}
)
group = response.json()
DELETE
Users/{id}
Delete a user. Returns 204 No Content on success.
- cURL
- JavaScript
- Python
curl -X DELETE "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}" \
-H "Authorization: Bearer {access_token}"
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/${userId}`, {
method: 'DELETE',
headers: { Authorization: 'Bearer {access_token}' },
});
// Returns 204 No Content on success
import requests
response = requests.delete(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Users/{user_id}',
headers={'Authorization': 'Bearer {access_token}'}
)
# Returns 204 No Content on success
Groups/{id}
Delete a group. Returns 204 No Content on success.
- cURL
- JavaScript
- Python
curl -X DELETE "https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}" \
-H "Authorization: Bearer {access_token}"
const response = await fetch(`https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/${groupId}`, {
method: 'DELETE',
headers: { Authorization: 'Bearer {access_token}' },
});
// Returns 204 No Content on success
import requests
response = requests.delete(
f'https://{{subdomain}}.showpad.biz/api/Users/scim/v2/Groups/{group_id}',
headers={'Authorization': 'Bearer {access_token}'}
)
# Returns 204 No Content on success
PATCH
to replace resources. :::
Next Steps
- User Management: Direct API access to user operations
- Webhooks: Get notified when users are created or updated
Was this page helpful?