Site API Basics
Liferay’s REST APIs provide services for Liferay sites. You can create and edit sites with the API.
The Sites API uses External Reference Codes (ERCs) to reference these elements, enabling consistent identification across instances and supporting batch export and import for improved content management and portability.
Start by seeing an example of adding a new site.
Adding a Site
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.
Then, follow these steps:
-
Download and unzip Site API Basics.
curl https://resources.learn.liferay.com/examples/liferay-w9v7.zip -Ounzip liferay-w9v7.zip -
Use the cURL script to add a new site. On the command line, navigate to the
curlfolder. Execute theSites_POST.shscript../Sites_POST.shThe JSON response shows a new site has been added:
{ "active" : true, "analyticsConfiguration" : { "googleAnalyticsConfiguration" : { } }, "assetAutoTaggingEnabled" : false, "contentSharingWithChildrenEnabled" : true, "defaultLanguageId" : "en_US", "description" : "", "description_i18n" : { }, "descriptiveName" : "My Site", "descriptiveName_i18n" : { "fi-FI" : "My Site", "ar-SA" : "My Site", "hu-HU" : "My Site", "de-DE" : "My Site", "ca-ES" : "My Site", "en-US" : "My Site", "pt-BR" : "My Site", "es-ES" : "My Site", "zh-Hans-CN" : "My Site", "nl-NL" : "My Site", "sv-SE" : "My Site", "fr-FR" : "My Site", "ja-JP" : "My Site" }, "directoryIndexingEnabled" : false, "externalReferenceCode" : "dff0dc09-4124-177d-4adc-cb4b43e7883a", "friendlyUrlPath" : "/my-site", "id" : 43179, "inheritLocales" : true, "key" : "My Site", "locales" : [ "en-US", "ar-SA", "ca-ES", "zh-CN", "nl-NL", "fi-FI", "fr-FR", "de-DE", "hu-HU", "ja-JP", "pt-BR", "es-ES", "sv-SE" ], "manualMembership" : true, "membershipRestriction" : 0, "membershipType" : "restricted", "mentionsEnabled" : false, "name" : "My Site", "name_i18n" : { "en-US" : "My Site" }, "parentSiteExternalReferenceCode" : "", "ratingsTypes" : { }, "sharingEnabled" : false, "trashEnabled" : false, "trashEntriesMaxAge" : 0 } -
Open the Global Menu (
) and confirm that the new site appears in the list on the right.
-
You can also call the REST service using the Java client. Navigate to the
javafolder and compile the source files:javac -classpath .:* *.java -
Run the
Sites_POSTclass:java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* Sites_POSTTipIf you’re using an older version of Liferay on Java 8, remove the
--add-opensargument:java -classpath .:* Sites_POST
Examine the cURL Command
The Sites_POST.sh script calls the REST service with a cURL command.
curl \
"http://localhost:8080/o/headless-admin-site/v1.0/sites" \
--data-raw '
{
"name": "My Site"
}' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn"
Here are the command’s arguments:
| Arguments | Description |
|---|---|
"http://localhost:8080/o/headless-admin-site/v1.0/sites" | The REST service endpoint |
--data-raw "{\"name\": \"My Site\"}" | The data you are requesting to post |
--header "Content-Type: application/json" | Indicates that the request body format is JSON. |
--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, authorize users via OAuth2. See Using OAuth2 to Authorize Users for a sample React application that uses OAuth2.
The other cURL commands use similar JSON arguments.
Examine the Java Class
The Sites_POST.java class adds a site by calling the SiteResource service.
public static void main(String[] args) throws Exception {
SiteResource.Builder builder = SiteResource.builder();
SiteResource siteResource = builder.authentication(
"test@liferay.com", "learn"
).build();
Site site = siteResource.postSite(
new Site() {
{
name = "My Site";
}
});
System.out.println(site);
}
}
This class invokes the REST service in a few lines of code:
| Line (abbreviated) | Description |
|---|---|
SiteResource.Builder builder = ... | Gets a Builder for generating a SiteResource service instance. |
SiteResource siteResource = builder.authentication(...).build(); | Specifies basic authentication and generates a SiteResource service instance. |
Site site = siteResource.postSite(...); | Calls the siteResource.postSite method and passes the data to post. |
Note that the project includes the com.liferay.headless.admin.site.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.
The main method’s comment demonstrates running the class.
The other Java classes follow the same pattern but call different SiteResource methods.
See SiteResource for service details.
Below are examples of calling other Site REST services using cURL and Java.
Get Sites
You can list sites using cURL or Java.
Sites_GET.sh
Command:
./Sites_GET.sh
Code:
curl \
"http://localhost:8080/o/headless-admin-site/v1.0/sites" \
--header "Accept: application/json" \
--request "GET" \
--user "test@liferay.com:learn"
Sites_GET.java
Command:
java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* Sites_GET
Code:
public static void main(String[] args) throws Exception {
SiteResource.Builder builder = SiteResource.builder();
SiteResource siteResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(siteResource.getSitesPage(null, null, null));
}
}
The sites objects appear in JSON.
Get a Site
Get a specific site using its External Reference Code (ERC).
Find the ERC in the POST response or in the site settings:
-
Navigate to the site. Open the Site Menu (
), expand Configuration, and go to Site Settings. -
Under Platform, click Site Configuration. The ERC appears in the Details tab.

Alternatively, use Sites_GET.[java|sh] to list sites and retrieve their ERCs.
- Replace
1234in the following commands with the site’s ERC.
Sites_GET_ByExternalReferenceCode.sh
Command:
./Sites_GET_ByExternalReferenceCode.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-admin-site/v1.0/sites/${1}" \
--header "Accept: application/json" \
--request "GET" \
--user "test@liferay.com:learn"
Sites_GET_ByExternalReferenceCode.java
Command:
java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* -DsiteExternalReferenceCode=1234 Sites_GET_ByExternalReferenceCode
Code:
public static void main(String[] args) throws Exception {
SiteResource.Builder builder = SiteResource.builder();
SiteResource siteResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
siteResource.getSite(
System.getProperty("siteExternalReferenceCode")));
}
}
The Site fields appear in JSON.
Put a Site
Overwrite an existing site. Note, replace 1234 with your site’s ERC.
Sites_PUT_ByExternalReferenceCode.sh
Command:
./Sites_PUT_ByExternalReferenceCode.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-admin-site/v1.0/sites/${1}" \
--data-raw '
{
"name": "My Updated Site"
}' \
--header "Content-Type: application/json" \
--request "PUT" \
--user "test@liferay.com:learn"
Sites_PUT_ByExternalReferenceCode.java
Command:
java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* -DsiteExternalReferenceCode=1234 Sites_PUT_ByExternalReferenceCode
Code:
public static void main(String[] args) throws Exception {
SiteResource.Builder builder = SiteResource.builder();
SiteResource siteResource = builder.authentication(
"test@liferay.com", "learn"
).build();
Site site = siteResource.putSite(
System.getProperty("siteExternalReferenceCode"),
new Site() {
{
name = "My Updated Site";
}
});
System.out.println(site);
}
}
Delete a Site
Delete an existing site using its ERC. Note, replace 1234 with your site’s ERC.
Sites_DELETE_ByExternalReferenceCode.sh
Command:
./Sites_DELETE_ByExternalReferenceCode.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-admin-site/v1.0/sites/${1}" \
--request "DELETE" \
--user "test@liferay.com:learn"
Sites_DELETE_ByExternalReferenceCode.java
Command
java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* -DsiteExternalReferenceCode=1234 Sites_DELETE_ByExternalReferenceCode
Code:
public static void main(String[] args) throws Exception {
SiteResource.Builder builder = SiteResource.builder();
SiteResource siteResource = builder.authentication(
"test@liferay.com", "learn"
).build();
siteResource.deleteSite(
System.getProperty("siteExternalReferenceCode"));
}
}
The API Explorer lists all Site services and schemas and has an interface to try out each service.
Site Management via Batch Engine
The Sites API supports batch export and import for migrating sites and related entities across Liferay instances. You can include associated permissions, apply filters to refine results, and configure how creator data is handled during import and export requests.
For details on using the batch engine, see Exporting and Importing Data using the Batch Engine API.
Site Permissions
Manage site permissions using these API endpoints. Replace {siteExternalReferenceCode} with the site’s ERC.
-
Create a site with permissions
Assign custom permissions during creation by sending a
POSTrequest to the endpoint. The specified roles must already exist. If a specified role does not exist, the API returns a 404 error.If you omit the
permissionsarray, the site is created with default permissions.If you include the
permissionsarray, Liferay applies the specified roles and actions during site creation.Example:
curl \ "http://localhost:8080/o/headless-admin-site/v1.0/sites" \ --data-binary ' { "name": "My Site", "permissions": [ { "roleName": "Owner", "actionIds": ["VIEW", "UPDATE"] } ] }' \ --header "Content-Type: application/json" \ --request "POST" \ --user "test@liferay.com:learn" -
Get Site Permissions
Permissions are not included in site responses. To retrieve them, use the
/v1.0/sites/{siteExternalReferenceCode}/permissionsendpoint.Example:
curl \ "http://localhost:8080/o/headless-admin-site/v1.0/sites/{siteExternalReferenceCode}/permissions" \ --user "test@liferay.com:learn" -
Update Site Permissions
Update the permissions of an existing site using a
PUTrequest. Replace{siteExternalReferenceCode}with the site’s ERC.This operation replaces all existing site permissions. Only the roles and actions included in the request remain after the update.
TipYou can find the site ERC while getting sites.
Example:
curl \ "http://localhost:8080/o/headless-admin-site/v1.0/sites/{siteExternalReferenceCode}/permissions" \ --data-binary ' [ { "actionIds": ["VIEW", "UPDATE", "DELETE", "PERMISSIONS"], "roleName": "Owner" } ]' \ --header "Content-Type: application/json" \ --request "PUT" \ --user "test@liferay.com:learn"
Filter Data
You can use filters to refine which sites to fetch.
-
Fetch filtered sites using the
getSitesPageendpoint. Retrieve only the sites you need using thefilterparameter:curl \ "http://localhost:8080/o/headless-admin-site/v1.0/sites?filter=dateCreated%20le%202025-07-18T14%3A25%3A00Z&sort=dateCreated%3Adesc" \ --header "Content-Type: application/json" \ --request "GET" \ --user "test@liferay.com:learn"Here’s how the query parameters work:
Parameter Description /o/headless-admin-site/v1.0/sitesEndpoint to fetch sites using the headless admin site API. filter=dateCreated%20le%202025-07-18T14%3A25%3A00ZURL-encoded. Refines results to include only sites created on or before July 18, 2025, at 14:25 UTC. sort=dateCreated%3AdescURL-encoded. Orders results by dateCreatedin descending order (most recent first).TipAdd a
search=parameter to retrieve specific sites by name. For example,/o/headless-admin-site/v1.0/sites?filter=dateCreated%20le%202025-07-18T14%3A25%3A00Z&search=Main&sort=dateModified:descThis retrieves only sites with
Mainin the name.
Maintain Creator Data
When importing sites, you can use the importCreatorStrategy and creatorStrategy query parameters to control how creator information is handled.
| Parameter | Description |
|---|---|
creatorStrategy=INSERT | Adds a new user as the creator if the specified creator is missing in the target system. Required when using importCreatorStrategy=KEEP_CREATOR. |
importCreatorStrategy=KEEP_CREATOR | Keeps the original creator from the exported data. The import fails if the creator does not exist unless creatorStrategy=INSERT is also set. |
importCreatorStrategy=OVERWRITE_CREATOR | Replaces the original creator with the importing user. All imported sites are assigned to the user performing the import. Defaults to this if omitted. |
Example:
curl \
"http://localhost:8080/o/headless-batch-engine/v1.0/import-task/com.liferay.headless.admin.site.dto.v1_0.Site?creatorStrategy=INSERT&importCreatorStrategy=KEEP_CREATOR" \
--data-raw '
[
{
"name": "My Imported Site",
"externalReferenceCode": "my-site-001"
}
]' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn"