How to invoke OpenAPI-based AEM APIs invoke-openapi-based-aem-apis
Learn how to configure and invoke OpenAPI-based AEM APIs on AEM as a Cloud Service from custom applications.
In this tutorial, you learn how to:
- Enable OpenAPI-based AEM APIs access for your AEM as a Cloud Service environment.
- Create and configure an Adobe Developer Console (ADC) project to access AEM APIs using OAuth Server-to-Server authentication.
- Develop a sample NodeJS application that calls the Assets Author API to retrieve metadata for a specific asset.
Before you start, make sure you reviewed the Accessing Adobe APIs and related concepts section.
Prerequisites
To complete this tutorial, you need:
-
Modernized AEM as a Cloud Service environment with the following:
- AEM Release
2024.10.18459.20241031T210302Z
or later. - New style Product Profiles (if environment was created before November 2024)
- AEM Release
-
The sample WKND Sites project must be deployed on to it.
-
Access to the Adobe Developer Console.
-
Install Node.js on your local machine to run the sample NodeJS application.
Development steps
The high-level development steps are:
-
Modernization of AEM as a Cloud Service environment.
-
Enable AEM APIs access.
-
Create Adobe Developer Console (ADC) Project.
-
Configure ADC Project
- Add desired AEM APIs
- Configure its authentication
- Associate Product Profile with the authentication configuration
-
Configure the AEM instance to enable ADC Project communication
-
Develop a sample NodeJS application
-
Verify the end-to-end flow
Modernization of AEM as a Cloud Service environment
Let’s start by modernizing the AEM as a Cloud Service environment. This step is only needed if the environment is not modernized.
Modernization of the AEM as a Cloud Service environment is a two-step process,
- Update to the latest AEM release version
- Add new Product Profiles to it.
Update AEM instance
To update the AEM instance, in the Adobe Cloud Manager’s Environments section, select the ellipsis icon next to the environment name and select Update option.
Then click the Submit button and run the suggested Fullstack Pipeline.
In my case, the name of Fullstack Pipeline is Dev :: Fullstack-Deploy and the AEM environment name is wknd-program-dev it may vary in your case.
Add new Product Profiles
To add new Product Profiles to the AEM instance, in the Adobe Cloud Manager’s Environments section, select the ellipsis icon next to the environment name and select the Add Product Profiles option.
You can review the newly added Product Profiles by clicking on the ellipsis icon next to the environment name and selecting Manage Access > Author Profiles.
The Admin Console window displays the newly added Product Profiles.
The above steps complete the modernization of the AEM as a Cloud Service environment.
Enable AEM APIs access
New Product Profiles enable OpenAPI-based AEM API access in the Adobe Developer Console (ADC).
The newly added Product Profiles are associated with the Services that represent AEM user groups with predefined Access Control Lists (ACLs). The Services are used to control the level of access to the AEM APIs.
You can also select or deselect the Services associated with the Product Profile to reduce or increase the level of access.
Review the association by clicking on the View Details icon next to the Product Profile name.
By default, the AEM Assets API Users Service is not associated with any Product Profile. Let’s associate it with the newly added AEM Administrators - author - Program XXX - Environment XXX Product Profile. After this association, the ADC Project’s Asset Author API can setup the OAuth Server-to-Server authentication and associate the authentication account with the Product Profile.
It is important to note that before the modernization, in AEM Author instance, two Product Profiles were available, AEM Administrators-XXX and AEM Users-XXX. It is also possible to associate these existing Product Profiles with the new Services.
Create Adobe Developer Console (ADC) Project
Next, create an ADC Project to access AEM APIs.
-
Login to the Adobe Developer Console using your Adobe ID.
-
From the Quick Start section, click on the Create new project button.
-
It creates a new project with the default name.
-
Edit the project name by clicking the Edit project button in the top right corner. Provide a meaningful name and click Save.
Configure ADC Project
Next, configure the ADC Project to add AEM APIs, configure its authentication, and associate the Product Profile.
-
To add AEM APIs, click on the Add API button.
-
In the Add API dialog, filter by Experience Cloud and select the AEM Assets Author API card and click Next.
-
Next, in the Configure API dialog, select the Server-to-Server authentication option and click Next. The Server-to-Server authentication is ideal for backend services needing API access without user interaction.
-
Rename the credential for easier identification (if needed) and click Next. For demo purposes, the default name is used.
-
Select the AEM Administrators - author - Program XXX - Environment XXX Product Profile and click Save. As you can see, only the Product Profile associated with the AEM Assets API Users Service is available for selection.
-
Review the AEM API and authentication configuration.
Configure AEM instance to enable ADC Project communication
To enable the ADC Project’s OAuth Server-to-Server credential ClientID to communication with the AEM instance, you need to configure the AEM instance.
It is done by defining the configuration in the config.yaml
file in the AEM Project. Then, deploy the config.yaml
file using the Config Pipeline in the Cloud Manager.
-
In AEM Project, locate or create the
config.yaml
file from theconfig
folder. -
Add the following configuration to the
config.yaml
file.code language-yaml kind: "API" version: "1.0" metadata: envTypes: ["dev", "stage", "prod"] data: allowedClientIDs: author: - "<ADC Project's OAuth Server-to-Server credential ClientID>"
Replace
<ADC Project's OAuth Server-to-Server credential ClientID>
with the actual ClientID of the ADC Project’s OAuth Server-to-Server credential. The API endpoint that is used in this tutorial is available only on the author tier, but for other APIs, the yaml config can also have a publish or preview node. -
Commit the config changes to the Git repository and push the changes to the remote repository.
-
Deploy the above changes using the Config Pipeline in the Cloud Manager. Note that the
config.yaml
file can also be installed in an RDE, using command line tooling.
Develop a sample NodeJS application
Let’s develop a sample NodeJS application that calls the Assets Author API.
You can use other programming languages like Java, Python, etc., to develop the application.
For testing purposes, you can use the Postman, curl, or any other REST client to invoke the AEM APIs.
Review the API
Before developing the application, let’s review deliver the specified asset’s metadata endpoint from the Assets Author API. The API syntax is:
GET https://{bucket}.adobeaemcloud.com/adobe/assets/{assetId}/metadata
To retrieve the metadata of a specific asset, you need the bucket
and assetId
values. The bucket
is the AEM instance name without the Adobe domain name (.adobeaemcloud.com), for example, author-p63947-e1420428
.
The assetId
is the JCR UUID of the asset with the urn:aaid:aem:
prefix, for example, urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da
. There are multiple ways to get the assetId
:
-
Append the AEM asset path
.json
extension to get the asset metadata. For example,https://author-p63947-e1420429.adobeaemcloud.com/content/dam/wknd-shared/en/adventures/cycling-southern-utah/adobestock-221043703.jpg.json
and look for thejcr:uuid
property. -
Alternatively, you can get the
assetId
by inspecting the asset in the browser’s element inspector. Look for thedata-id="urn:aaid:aem:..."
attribute.
Invoke the API using the browser
Before developing the application, let’s invoke the API using the Try it feature in the API documentation.
-
Open the Assets Author API documentation in the browser.
-
Expand the Metadata section and click on the Delivers the specified asset’s metadata option.
-
In the right pane, click on the Try it button.
-
Enter the following values:
-
The
bucket
value is the AEM instance name without the Adobe domain name (.adobeaemcloud.com), for example,author-p63947-e1420428
. -
The Security section related
Bearer Token
andX-Api-Key
values are obtained from the ADC Project’s OAuth Server-to-Server credential. Click Generate access token to get theBearer Token
value and use theClientID
value as theX-Api-Key
.
-
The Parameters section related
assetId
value is the unique identifier for the asset in AEM. TheX-Adobe-Accept-Experimental
is set to 1.
-
-
Click Send to invoke the API.
-
Review the Response tab to see the API response.
The above steps confirm the modernization of the AEM as a Cloud Service environment, enabling AEM APIs access. It also confirms the successful configuration of the ADC Project, and the OAuth Server-to-Server credential ClientID communication with the AEM author instance.
Sample NodeJS application
Let’s develop a sample NodeJS application.
To develop the application, you can either use the Run-the-sample-application or the Step-by-step-development instructions.
-
Download the sample demo-nodejs-app-to-invoke-aem-openapi application zip file and extract it.
-
Navigate to the extracted folder and install the dependencies.
code language-bash $ npm install
-
Replace the placeholders in the
.env
file with the actual values from the ADC Project’s OAuth Server-to-Server credential. -
Replace the
<BUCKETNAME>
and<ASSETID>
in thesrc/index.js
file with the actual values. -
Run the NodeJS application.
code language-bash $ node src/index.js
-
Create a new NodeJS project.
code language-bash $ mkdir demo-nodejs-app-to-invoke-aem-openapi $ cd demo-nodejs-app-to-invoke-aem-openapi $ npm init -y
-
Install the fetch and dotenv library to make HTTP requests and read the environment variables respectively.
code language-bash $ npm install node-fetch $ npm install dotenv
-
Open the project in your favorite code editor and update the
package.json
file to add thetype
tomodule
.code language-json { ... "version": "1.0.0", "type": "module", "main": "index.js", ... }
-
Create
.env
file and add the following configuration. Replace the placeholders with the actual values from the ADC Project’s OAuth Server-to-Server credential.code language-properties CLIENT_ID=<ADC Project OAuth Server-to-Server credential ClientID> CLIENT_SECRET=<ADC Project OAuth Server-to-Server credential Client Secret> SCOPES=<ADC Project OAuth Server-to-Server credential Scopes>
-
Create
src/index.js
file and add the following code, and replace the<BUCKETNAME>
and<ASSETID>
with the actual values.code language-javascript // Import the dotenv configuration to load environment variables from the .env file import "dotenv/config"; // Import the fetch function to make HTTP requests import fetch from "node-fetch"; // REPLACE THE FOLLOWING VALUES WITH YOUR OWN const bucket = "<BUCKETNAME>"; // Bucket name is the AEM instance name (e.g. author-p63947-e1420428) const assetId = "<ASSETID>"; // Asset ID is the unique identifier for the asset in AEM (e.g. urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da). You can get it by inspecting the asset in browser's element inspector, look for data-id="urn:aaid:aem:..." // Load environment variables for authentication const clientId = process.env.CLIENT_ID; // Adobe IMS client ID const clientSecret = process.env.CLIENT_SECRET; // Adobe IMS client secret const scopes = process.env.SCOPES; // Scope for the API access // Adobe IMS endpoint for obtaining an access token const adobeIMSV3TokenEndpointURL = "https://ims-na1.adobelogin.com/ims/token/v3"; // Function to obtain an access token from Adobe IMS const getAccessToken = async () => { console.log("Getting access token from IMS"); // Log process initiation //console.log("Client ID: " + clientId); // Display client ID for debugging purposes // Configure the HTTP POST request to fetch the access token const options = { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", // Specify form data content type }, // Send client ID, client secret, and scopes as the request body body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=${scopes}`, }; // Make the HTTP request to fetch the access token const response = await fetch(adobeIMSV3TokenEndpointURL, options); //console.log("Response status: " + response.status); // Log the HTTP status for debugging const responseJSON = await response.json(); // Parse the JSON response console.log("Access token received"); // Log success message // Return the access token return responseJSON.access_token; }; // Function to retrieve metadata for a specific asset from AEM const getAssetMetadat = async () => { // Fetch the access token using the getAccessToken function const accessToken = await getAccessToken(); console.log("Getting asset metadata from AEM"); // Invoke the Assets Author API to retrieve metadata for a specific asset const resp = await fetch( `https://${bucket}.adobeaemcloud.com/adobe/assets/${assetId}/metadata`, // Construct the URL with bucket and asset ID { method: "GET", headers: { "If-None-Match": "string", // Header to handle caching (not critical for this tutorial) "X-Adobe-Accept-Experimental": "1", // Header to enable experimental Adobe API features Authorization: "Bearer " + accessToken, // Provide the access token for authorization "X-Api-Key": clientId, // Include the OAuth S2S ClientId for identification }, } ); const data = await resp.json(); // Parse the JSON response console.log("Asset metadata received"); // Log success message console.log(data); // Display the retrieved metadata }; // Call the getAssets function to start the process getAssetMetadat();
-
Run the NodeJS application.
code language-bash $ node src/index.js
API response
Upon successful execution, the API response is displayed in the console. The response contains the metadata of the specified asset.
{
"assetId": "urn:aaid:aem:9c09ff70-9ee8-4b14-a5fa-ec37baa0d1b3",
"assetMetadata": {
...
"dc:title": "A Young Mountain Biking Couple Takes A Minute To Take In The Scenery",
"xmp:CreatorTool": "Adobe Photoshop Lightroom Classic 7.5 (Macintosh)",
...
},
"repositoryMetadata": {
...
"repo:name": "adobestock-221043703.jpg",
"repo:path": "/content/dam/wknd-shared/en/adventures/cycling-southern-utah/adobestock-221043703.jpg",
"repo:state": "ACTIVE",
...
}
}
Congratulations! You have successfully invoked the OpenAPI-based AEM APIs from your custom application using OAuth Server-to-Server authentication.
Review the application code
The key callouts from the sample NodeJS application code are:
-
IMS Authentication: Fetches an access token using OAuth Server-to-Server credentials setup in the ADC Project.
code language-javascript // Function to obtain an access token from Adobe IMS const getAccessToken = async () => { // Configure the HTTP POST request to fetch the access token const options = { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", // Specify form data content type }, // Send client ID, client secret, and scopes as the request body body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=${scopes}`, }; // Make the HTTP request to fetch the access token from Adobe IMS token endpoint https://ims-na1.adobelogin.com/ims/token/v3 const response = await fetch(adobeIMSV3TokenEndpointURL, options); const responseJSON = await response.json(); // Parse the JSON response // Return the access token return responseJSON.access_token; }; ...
-
API Invocation: Invokes the Assets Author API to retrieve metadata for a specific asset by providing the access token for authorization.
code language-javascript // Function to retrieve metadata for a specific asset from AEM const getAssetMetadat = async () => { // Fetch the access token using the getAccessToken function const accessToken = await getAccessToken(); console.log("Getting asset metadata from AEM"); // Invoke the Assets Author API to retrieve metadata for a specific asset const resp = await fetch( `https://${bucket}.adobeaemcloud.com/adobe/assets/${assetId}/metadata`, // Construct the URL with bucket and asset ID { method: "GET", headers: { "If-None-Match": "string", // Header to handle caching (not critical for this tutorial) "X-Adobe-Accept-Experimental": "1", // Header to enable experimental Adobe API features Authorization: "Bearer " + accessToken, // Provide the access token for authorization "X-Api-Key": clientId, // Include the OAuth S2S ClientId for identification }, } ); const data = await resp.json(); // Parse the JSON response console.log("Asset metadata received"); // Log success message console.log(data); // Display the retrieved metadata }; ...
Summary
In this tutorial, you learned how to invoke OpenAPI-based AEM APIs from custom applications. You enabled AEM APIs access, created and configured an Adobe Developer Console (ADC) project.
In the ADC Project, you added the AEM APIs, configured its authentication type, and associated the Product Profile. You also configured the AEM instance to enable ADC Project communication and developed a sample NodeJS application that calls the Assets Author API.