Site APIs

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:

  1. Download and unzip Site API Basics.

    curl https://resources.learn.liferay.com/examples/liferay-w9v7.zip -O
    
    unzip liferay-w9v7.zip
    
  2. Use the cURL script to add a new site. On the command line, navigate to the curl folder. Execute the Sites_POST.sh script.

    ./Sites_POST.sh
    

    The 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
    }
    
  3. Open the Global Menu (Global Menu icon) and confirm that the new site appears in the list on the right.

    Use the global menu to see that a new site has been added.

  4. You can also call the REST service using the Java client. Navigate to the java folder and compile the source files:

    javac -classpath .:* *.java
    
  5. Run the Sites_POST class:

    java --add-opens java.base/java.net=ALL-UNNAMED -classpath .:* Sites_POST
    
    Tip

    If you’re using an older version of Liferay on Java 8, remove the --add-opens argument:

    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:

ArgumentsDescription
"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 POSTThe HTTP method to invoke at the specified endpoint
--user "test@liferay.com:learn"Basic authentication credentials
Note

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.

Note

The main method’s comment demonstrates running the class.

The other Java classes follow the same pattern but call different SiteResource methods.

Important

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:

  1. Navigate to the site. Open the Site Menu (Site Menu icon), expand Configuration, and go to Site Settings.

  2. Under Platform, click Site Configuration. The ERC appears in the Details tab.

    The site ERC appears under Details.

Tip

Alternatively, use Sites_GET.[java|sh] to list sites and retrieve their ERCs.

  1. Replace 1234 in 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.

  1. Create a site with permissions

    Assign custom permissions during creation by sending a POST request 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 permissions array, the site is created with default permissions.

    If you include the permissions array, 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"
    
  2. Get Site Permissions

    Permissions are not included in site responses. To retrieve them, use the /v1.0/sites/{siteExternalReferenceCode}/permissions endpoint.

    Example:

    curl \
       "http://localhost:8080/o/headless-admin-site/v1.0/sites/{siteExternalReferenceCode}/permissions" \
       --user "test@liferay.com:learn"
    
  3. Update Site Permissions

    Update the permissions of an existing site using a PUT request. 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.

    Tip

    You 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.

  1. Fetch filtered sites using the getSitesPage endpoint. Retrieve only the sites you need using the filter parameter:

    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:

    ParameterDescription
    /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 dateCreated in descending order (most recent first).
    Tip

    Add 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:desc

    This retrieves only sites with Main in the name.

Maintain Creator Data

When importing sites, you can use the importCreatorStrategy and creatorStrategy query parameters to control how creator information is handled.

ParameterDescription
creatorStrategy=INSERTAdds a new user as the creator if the specified creator is missing in the target system. Required when using importCreatorStrategy=KEEP_CREATOR.
importCreatorStrategy=KEEP_CREATORKeeps the original creator from the exported data. The import fails if the creator does not exist unless creatorStrategy=INSERT is also set.
importCreatorStrategy=OVERWRITE_CREATORReplaces 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"