Prerequisite knowledge

  • Understanding of AEM Mobile
  • Knowledge of creating and publishing content through the standard On-Demand Portal
  • Experience with the On-Demand Services API

Required products

  • AEM Mobile
  • API key
  • Access to the On-Demand Services API



The AEM Mobile On-Demand Services SDK for PHP is a library that enables third-party developers to easily integrate with the On-Demand Services API (previously called the "Content Producer Service API").

The SDK will help PHP developers by taking care of various overheads, such as best practices, failsafes for errors, and minor but important guidelines such as setting the correct headers per API request.

Download the On-Demand Services SDK for PHP


By downloading the software listed below, I acknowledge that I have read and agreed to the terms of the APIs for Experience Manager Mobile Services License, the Terms of Use, and the Adobe Online Privacy Policy.

Laadi alla

For a list of recent changes, see the change log at the end of this document.

Understanding the concepts

The On-Demand Services API will require authorized access; therefore, it is important to understand and complete this section before continuing.


For each client (HTTPS) request made using the On-Demand Services API, you must provide the following in the request headers:

  • X-Dps-Api-Key: {{client_id}}
  • Authorization: Bearer {{access token}}

The API key will grant the client access to the On-Demand Services API, while the access token identifies the client account.

To request an API key, please view the On-Demand Services API documentation, and download and complete the request form as described in the documentation.

After receiving the API key, you can generate an access token. To generate the access token, do the following:

  1. Go to the AEX Device Token Generator.
  2. Enter a valid client ID.
  3. Sign in with a valid Adobe ID.
  4. If successful, a device Id and device token will be generated.
  5. Make an API request using the client Id, device Id and device token to generate the access token.

Authentication notes:

  • The access token will expire within 24 hours.
  • The device Id and device token will autorenew itself as long as it is being used. The client can use the device Id and token to generate new access tokens when needed.
  • The device Id and device token will become invalid if the password for the account that was used to generate them was updated. If that happens, please generate a new set of device Ids and device tokens.



During the API key request process, you can request as many as three Adobe IDs that will be granted access to the AEX Device Token Generator. That means that you can only gain access to projects within a maximum of three Adobe IDs. However, with our new Roles & Permissions, you add the Adobe ID to any number of projects.

For example, if you have projects in account A, B, and C, you can add account A to projects in account B and C. This way, you will only need to generate the device Id and device token for account A and it will have access to projects within account A, B, and C.

Getting started

The SDK for PHP follows the PHP PSR-4 workflow, utilizing autoloader and namespace to load the necessary classes.


The autoloader is located in /aemmobilesdk/vendor/autoload.php. You can load the autoloader using the following method, replacing the path/to portion depending on the location of the PHP file relative to the autoloader:



The namespace to the class name will follow the folder structure within /aemmobilesdk/. For example, the “Article” class object is located in /aemmobilesdk/contentService/Article.php, and the namespace would be as follows:

use aemmobilesdk\contentService\Article

Please note that the namespace is case-sensitive in some versions of PHP; it is best to use the exact case of folder/file name.


Each class object represents a component in AEM Mobile, and will handle only within its own area of expertise. For example, the “Article” class object will handle only article-related tasks, such as uploading an .article zip file. You will not be able to use an “Article” class object to add an article to a collection, that is what the “Collection” class object is for.

Setting up

All class objects will require an instance of the user client during its initialization. All abstract class objects should not be initialized (nor can they be).

User Client

The “User” class object represents the user client, it will contain the following:

  • client credentials
  • client project Id
  • API request execution

To initialize the user client, you will need to specify the namespace (as with other class objects):

use aemmobilesdk\userService\User; 
$objUser = new User();

The client credentials can be set in /aemmobilesdk/configuration/Credentials.php and it will be automatically loaded or during run time by calling the following functions:


To generate the access token, you can call the following two functions, which requests for and stores the access token in PHP Session, respectively:


To target a project, you must specify the project Id:


The project Id can be found either from the URL in the dashboard (i.e. or via the API. To use the latter, you can use the following function to get the list of projects that is associated with this user client:

$arrPermissionList = $objUser->getResponse();

As a best practice, you should verify that the client user have the correct roles & permissions prior to accessing the specified project:


API Request

Each class object functions will correctly generate the request headers and data, but the actual execution lies in the “User” class object, as mentioned earlier. To initialize the class object, it is similar process to initializing the user client:

use aemmobilesdk\contentService\Article; 
$objArticle = new Article($objUser);

Data persistency

The user is in charge of keeping the persistence of the metadata. For example, there is a collection has two articles and a banner, and you want to add a third article to the collection. You must first get the list of the existing two articles and banner within this collection, append (or prepend) the third article into the list, then update the collection with all four items. Otherwise, if you just update the collection with the third article, the collection will now only have the third article, the other three will be removed.

Experimenting with recipes

We have provided recipes that you can use for proof of concepts. They are located in /recipes/.

Exporting a project

Before continuing, ensure that you have the following credentials:

  • Client ID (API key)
  • Client Secret (secret associated with the API key)
  • Device ID
  • Device Token

To get the above credentials, see Understanding the concepts.

Roles and permissions

When exporting from a project, you will need the following permissions:

  • Manage Apps
  • View Content
  • View Layouts and Cards
  • View Products and Subscriptions

Set up and export a project

Fill out all the fields in the configuration file located at /aemmobile/configuration/Credentials.php using the credentials. The script to export a project can be found at recipes/project/exportProject.php. You can either run it from the terminal or a PHP server.

To export a project, create a snapshot of the source project and run the following command to run the script:

php ./exportProject.php {{publicationId}} {{downloadDirectory}} {{exportList}} {{lastEntityName}}

  • The {{publicationId}} is the source project ID.
  • The {{downloadDirectory}} is an optional parameter. If not provided, then the script will download the entity to a folder relative to the script: ./export_dps_{{publicationId}}.
  • The {{exportList}} is an optional list parameter, separated by commas. If provided, the script will only export the entities from the list. Otherwise, it will export everything in the project (default). The available {{exportList}} are as follows:

publication, cardTemplate, layout, article, banner, dynamicBanner, sharedContent, collection, font

  • The {{lastEntityName}} is an optional entity name parameter. If provided, the script will attempt to start the download from this entity name.

Change log


2021/02/25 Updates

  • Added recipe to download an AEMM project (excluding the apps). The exportProject.php recipe downloads the content of a project except for the apps (Android/iOS/Windows) built in it.

2016/11/01 Updates

  • Added support and recipes for Dynamic Banner.
  • Added support for uploading PDF directly to the Ingestion Service (Article only).

2016/02/22 Updates

  • The SDK directory is updated from dps2015sdk to aemmobilesdk. All existing and future PHP SDK namespaces should be updated to aemmobilesdk (specifically, use aemmobilesdk\userService\User;).
  • Added an optional parameter to Entity::publish() and Entity::unpublish(). This will allow bulk publish and unpublished actions. The optional parameter should contain an array list of entity HREF with head versions.
  • Added an optional parameter to Entity::getHref(). This will allow the curation of the entity HREF without the head version. Mainly used for adding entities to a collection, since it is optional to provide the head version.
  • Updated the logic in recipes/publication/reset.php (previously as deleteAll.php). This recipe will now use the updated bulk Entity::unpublish() to unpublish a list of entities (based on dependencies) rather than unpublishing individually.

2016/01/06 Updates

  • Stores the necessary entity metadata internal to.
  • Entity class after making an Entity::update() request.
  • Added Collection::removeEntity() to remove a specific entity from the list of collection content elements stored in the Collection class. Will need to call Collection::requestContentElements() prior to using this new function; otherwise, the list within the Collection class will be empty.
  • Added an Utility static class to handle more generic functions, such as generate timestamp, pretty-print objects, and so on.
  • In recipes/product/genIssueList.php, the recipe will now download the thumbnail (and background) images, if available and not already downloaded. A separate recipe (see recipes/product/downloadImage.php) was created to only download the images, alleviating the load time of genIssueList.php.
  • Added a recipe to add an article to a collection (see recipes/collection/addArticle.php).
  • Added a recipe to remove an article from a collection (see recipes/collection/removeArticle.php).
  • Added a recipe to publish all entities (not just the immediate entities) of a collection (see recipes/collection/publishAllChildren.php).