Overview
AEM Guides is Adobe’s enterprise-grade component content management system (CCMS) built on AEM. It enables structured authoring using the DITA standard, supports multi-channel publishing, and provides robust version control and translation workflows for technical documentation teams. Gradial’s AI agents integrate with AEM Guides to automate content creation, updates, translation tasks, and quality assurance across your DITA-based content libraries. This page covers the full end-to-end setup for Native PDF Publishing on AEM as a Cloud Service (AEMaaCS), including the credential and OSGi configuration required to connect AEM author to Adobe’s publishing microservice.What Native PDF Publishing Actually Requires
Three independent things must all be true:- AEM Guides authoring entitlement on the program — gives you the Web Editor, output presets UI, templates UI, and fmdita JCR setup. This is a paid Adobe add-on sold separately from base AEMaaCS Sites/Assets.
- AEM Guides publishing tenant provisioned by Adobe — the customer-specific Adobe I/O Runtime tenant that renders PDFs. This is a separate Adobe-side provisioning step from #1. Contact your Adobe Customer Success representative to confirm this is in place.
- A correctly-scoped IMS service account in your AEMaaCS environment — the OAuth Server-to-Server credential that AEM author uses to authenticate calls to the publishing tenant. This is the step most often misconfigured.
Prerequisites
- An AEMaaCS program with AEM Guides provisioned by Adobe Customer Success
- Admin access to Adobe Cloud Manager (
experience.adobe.com) - Admin access to Adobe Developer Console (
developer.adobe.com/console) - Admin access to Adobe Admin Console (
adminconsole.adobe.com) - Ability to push to the implementation repository’s
mainbranch and trigger Cloud Manager pipelines - AEM 6.5 or AEM as a Cloud Service with the AEM Guides add-on installed and licensed
Authentication
AEM Guides runs on top of AEM, so authentication follows the same model as your underlying AEM environment:- AEM 6.5 with AEM Guides: Use OAuth 2.0 authentication — refer to the AEM 6.5 setup guide.
- AEM Cloud with AEM Guides: Use Adobe IMS authentication — refer to the AEM Cloud setup guide.
End-to-End Setup for Native PDF Publishing
Phase 1 — Confirm AEM Guides is provisioned
- In Cloud Manager → Programs → your program → Solutions and Add-ons, confirm “AEM Guides” appears.
- If it doesn’t appear, contact your Adobe Customer Success team — AEM Guides is a paid add-on with no self-serve provisioning path.
- Verify the publishing tenant exists. When you fire a publish job, the output history entry’s
cloudPublishJobIdfield will be populated with a UUID (e.g.,bec82ef6-b151-44f2-9bcc-5db3b8b357d6). If publishes get stuck inoutputStatus=Waitingindefinitely, the tenant is not provisioned — open an Adobe Engineering ticket referencing your program ID.
Phase 2 — Adobe Developer Console: OAuth credential
Adobe Developer Console is where you create the IMS service-account credential that AEM author uses to authenticate outbound calls to the publishing microservice. Use OAuth Server-to-Server, not JWT. Adobe deprecated JWT credentials on June 30, 2025.2.1 Create or open the Developer Console project
- Go to https://developer.adobe.com/console.
- Confirm the org switcher (top-right) shows the same Adobe org that owns your AEMaaCS environment. If the org is wrong, every credential you create will fail with “different org” errors at runtime.
- Open or create a project.
2.2 Add APIs to the project
Add these APIs (Add API → search):| API | Why it’s needed |
|---|---|
| I/O Management API | Critical for Native PDF Publishing. Grants ent_adobeio_sdk scope, which authorizes calls to adobeioruntime.net. Without it, publishing fails with IMS credentials of different org are used (Adobe’s error message is misleading — the org is correct; the scope is missing). |
| AEM Assets Author API | General AEM author API access |
| AEM CS Sites Content Management | AEM Sites API access |
2.3 Create the OAuth Server-to-Server credential
- In the project, click Add credential → OAuth Server-to-Server.
- Associate it with all the APIs added above.
- Save. You’ll receive
CLIENT_ID,CLIENT_SECRET,TECHNICAL_ACCOUNT_ID, and scopes.
2.4 Download the project JSON
- Project overview → Download (top-right).
- Verify the scopes array contains
ent_adobeio_sdkbefore continuing. If it doesn’t, the I/O Management API was not added correctly in step 2.2.
Phase 3 — Cloud Manager: environment secret
- Cloud Manager → Programs → your program → Environments → your env → Configuration tab.
- Create environment variable
SERVICE_ACCOUNT_DETAILS(type: Secret). - Value: paste the complete contents of the project JSON file from step 2.4 (the entire
{ "project": { ... } }wrapper). - Save.
If migrating from a deprecated JWT setup, also delete the old
PRIVATE_KEY variable if it exists.Phase 4 — Code repository: OSGi configs
Three config files live inui.config/src/main/content/jcr_root/apps/<your-app>/osgiconfig/config.author.<env>/. Create the same three files under each environment directory (dev, stage, prod).
com.adobe.aem.guides.eventing.ImsConfiguratorService.cfg.json
com.adobe.fmdita.publishworkflow.PublishWorkflowConfigurationService.cfg.json
com.adobe.fmdita.config.ConfigManager.cfg.json (optional)
Phase 5 — Deploy
Commit and push the OSGi config changes. Run a Cloud Manager pipeline to apply. If only theSERVICE_ACCOUNT_DETAILS secret was updated (no code changes), restart the AEM author tier via Cloud Manager → Environment → ⋮ → Restart.
Phase 6 — AEM Author: templates and presets
Native PDF templates
The OOTB Native PDF templates ship with the AEM Guides module itself. Once Adobe enables AEM Guides on your program, three templates are already present in JCR at/content/dam/dita-templates/pdf/:
BasicHi-TechPrime
Output presets per ditamap
- Open the ditamap in the Web Editor → Map console → Output Presets.
- Click + to add a preset.
- Configure: Type: PDF, Target: Native PDF, Layout → Template: pick your template.
- Set the output path and PDF filename.
- Click Generate output to test.
Verification
A successful Native PDF publish progresses through these states (poll/var/dxml/metadata/outputHistory/<map-uuid>/<gen-id>.json):
ditaotFaliure: false(Adobe’s typo) — this is the authoritative success flagoutputStatus: FinishedANDcloudStatus: FinishedoutputPathis populated
errorsExist: true can appear even on a successful run (soft warnings about unresolvable hrefs). Do not use it as a failure signal.
Troubleshooting
Generate output queues a workflow but it hangs at outputStatus=Waiting
Generate output queues a workflow but it hangs at outputStatus=Waiting
The Granite workflow engine accepted the job but the publish step is wedged. Most likely cause: the publishing tenant is not provisioned.Fix: Open an Adobe Engineering ticket referencing the program ID and workflow ID, and ask them to confirm the Guides publishing tenant is registered.
Workflow fails immediately with 'IMS credentials of different org are used'
Workflow fails immediately with 'IMS credentials of different org are used'
Output shows
outputStatus=Finished, cloudStatus=Failed, ditaotFaliure=true. Despite the error message, the org is almost certainly correct — the actual cause is the credential’s access token is missing the ent_adobeio_sdk scope because the I/O Management API was not added to the Developer Console project.Fix: Adobe Developer Console → project → Add API → I/O Management API → associate with the existing OAuth S2S credential → download the project JSON → paste into Cloud Manager SERVICE_ACCOUNT_DETAILS → run a pipeline or restart the author pod.outputStatus=Executing, cloudStatus=Trigger-Successful for 10+ minutes
outputStatus=Executing, cloudStatus=Trigger-Successful for 10+ minutes
This is normal for Native PDF rendering on a large map. Adobe I/O Runtime has accepted the job and is rendering. For a map with 50+ topics and many images, 10–20 minutes is typical. If it goes beyond 30 minutes, contact Adobe.
Templates → Layout dropdown shows only '(Default)'
Templates → Layout dropdown shows only '(Default)'
The selected output preset has an empty
templatePath. Usually caused by a stale global preset that referenced a deleted demo ditamap.Fix: Delete the stale global preset at /var/dxml/folderprofiles/global-profile/presets/<uuid> via CRXDE Lite. Create a fresh per-map preset and explicitly select a template.