Processes a request from a SCIM IdP, creates a response, and alerts of required changes to make to your users.
Arguments
method 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' required
The HTTP method of the request from the SCIM IdP
pathAndQueryParams string required
The path and any included URL query parameters from the request URL (e.g. '/Users?filter=userName eq example@propelauth.com')
body object
The body of the request from the SCIM IdP
scimApiKey string
The SCIM Connection API Key from the Authorization header (can also pass the full 'Bearer scim_...' header)
Successful Response
status 'Completed' | 'ActionRequired'
When 'Completed', the SCIM request was fully processed and you can return the response to the IdP. When 'ActionRequired', you need to take action in your system (like creating/disabling a user) before responding to the IdP. See here for more information.
connectionId string
The ID of the SCIM connection
responseData object
The response data to return to the SCIM IdP (only when status is 'Completed')
responseHttpCode number
The HTTP status code to return to the SCIM IdP (only when status is 'Completed')
affectedUserIds string[]
Array of user IDs affected by this request (only when status is 'Completed')
action 'LinkUser' | 'DisableUser' | 'EnableUser' | 'DeleteUser'
The action required (only when
status is 'ActionRequired') commitId string
The ID to use when committing this change (only when
status is 'ActionRequired') userId string
The ID of the user to act upon (for DisableUser, EnableUser, DeleteUser actions)
primaryEmail string | null
The primary email of the SCIM user
userName string
The username from the SCIM request (only for LinkUser action)
parsedUserData object
Parsed user data based on your SCIM configuration
active boolean
Whether the user should be active (only for LinkUser action)
ssoUserSubject string | null
The SSO subject identifier (only for LinkUser action)
Error Types
statusToReturn
The HTTP status code to return to the SCIM IdP
bodyToReturn
The error response body to return to the SCIM IdP
underlyingError
Details about the specific error that occurred (e.g. InvalidApiKey, UserNotFound, MissingRequiredField)
const auth = createClient({ url, integrationKey });
// Set up a route handler to receive SCIM requests from your IdP// Forward the method, path, body, and API key from the incoming requestconst result = await auth.scim.scimRequest({ method: req.method, // Forward HTTP method from IdP pathAndQueryParams: req.url, // Forward path and query params from IdP body: req.body, // Forward request body from IdP scimApiKey: req.headers.authorization, // Forward Authorization header from IdP});
if (result.ok) { if (result.data.status === "Completed") { // Respond to SCIM IdP with the response data res.status(result.data.responseHttpCode).json(result.data.responseData); } else { // Action required - handle based on action type const { action, commitId } = result.data; console.log(`Action required: ${action} with commitId: ${commitId}`); }} else { // Return error to SCIM IdP res.status(result.error.statusToReturn).json(result.error.bodyToReturn);}def get_full_url(request): return request.url.path + ("?" + request.url.query if request.url.query else "")
async def get_body(request): return await request.json() if request.method != "GET" else None
client = create_client(url=url, integration_key=integration_key)
# Set up a route handler to receive SCIM requests from your IdP# Forward the method, path, body, and API key from the incoming requestresult = await client.scim.scim_request( method=request.method, # Forward HTTP method from IdP path_and_query_params=get_full_url(request), # Forward path and query params from IdP body=await get_body(request), # Forward request body from IdP scim_api_key=request.headers.get("authorization"), # Forward Authorization header from IdP)
if is_ok(result): if result.data.status == "Completed": # Respond to SCIM IdP with the response data return JSONResponse( status_code=result.data.response_http_code, content=result.data.response_data ) else: # Action required - handle based on action type action = result.data.action commit_id = result.data.commit_id print(f"Action required: {action} with commit_id: {commit_id}")else: # Return error to SCIM IdP return JSONResponse( status_code=result.error.status_to_return, content=result.error.body_to_return )client, err := byo.NewClient(url, integrationKey)if err != nil { log.Fatal(err)}
// Set up a route handler to receive SCIM requests from your IdP// Forward the method, path, body, and API key from the incoming requestresult, err := client.Scim.ScimRequest(r.Context(), byo.ScimRequestCommand{ Method: r.Method, PathAndQueryParams: r.URL.RequestURI(), Body: body, ScimAPIKey: byo.String(r.Header.Get("Authorization")),})if err != nil { log.Fatal(err)}
switch response := result.(type) {case *byo.ScimResponseCompleted: // Respond to the SCIM IdP with the response data fmt.Println(response.ResponseHTTPCode)case *byo.ScimResponseActionRequiredLinkUser: // Action required - handle based on the action type fmt.Println(response.CommitID)}PropelAuthClient client = PropelAuthClient.create(url, integrationKey);
ScimRequestCommand command = ScimRequestCommand.builder() .method(HttpMethod.valueOf(request.getMethod())) .pathAndQueryParams(request.getRequestURI() + (request.getQueryString() != null ? "?" + request.getQueryString() : "")) .body(JsonValue.of(requestBody)) .scimApiKey(request.getHeader("Authorization")) .build();
try { ScimRequestResponse scimResponse = client.scim.scimRequest(command);
if (scimResponse instanceof ScimRequestResponse.Completed) { ScimRequestResponse.Completed completed = (ScimRequestResponse.Completed) scimResponse; return ResponseEntity .status(completed.getResponseHttpCode()) .body(completed.getResponseData()); } else if (scimResponse instanceof ScimRequestResponse.ActionRequired) { ScimRequestResponse.ActionRequired actionRequired = (ScimRequestResponse.ActionRequired) scimResponse; // Handle based on action type (LinkUser, DisableUser, EnableUser, DeleteUser) System.out.println("Action required with commitId: " + actionRequired.getCommitId()); }} catch (ScimClientFacingException e) { return ResponseEntity .status(e.getStatusToReturn()) .body(e.getBodyToReturn());}var client = new PropelAuthClient(new PropelAuthOptions { Url = url, IntegrationKey = integrationKey });
var command = new ScimRequestCommand{ Method = Enum.Parse<HttpMethod>(request.Method), PathAndQueryParams = request.Path + (request.QueryString.HasValue ? request.QueryString.Value : ""), Body = requestBody, // JsonElement from request ScimApiKey = request.Headers["Authorization"]};
try{ var scimResponse = await client.Scim.ScimRequestAsync(command);
return scimResponse switch { ScimRequestResponseCompleted completed => Results.Json(completed.ResponseData, statusCode: completed.ResponseHttpCode), ActionRequired.LinkUser linkUser => HandleLinkUserAction(linkUser), ActionRequired.DisableUser disableUser => HandleDisableUserAction(disableUser), // ... EnableUser, DeleteUser };}catch (ScimClientFacingException ex){ // Return error to SCIM IdP return Results.Json(ex.BodyToReturn, statusCode: ex.StatusToReturn);}
Response
// When status is 'Completed':{ ok: true, data: { status: 'Completed', connectionId: 'Yhc4Nan2ZiIPp7kyoyhT9c', responseData: { /* SCIM response object to return to IdP */ }, responseHttpCode: 200, affectedUserIds: ['057806f5-6e19-45ef-ba31-238471a16fc5'] }}
// When status is 'ActionRequired':{ ok: true, data: { status: 'ActionRequired', connectionId: 'Yhc4Nan2ZiIPp7kyoyhT9c', action: 'LinkUser', commitId: 'a7272904-686e-4097-bdf5-ce1e2bd5707f', primaryEmail: 'example@propelauth.com', userName: 'example@propelauth.com', parsedUserData: { // Your parsed user data, based on your property configuration firstName: "Example", lastName: "User", department: "Engineering", employeeId: "00utc0x6na8aflr0E697" }, active: true, ssoUserSubject: null }}# When status is 'Completed':Result( data=CompletedScimRequestResponse( status='Completed', connection_id='Yhc4Nan2ZiIPp7kyoyhT9c', response_data={ # SCIM response object to return to IdP }, response_http_code=200, affected_user_ids=['057806f5-6e19-45ef-ba31-238471a16fc5'] ))
# When status is 'ActionRequired':Result( data=ScimRequestResponseActionRequiredLinkUser( status='ActionRequired', connection_id='Yhc4Nan2ZiIPp7kyoyhT9c', action='LinkUser', commit_id='a7272904-686e-4097-bdf5-ce1e2bd5707f', primary_email='example@propelauth.com', user_name='example@propelauth.com', parsed_user_data={ # Your parsed user data, based on your property configuration 'first_name': 'Example', 'last_name': 'User', 'department': 'Engineering', 'employee_id': '00utc0x6na8aflr0E697' }, active=True, sso_user_subject=None ))byo.ScimResponseCompleted{ ConnectionID: "Yhc4Nan2ZiIPp7kyoyhT9c", ResponseHTTPCode: 200, AffectedUserIds: []string{"057806f5-6e19-45ef-ba31-238471a16fc5"},}// When status is 'Completed':ScimRequestResponse.Completed( status="Completed", connectionId="Yhc4Nan2ZiIPp7kyoyhT9c", responseData={...}, responseHttpCode=200, affectedUserIds=["057806f5-6e19-45ef-ba31-238471a16fc5"])
// When status is 'ActionRequired':ScimRequestResponse.ActionRequired.ActionRequiredLinkUser( status="ActionRequired", action="LinkUser", connectionId="Yhc4Nan2ZiIPp7kyoyhT9c", commitId="a7272904-686e-4097-bdf5-ce1e2bd5707f", primaryEmail="example@propelauth.com", userName="example@propelauth.com", parsedUserData={ firstName="Example", lastName="User", department="Engineering", employeeId="00utc0x6na8aflr0E697" }, active=true, ssoUserSubject=null)// When status is 'Completed':ScimRequestResponseCompleted{ Status = "Completed", ConnectionId = "Yhc4Nan2ZiIPp7kyoyhT9c", ResponseData = {...}, ResponseHttpCode = 200, AffectedUserIds = ["057806f5-6e19-45ef-ba31-238471a16fc5"]}
// When status is 'ActionRequired':ActionRequired.LinkUser{ Status = "ActionRequired", Action = "LinkUser", ConnectionId = "Yhc4Nan2ZiIPp7kyoyhT9c", CommitId = "a7272904-686e-4097-bdf5-ce1e2bd5707f", PrimaryEmail = "example@propelauth.com", UserName = "example@propelauth.com", ParsedUserData = { // Your parsed user data, based on your property configuration FirstName = "Example", LastName = "User", Department = "Engineering", EmployeeId = "00utc0x6na8aflr0E697" }, Active = true, SsoUserSubject = null}