This article outlines common SCIM API calls that Okta may make and the expected response bodies.
- SCIM
- Okta Classic Engine
- Okta Identity Engine (OIE)
- Provisioning
- Group Push
Q1: When returning the response from Get Users With Filter, what are the required elements of the Resource objects, and what is the required set of attributes that must be returned to Okta in response to a Create User request?
A1: When Okta sends a GET /Users?filter=userName eq "username" request, the SCIM server must return a valid SCIM list response. Each user object in the Resources array must include the following required elements:
-
schemas – An array that identifies the SCIM schema(s) used (for example,
urn:scim:schemas:core:1.0orurn:ietf:params:scim:schemas:core:2.0:User). -
id – A unique identifier for the user in the SCIM system.
-
userName – The username that Okta uses to match the user.
-
active – A Boolean value indicating whether the user is active (true) or deactivated (false).
-
meta – A metadata object that includes at least the
location(the user’s SCIM resource URL) andresourceType(for example, "User").
A valid example response when a user exists would look like this:
{
"totalResults": 1,
"schemas": ["urn:scim:schemas:core1.0"],
"Resources": [
{
"schemas": ["urn:scim:schemas:core1.0"],
"id": "102",
"userName": "admin",
"active": false,
"meta": {
"location": "http://scim-server.example.com/scim/v2/Users/102",
"resourceType": "User"
}
}
]
}
If no user is found, the response must include "totalResults": 0 and an empty Resources array.
Q2: Is support for the Get Users endpoint required for the create user experience, or is Get Users With Filter sufficient? If there are no plans for user imports, what is the specific use case for the Get Users endpoint?
A2: Okta primarily uses the GET /Users?filter=... endpoint (Get Users With Filter) during the user creation and assignment process. This call allows Okta to check whether a user already exists in the SCIM system before creating them. Therefore, supporting Get Users With Filter is required for provisioning to work correctly.
The GET /Users endpoint (without a filter) is used only when Okta performs a user import — that is, when Okta retrieves a list of users from the SCIM application to sync them into Okta. If the integration excludes user import functionality, implementation of the unfiltered Get Users endpoint is not required.
In summary:
-
✅ Required:
GET /Users?filter=...— Used during user creation and assignment. -
⚙️ Optional:
GET /Users— Only necessary when implementing Okta user import functionality.
The spec indicates a Create User request which matches an existing user (based on displayname) should return a 409. Our legacy application would treat this use case as a PUT, update our local user and then return the updated user. I believe this was to account for the case where a user logged in (via SAML) before they had been synced via SCIM. What are the thoughts on this situation?
According to the SCIM standard and Okta’s expected behavior, if a Create User (POST /Users) request is made for a user that already exists in the SCIM system, the SCIM server should return an HTTP 409 Conflict response. This tells Okta that the user already exists, preventing it from creating a duplicate record.
If the legacy system currently updates the existing user and returns a success response instead of a 409, Okta may interpret that as a successful creation, which can cause synchronization issues. The correct approach is:
-
When Okta sends POST /Users, the SCIM server should first check if the user already exists (for example, by userName).
-
If the user exists, return 409 Conflict.
-
If the user does not exist, create the user and return 201 Created with the full user object.
Update existing Okta users via PUT or PATCH requests rather than POST.
Q3: What is the consequence of not including a list of groups? What is the expected structure?
A3: If the Get User by ID or Get Users with Filter responses do not include a list of groups, Okta simply will not be aware of any group memberships for that user. This means:
Okta cannot import or synchronize group membership from the SCIM application.
-
Group push or membership reconciliation features will not function for that user.
-
The user’s group assignments in Okta will remain unaffected, as Okta assumes no group data is available from the SCIM system.
Group information must adhere to the SCIM standard structure for the groups attribute: an array of objects where each contains a value (the group’s unique ID) and an optional display.
Example structure:
"groups": [
{
"value": "02a1ff9a-7f76-453a-919d-{Phone_number}",
"display": "Engineering"
},
{
"value": "9b3f2c11-8a22-4b9a-9b1a-1a2b3c4d5e6f",
"display": "Developers"
}
]
Including this data allows Okta to accurately reflect and manage group memberships during imports or synchronization.
Q4: If receiving an Update User (PATCH) request that includes more than one operation or two instances of the same operation (for example, setting a user’s active state multiple times), should Okta gracefully handle that or throw an error?
A4: According to the SCIM specification and Okta’s expected behavior, the SCIM service should gracefully handle multiple operations within a single PATCH request. Okta may send multiple operations in a single request (for example, updating multiple attributes or toggling the active state).
Here’s what’s expected:
-
Process each operation in the order it appears in the Operations array.
-
If the same attribute (such as active) is updated multiple times, apply the final state from the last operation.
-
Only return an error if the request is malformed or includes unsupported operations — not simply because there are duplicates.
Graceful handling ensures Okta’s provisioning flow continues smoothly and avoids unnecessary failures during user updates or deactivations.
Q5: Okta returns an ID as part of the Create Group response, which is then stored and used for subsequent update or delete requests. Documentation indicates that if this ID is unavailable—such as when the Import Groups option is disabled—Okta defaults to a Get Group With Filter request. Given that group imports are out of scope for this integration, does this necessitate implementation of the Get Group With Filter endpoint?
A5: Correct, this is how Okta handles SCIM group provisioning.
When the SCIM service receives a Create Group (POST /Groups) request, it must generate and return a unique, non-empty ID value in the response. This ID is then stored by Okta and used in all subsequent SCIM operations for that group, such as Update Group (PUT /Groups/{id}) or Delete Group (DELETE /Groups/{id}).
Per the SCIM specification (RFC 7643, section 3.1), the ID must:
-
Be unique across all resources in the SCIM system.
-
Be stable and non-reassignable (it should never change for the same group).
-
Be issued by the service provider (the SCIM app), not by Okta.
-
Never be empty or use the reserved keyword "bulkId".
If the ID is missing or empty, Okta will return an error such as Found an empty SCIM group string. Cannot update the group.
Q6: The response examples for Create Group, Get Group By ID, and Update Group (PATCH) indicate that the only meta property required is the resourceType. The response example for Get Groups With Filter and Update Group (PUT) indicate the meta property must also include the created, lastModified, and version attributes. Specify required endpoint parameters, their necessity, and the impact of their absence.
A6: Meta object requirements can vary slightly depending on the SCIM operation.
Based on Okta’s SCIM implementation and the SCIM specification:
-
For Create Group, Get Group by ID, and Update Group (PATCH) responses, the only required meta property is resourceType (for example, "Group").
-
For Get Groups with Filter and Update Group (PUT) responses, the meta object must include both resourceType and location.
The location attribute provides the resource's canonical URL (for example, https://example.com/scim/v2/Groups/{id}), which Okta uses to reference the group in subsequent operations.
Summary:
| Operation | Required meta fields |
|------------|------------------------|
| Create Group | resourceType |
| Get Group by ID | resourceType |
| Update Group (PATCH) | resourceType |
| Get Groups with Filter | resourceType, location |
| Update Group (PUT) | resourceType, location |
Including both fields (resourceType and location) in all responses is a best practice — it ensures consistency and avoids potential issues with Okta’s group push or synchronization processes.
