SCIM User API Basics
Liferay DXP 2024.Q1+/Portal GA112+
Liferay provides a headless API to perform CRUD operations on SCIM users to keep their identity information in sync with your company’s applications. Use the /scim endpoint from the API Explorer to manage SCIM users.
Mapping SCIM Attributes to Custom Fields
Liferay DXP 2025.Q4+
Liferay processes additional SCIM attributes during SCIM provisioning. When the incoming SCIM payload contains attributes that do not map to built-in user fields, Liferay creates matching custom fields automatically and stores the values there.
Typed addresses, multiple emails, phone numbers, profile URLs, instant-messaging handles, and other extension attributes map directly to built-in fields when possible. All remaining attributes map to auto-created custom fields under the User entity.
Adding a User
Start a new Liferay DXP instance by running
docker run -it -m 8g -p 8080:8080 liferay/dxp:2025.q1.6-lts
Sign in to Liferay at http://localhost:8080 using the email address test@liferay.com and the password test. When prompted, change the password to learn.
Once Liferay is running,
-
Download and unzip SCIM User API Basics.
curl https://resources.learn.liferay.com/examples/liferay-g7y9.zip -Ounzip liferay-g7y9.zip -
Use the cURL script to add a SCIM user in Liferay. On the command line, navigate to the
curlfolder. Execute theUsers_POST_ToInstance.shscript../Users_POST_ToInstance.shThe JSON response shows the addition of a new SCIM user:
{ "emails": [ { "type": "default", "value": "able@liferay.com", "primary": true } ], "meta": { "created": "2024-03-13T09:53:22Z", "location": "http://localhost:8080/o/scim/v1.0/v2/Users/36433", "lastModified": "2024-03-13T09:53:23Z", "resourceType": "User" }, "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:liferay:2.0:User" ], "urn:ietf:params:scim:schemas:extension:liferay:2.0:User": { "birthday": "1970-01-01", "male": true }, "name": { "familyName": "Baker", "givenName": "Able" }, "active": true, "externalId": "1446cf10-3de9-6e11-dd15-c561de806259", "id": "36433", "title": "", "userName": "able.baker" } -
Verify this by opening the Global Menu (
), and navigating to Control Panel → Users and Organizations. See that a new user has been added.
-
Alternatively, call the REST service using the Java client. Navigate into the
javafolder and compile the source files:javac -classpath .:* *.java -
Run the
Users_POST_ToInstanceclass.java -classpath .:* Users_POST_ToInstance
Examine the cURL Command
The Users_POST_ToInstance.sh script calls the REST service with a cURL command.
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users" \
--data-raw '
{
"active": "'true'",
"emails": [
{
"primary": "'true'",
"type": "default",
"value": "able@liferay.com"
}
],
"name": {
"familyName": "Baker",
"givenName": "Able"
},
"userName": "able.baker"
}' \
--header "Content-Type: application/scim+json" \
--request "POST" \
--user "test@liferay.com:learn"
Here are the command’s arguments:
| Arguments | Description |
|---|---|
"http://localhost:8080/o/scim/v1.0/v2/Users" | The REST service endpoint |
--data-raw "{ "active": "'true'", "emails": [ { "primary": "'true'", "type": "default", "value": "able@liferay.com" } ], "name": { "familyName": "Baker", "givenName": "Able" }, "userName": "able.baker" }" | The data to post |
--header "Content-Type: application/scim+json" | Indicates that the request body format is in JSON and conforms to the SCIM protocol. |
--request "POST" | The HTTP method to invoke at the specified endpoint |
--user "test@liferay.com:learn" | Basic authentication credentials |
Basic authentication is used here for demonstration purposes. For production, you should authorize users via OAuth2. See Using OAuth2 to Authorize Users for a sample React application using OAuth2.
Examine the Java Class
The Users_POST_ToInstance.java class adds a SCIM user by calling the UserResource service.
public static void main(String[] args) throws Exception {
UserResource.Builder builder = UserResource.builder();
UserResource userResource = builder.authentication(
"test@liferay.com", "learn"
).build();
userResource.postV2User(
new User() {
{
active = true;
name = new Name() {
{
familyName = "Baker";
givenName = "Able";
}
};
emails = new MultiValuedAttribute[] {
new MultiValuedAttribute() {
{
primary = true;
type = "default";
value = "able@liferay.com";
}
}
};
userName = "able.baker";
}
});
}
This class invokes the REST service using only three lines of code:
| Line (abbreviated) | Description |
|---|---|
UserResource.Builder builder = ... | Get a Builder for generating a UserResource service instance. |
UserResource userResource = builder.authentication(...).build(); | Use basic authentication and generate a UserResource service instance. |
userResource.postV2User(...); | Call the userResource.postV2User method. |
Note that the project includes the com.liferay.scim.rest.client.jar file as a dependency. You can find client JAR dependency information for all REST applications in the API explorer in your installation at /o/api (e.g., http://localhost:8080/o/api).
The main method’s comment demonstrates running the class.
See UserResource for service details.
Users_GET_FromInstance.sh
Command:
./Users_GET_FromInstance.sh
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users" \
--user "test@liferay.com:learn"
Users_GET_FromInstance.java
Command:
java -classpath .:* Users_GET_FromInstance
Code:
public static void main(String[] args) throws Exception {
UserResource.Builder builder = UserResource.builder();
UserResource userResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(userResource.getV2Users(null, null));
}
The User objects of your Liferay instance appear in JSON.
Read API Query Parameters for more information.
Get a User
Get a specific user with the following cURL or Java command. Replace 1234 with the user’s ID.
Use Users_GET_FromInstance.[java|sh] to get a list of all users, and note the id of the user you want specifically.
Users_GET_ById.sh
Command:
./Users_GET_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--user "test@liferay.com:learn"
Users_GET_ById.java
Command:
java -classpath .:* -DuserId=1234 Users_GET_ById
Code:
public static void main(String[] args) throws Exception {
UserResource.Builder builder = UserResource.builder();
UserResource userResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
userResource.getV2UserById(
String.valueOf(System.getProperty("userId"))));
}
The User fields appear in JSON.
Using Query Parameters
You can filter the data you get by using query parameters. The example below gets users by user name.
Users_GET_ByUserName.sh
Command:
./Users_GET_ByUserName.sh 1234
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users?filter=userName%20eq%20%22${1}%22" \
--user "test@liferay.com:learn"
Query parameters can also be used to refine the data returned. When querying the Users resource, filtering supports only the externalId and userName attributes. For example, you can filter results by modifying the query in the script above like this:
http://localhost:8080/o/scim/v1.0/v2/Users?filter=userName%20eq%20%22${1}%22
Put a User
Update an existing user with the following cURL and Java commands. Replace 1234 with your user’s ID.
Users_PUT_ById.sh
Command:
./Users_PUT_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--data-raw '
{
"emails": [
{
"primary": true,
"type": "default",
"value": "able@liferay.com"
}
],
"name": {
"familyName": "Charlie",
"givenName": "Able"
},
"userName": "able.baker"
}' \
--header "Content-Type: application/scim+json" \
--request "PUT" \
--user "test@liferay.com:learn"
Users_PUT_ById.java
Command:
java -classpath .:* -DuserId=1234 Users_PUT_ById
Code:
public static void main(String[] args) throws Exception {
UserResource.Builder builder = UserResource.builder();
UserResource userResource = builder.authentication(
"test@liferay.com", "learn"
).build();
userResource.putV2User(
String.valueOf(System.getProperty("userId")),
new User() {
{
name = new Name() {
{
familyName = "Charlie";
givenName = "Able";
}
};
emails = new MultiValuedAttribute[] {
new MultiValuedAttribute() {
{
primary = true;
type = "default";
value = "able@liferay.com";
}
}
};
userName = "able.baker";
}
});
}
Deactivate a User
Deactivate an existing user with the following cURL and Java commands. Replace 1234 with your user’s ID.
Users_DELETE_ById.sh
Command:
./Users_DELETE_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--request "DELETE" \
--user "test@liferay.com:learn"
Users_DELETE_ById.java
Command
java -classpath .:* -DuserId=1234 Users_DELETE_ById
Code:
public static void main(String[] args) throws Exception {
UserResource.Builder builder = UserResource.builder();
UserResource userResource = builder.authentication(
"test@liferay.com", "learn"
).build();
userResource.deleteV2User(String.valueOf(System.getProperty("userId")));
}
Patch a User
Liferay DXP 2025.Q2+
Patch an existing user with the following cURL command. Replace 1234 with your user’s ID.
Command:
./Users_PATCH_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--data-raw '
{
"Operations": [
{
"op": "replace",
"path": "name.givenName",
"value": "Abel"
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}' \
--header "Content-Type: application/scim+json" \
--request "PATCH" \
--user "test@liferay.com:learn"
The API Explorer lists all of the User services and schemas and has an interface to try out each service.
Feature Availability by Version
| Feature | Liferay DXP Version | Portal Version | Notes |
|---|---|---|---|
| Mapping SCIM Attributes to Custom Fields | 2025.Q4+ | - | Initially released as a release feature (LPD-56434). Made Generally Available (GA) in Liferay DXP 2026.Q1. |