SCIM API reference
This page documents the System for Cross-domain Identity Management (SCIM) v2.0 endpoints implemented by Posit Connect. For setup instructions, see SCIM provisioning. For the full protocol specification, see RFC 7644 (protocol) and RFC 7643 (schema).
Write requests (POST, PUT, PATCH) must include a Content-Type header of application/scim+json or application/json, and must include a schemas array identifying the resource type. All responses use Content-Type: application/scim+json.
Success response codes
| Code | Meaning | Returned by |
|---|---|---|
200 OK |
Resource retrieved or updated | GET, PUT, PATCH |
201 Created |
Resource created | POST |
204 No Content |
Request accepted (no body returned) | DELETE |
Discovery
The discovery endpoints are publicly accessible and do not require authentication. They allow identity providers (IdPs) and clients to determine the SCIM capabilities that Connect supports before making provisioning requests.
| Method | Endpoint | Description |
|---|---|---|
GET |
/scim/v2/ServiceProviderConfig |
Returns supported SCIM features (authentication schemes, patch support, filtering, pagination limits) |
GET |
/scim/v2/ResourceTypes |
Returns the resource types Connect supports (User and Group) with their schema URIs |
GET |
/scim/v2/Schemas |
Returns the full schema definitions for User and Group resources |
Users
The {id} path parameter is the Connect globally unique identifier (GUID) for the user.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/scim/v2/Users |
List users (supports filtering and pagination) |
GET |
/scim/v2/Users/{id} |
Get user by GUID |
POST |
/scim/v2/Users |
Create user |
PUT |
/scim/v2/Users/{id} |
Replace user |
PATCH |
/scim/v2/Users/{id} |
Update user |
DELETE |
/scim/v2/Users/{id} |
No-op (returns 204). Does not remove the user. Use the usermanager CLI to delete users. |
Attributes
| Attribute | Required | Notes |
|---|---|---|
userName |
Yes | Must be unique |
active |
No | true = unlocked, false = locked. Defaults to locked if omitted. Accepts string "True"/"False" in PATCH (Entra ID compatibility) |
name.givenName |
No | Used by POST and PUT |
name.familyName |
No | Used by POST and PUT |
displayName |
No | Used by PATCH only. Split on whitespace into first name and last name |
emails[0].value |
No | Only the first email is used |
externalId |
No | Your IdP’s identifier. See details |
If your IdP sends both name and displayName in the same request, name.givenName and name.familyName take precedence and displayName has no effect. This applies to POST, PUT, and path-less PATCH operations.
Users created via SCIM are assigned the role specified by Authorization.DefaultUserRole (defaults to viewer). SCIM does not support setting or changing user roles. To modify a SCIM-provisioned user’s role, use the Connect UI or the Connect API.
PATCH operations
PATCH requests use the following request body structure:
Request body
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [...]
}For single-valued attributes, add and replace are semantically equivalent (RFC 7644 §3.5.2.1). Both set the attribute to the supplied value. Unsupported paths are silently ignored.
All user attributes can be modified with a direct-path operation:
{"op": "replace", "path": "active", "value": false}{"op": "replace", "path": "userName", "value": "newname"}{"op": "replace", "path": "displayName", "value": "Jane Smith"}{"op": "replace", "path": "name.givenName", "value": "Jane"}{"op": "replace", "path": "name.familyName", "value": "Smith"}{"op": "replace", "path": "externalId", "value": "external-id-value"}{"op": "replace", "path": "emails", "value": [{"value": "new@example.com", "primary": true}]}The path-less form supports setting multiple attributes in a single operation (Okta style):
{"op": "replace", "value": {"active": true, "userName": "jsmith", "displayName": "Jane Smith"}}The path-less form accepts all user attributes, including name, emails, and externalId:
{"op": "replace", "value": {"name": {"givenName": "Jane", "familyName": "Smith"}, "emails": [{"value": "jane@example.com", "primary": true}], "externalId": "ext-123"}}Entra ID sends PATCH operation names with an initial capital letter (e.g., "Replace" instead of "replace") and encodes the active field as a string ("True"/"False") rather than a JSON boolean. Connect handles both forms automatically.
Examples
Create a user
Terminal
curl -X POST https://connect.example.com/scim/v2/Users \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "jsmith",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"emails": [{"value": "jsmith@example.com", "primary": true}],
"externalId": "<external-id>",
"active": true
}'Response (201 Created):
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "<user-guid>",
"externalId": "<external-id>",
"userName": "jsmith",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"emails": [{"value": "jsmith@example.com", "type": "work", "primary": true}],
"active": true,
"meta": {
"resourceType": "User",
"created": "<timestamp>",
"lastModified": "<timestamp>",
"version": "W/\"<version>\"",
"location": "/scim/v2/Users/<user-guid>"
}
}Deactivate a user (PATCH)
Terminal
curl -X PATCH https://connect.example.com/scim/v2/Users/<user-guid> \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [{"op": "replace", "path": "active", "value": false}]
}'Response (200 OK): Returns the full user resource with "active": false.
Replace a user (PUT)
Terminal
curl -X PUT https://connect.example.com/scim/v2/Users/<user-guid> \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "jsmith",
"name": {
"givenName": "Jane",
"familyName": "Doe"
},
"emails": [{"value": "jdoe@example.com", "primary": true}],
"active": true
}'Response (200 OK): Returns the full updated user resource. PUT preserves system-managed fields (GUID, role, unique ID, creation time) and replaces only profile attributes. Connect ignores the externalId field in PUT requests. To update a user’s unique ID after creation, use the usermanager alter --new-unique-id CLI command on the Connect server.
Groups
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/scim/v2/Groups |
List groups (supports filtering and pagination) |
GET |
/scim/v2/Groups/{id} |
Get group by GUID |
POST |
/scim/v2/Groups |
Create group |
PUT |
/scim/v2/Groups/{id} |
Replace group |
PATCH |
/scim/v2/Groups/{id} |
Update group or members |
DELETE |
/scim/v2/Groups/{id} |
Delete group |
Attributes
| Attribute | Required | Notes |
|---|---|---|
displayName |
Yes | Maximum 4096 characters |
members |
No | Array of {"value": "<user-guid>"} objects |
PATCH operations
PATCH requests use the following request body structure:
Request body
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [...]
}The supported operations are listed below. Unsupported paths are silently ignored.
Add members to a group
Duplicates are ignored.
{"op": "add", "path": "members", "value": [{"value": "<user-guid>"}]}Remove members (Entra ID style)
No error if the user is not a member.
{"op": "remove", "path": "members", "value": [{"value": "<user-guid>"}]}Remove a single member (Okta style)
No error if the user is not a member.
{"op": "remove", "path": "members[value eq \"<user-guid>\"]"}Replace the entire member list
{"op": "replace", "path": "members", "value": [{"value": "<user-guid>"}]}Rename the group (Entra ID style)
For single-valued attributes like displayName, add and replace are equivalent. Entra ID uses add when it believes the attribute is unset.
{"op": "replace", "path": "displayName", "value": "New Group Name"}{"op": "add", "path": "displayName", "value": "New Group Name"}Rename the group (Okta style)
The path is omitted and the value is an object:
{"op": "replace", "value": {"displayName": "New Group Name"}}Entra ID sends PATCH operation names with an initial capital letter (e.g., "Replace" instead of "replace"). Connect normalizes this automatically.
Examples
Create a group
Terminal
curl -X POST https://connect.example.com/scim/v2/Groups \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Data Science Team",
"members": [
{"value": "<user-guid>"}
]
}'Response (201 Created):
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": "<group-guid>",
"displayName": "Data Science Team",
"members": [
{
"value": "<user-guid>",
"$ref": "/scim/v2/Users/<user-guid>",
"display": "Jane Smith",
"type": "User"
}
],
"meta": {
"resourceType": "Group",
"location": "/scim/v2/Groups/<group-guid>"
}
}Add members (PATCH)
Terminal
curl -X PATCH https://connect.example.com/scim/v2/Groups/<group-guid> \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [{
"op": "add",
"path": "members",
"value": [{"value": "<user-guid-2>"}]
}]
}'Response (200 OK): Returns the full group resource with the updated member list.
Remove members (PATCH)
Terminal
curl -X PATCH https://connect.example.com/scim/v2/Groups/<group-guid> \
-H "Authorization: Bearer SERVICE-TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [{
"op": "remove",
"path": "members",
"value": [{"value": "<user-guid-2>"}]
}]
}'Response (200 OK): Returns the full group resource with the updated member list.
Filtering
Connect supports the eq (equals) operator for filtering. String comparisons are case-insensitive. Other SCIM filter operators are not supported.
| Resource | Filterable attributes |
|---|---|
| Users | userName, email or emails.value, externalId |
| Groups | displayName |
Example:
Terminal
curl -H "Authorization: Bearer SERVICE-TOKEN" \
"https://connect.example.com/scim/v2/Users?filter=userName%20eq%20%22jsmith%22"Enclose filter values in double quotes per the SCIM specification. URL-encode the filter parameter.
Pagination
| Parameter | Description | Default |
|---|---|---|
startIndex |
1-based starting position | 1 |
count |
Results per page | 20 |
Connect advertises a maxResults of 200 in the ServiceProviderConfig endpoint. Responses include totalResults, startIndex, and itemsPerPage for navigation.
Error responses
Connect returns errors in the SCIM error format defined by RFC 7644 section 3.12:
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "409",
"scimType": "uniqueness",
"detail": "User already exists"
}| Status | scimType |
Cause |
|---|---|---|
400 |
invalidSyntax |
Malformed JSON, missing schemas array, or missing required schema |
400 |
invalidValue |
Missing required attribute (e.g., userName, displayName, email.value, member.value) |
400 |
invalidPath |
Invalid resource path in URL |
401 |
— | Missing or invalid credentials |
403 |
— | Authenticated but insufficient permissions |
404 |
— | Resource not found (user or group GUID does not exist) |
405 |
— | HTTP method not allowed for the endpoint |
409 |
uniqueness |
Username or group name already exists |
500 |
— | Internal server error |
501 |
— | Unsupported endpoint (/Bulk, /Me) |
Limitations
| Feature | Status |
|---|---|
Bulk operations (/scim/v2/Bulk) |
Not supported |
Current user (/scim/v2/Me) |
Not supported |
| Change password | Not supported |
| User deletion | Returns 204 but does not delete |
Sorting (sortBy, sortOrder) |
Not supported |
| ETags | Not supported |
Filter operators other than eq |
Not supported |
Logical operators (and, or, not) |
Not supported |