An Adobe App Builder extension that exports Adobe Commerce product data as a feed compatible with the OpenAI Agentic Commerce Protocol (ACP). This enables merchants to make their products searchable and purchasable through ChatGPT.
Built on the Adobe Commerce Integration Starter Kit with Admin UI SDK integration for seamless Commerce Admin experience.
Note: This version supports Adobe Commerce as a Cloud Service (SaaS) using the Catalog Service GraphQL API. For PaaS (on-premise) deployments, see the legacy configuration section below.
| Feature | Status | Description |
|---|---|---|
| Full Sync | ✅ | Parallel workers for large catalogs (10k+ products) |
| Delta Sync | ✅ | Real-time updates via Commerce Events |
| Scheduled Sync | ✅ | OpenWhisk Alarm (cron-based feed refresh) |
| Feed Endpoint | ✅ | JSONL.GZ format, publicly accessible |
| Admin UI | ✅ | Integrated in Commerce Admin via Admin UI SDK |
| Config API | ✅ | REST API for settings (IMS-authenticated) |
| Sync Management | ✅ | Status, History, Cancel APIs |
# 1. Clone and setup
git clone <repository-url>
cd agentic-ai-commerce-feed-generator
cp env.dist .env
# Edit .env with your Commerce credentials
# 2. Install dependencies
npm install
# 3. Configure workspace
aio login
aio console org select
aio console project select
aio console workspace select
aio app use # Choose 'm' (merge)
# 4. Provision MongoDB database
# Follow the guide: https://developer.adobe.com/app-builder/docs/guides/app_builder_guides/storage/database
# Add the connection string to .env as MONGODB_URI
# 5. Build and Deploy (see Build Workaround below)
cd src/commerce-backend-ui-1/web-src && npm run build && cd ../../..
aio app build --no-web-assets && aio app deploy --no-build --force-deploy
# 6. Onboard events
npm run onboard
npm run commerce-event-subscribeDue to a Parcel compatibility issue with the aio CLI, web assets must be built manually:
# Build web assets manually
cd src/commerce-backend-ui-1/web-src && npm run build && cd ../../..
# Build actions and deploy
aio app build --no-web-assets && aio app deploy --no-build --force-deployThe feed generator uses two synchronization strategies to keep the product feed up-to-date:
A complete catalog synchronization that processes all products from Adobe Commerce. This is used for:
- Initial feed generation
- Periodic re-sync to ensure data consistency
- Manual trigger via Admin UI
The Full Sync uses a distributed worker architecture to handle large catalogs efficiently:
- Orchestrator fetches all product SKUs and creates batches
- Parallel Workers (up to 50) process batches concurrently
- Each worker fetches product details and transforms them to ACP format
- Products are stored in MongoDB with checksums for change detection
Real-time updates triggered by Adobe Commerce Events. Runs automatically every 15 minutes via a scheduled action that processes accumulated events:
com.adobe.commerce.catalog.product.created→ Add new productcom.adobe.commerce.catalog.product.updated→ Update existing productcom.adobe.commerce.catalog.product.deleted→ Remove product from feed
flowchart TB
subgraph Commerce["Adobe Commerce"]
API["Catalog Service<br/>(SaaS GraphQL API)"]
Events["Commerce Events"]
end
subgraph AppBuilder["Adobe App Builder"]
subgraph FullSync["Full Sync"]
Orchestrator["Orchestrator"]
Workers["Parallel Workers<br/>(up to 50)"]
end
subgraph DeltaSync["Delta Sync (every 15 min)"]
Created["created handler"]
Updated["updated handler"]
Deleted["deleted handler"]
end
Transformer["ACP Transformer<br/>(ProductView → ACP)"]
DB[("MongoDB<br/>products collection")]
Serve["Serve Action<br/>(JSONL.GZ Feed)"]
end
Consumer["ACP Feed Consumer<br/>(e.g. OpenAI)"]
API --> Orchestrator
API --> Workers
Events --> Created
Events --> Updated
Events --> Deleted
Orchestrator --> Workers
Workers --> Transformer
Created --> Transformer
Updated --> Transformer
Deleted --> DB
Transformer --> DB
DB --> Serve
Serve -->|"HTTP GET"| Consumer
agentic-ai-commerce-feed-generator/
├── app.config.yaml # App Builder configuration
├── install.yaml # Extension point declaration
├── extension-manifest.json # Extension metadata
├── package.json
├── REQUIREMENTS.md # Detailed requirements
│
├── actions/ # Backend Runtime Actions
│ ├── product/commerce/ # Product sync actions
│ │ ├── full-sync/ # Full catalog sync orchestrator
│ │ ├── sync-worker/ # Parallel worker for batch processing
│ │ ├── serve/ # Feed endpoint (JSONL.GZ)
│ │ ├── consumer/ # Event consumer
│ │ ├── created/ # Product created handler
│ │ ├── updated/ # Product updated handler
│ │ └── deleted/ # Product deleted handler
│ ├── config/ # Configuration API
│ │ ├── get/ # Get config
│ │ └── update/ # Update config
│ ├── sync/ # Sync management API
│ │ ├── status/ # Get sync status
│ │ ├── history/ # Get sync history
│ │ └── cancel/ # Cancel active sync
│ ├── feed-refresh/ # Scheduled sync trigger
│ ├── scheduler/ # OpenWhisk Alarm handler
│ └── shared/ # Shared utilities
│ ├── db-client.js # Database client
│ ├── acp-transformer.js # Commerce → ACP transformer
│ ├── feed-generator.js # JSONL.GZ generator
│ └── delta-sync.js # Delta sync utilities
│
├── src/ # Admin UI Extension
│ └── commerce-backend-ui-1/ # Commerce Admin Extension
│ ├── ext.config.yaml # Extension config
│ ├── actions/
│ │ └── registration/ # Menu registration action
│ └── web-src/
│ ├── index.html
│ └── src/
│ ├── index.js # Bootstrap with EXC Shell
│ ├── App.js # Main app component
│ └── components/
│ ├── Dashboard.js # Dashboard tab
│ ├── Configuration.js # Config tab
│ └── SyncHistory.js # History tab
│
├── scripts/ # Utility scripts
│ └── onboarding/ # Event onboarding
│
└── test/ # Test suites (300 tests)
└── actions/
The Admin UI is integrated directly into the Adobe Commerce Admin using the Admin UI SDK.
Navigate in Commerce Admin to:
ACP Feed Generator
The menu item appears as a top-level entry in the Commerce Admin navigation.
| Tab | Description |
|---|---|
| Dashboard | Product count, sync status, feed URL, manual sync trigger |
| Configuration | Merchant info, feed settings (search/checkout enabled) |
| Sync History | List of past syncs with status, timing, and errors |
The Admin UI runs within the Adobe Experience Cloud Shell, providing:
- IMS authentication automatically passed to API calls
- Consistent Adobe experience
- Seamless navigation within Commerce Admin
For development/testing, access the UI directly via Experience Cloud Shell:
https://experience.adobe.com/?devMode=true#/custom-apps/?localDevUrl=https://<workspace-id>-<project-name>-<stage>.adobeio-static.net/index.html
The feed is publicly accessible for OpenAI to fetch.
Stage Environment:
https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve
Usage:
# Get the feed (JSONL.GZ format)
curl https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve
# Check feed status
curl "https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve?status=true"
# Download and inspect first product
curl -s https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve | gunzip | head -1 | jq .These endpoints require Adobe IMS authentication. When using the Admin UI, authentication is handled automatically.
Base URL (Stage):
https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web
| Method | Endpoint | Description |
|---|---|---|
GET |
/acp-config/get |
Get current configuration |
POST |
/acp-config/update |
Update configuration |
| Method | Endpoint | Description |
|---|---|---|
GET |
/acp-sync/status |
Get current/latest sync status |
GET |
/acp-sync/status?syncId=<id> |
Get status of specific sync |
GET |
/acp-sync/history?limit=10 |
Get sync history |
POST |
/acp-sync/cancel |
Cancel active sync |
POST |
/product-commerce/full-sync |
Trigger full catalog sync |
Without proper IMS authentication, API calls will fail:
curl https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/acp-config/get
# Returns: {"error":"cannot authorize request, reason: missing authorization header"}# Commerce Catalog Service GraphQL Endpoint
COMMERCE_GRAPHQL_ENDPOINT=https://na1-sandbox.api.commerce.adobe.com/<tenant-id>/graphql
COMMERCE_BASE_URL=https://na1-sandbox.api.commerce.adobe.com/<tenant-id>/
# Required: Catalog Service Headers
COMMERCE_ENVIRONMENT_ID=<from Commerce Admin>
COMMERCE_WEBSITE_CODE=base
COMMERCE_STORE_VIEW_CODE=default
COMMERCE_STORE_CODE=main_website_store
COMMERCE_CUSTOMER_GROUP=0
# SaaS Authentication (IMS OAuth)
OAUTH_CLIENT_ID=
OAUTH_CLIENT_SECRET=
OAUTH_SCOPES=AdobeID, openid, read_organizations, ...
# Scheduler (Optional)
SYNC_CRON_EXPRESSION=0 1 * * * # Daily at 1:00 AM UTC| Variable | Location |
|---|---|
COMMERCE_ENVIRONMENT_ID |
Commerce Admin > Stores > Configuration > Services > Commerce Services Connector |
COMMERCE_WEBSITE_CODE |
Commerce Admin > Stores > All Stores > Website Code |
COMMERCE_STORE_CODE |
Commerce Admin > Stores > All Stores > Store Code |
COMMERCE_STORE_VIEW_CODE |
Commerce Admin > Stores > All Stores > Store View Code |
OAUTH_CLIENT_ID/SECRET |
Adobe Developer Console > Project > OAuth Server-to-Server |
# PaaS GraphQL Endpoint
COMMERCE_GRAPHQL_ENDPOINT=https://your-store.commercecloud.adobe.com/graphql
COMMERCE_BASE_URL=https://your-store.commercecloud.adobe.com/rest/
STORE_CODE=default
# PaaS Authentication (OAuth1)
COMMERCE_CONSUMER_KEY=
COMMERCE_CONSUMER_SECRET=
COMMERCE_ACCESS_TOKEN=
COMMERCE_ACCESS_TOKEN_SECRET=The feed follows the OpenAI Agentic Commerce Protocol specification.
{
"is_eligible_search": true,
"is_eligible_checkout": true,
"item_id": "SKU-001",
"title": "Product Name",
"description": "Product description text",
"url": "https://store.com/product/sku-001",
"price": "99.99 USD",
"availability": "in_stock",
"image_url": "https://cdn.store.com/images/sku-001.jpg",
"product_category": "Electronics > Computers",
"brand": "Brand Name",
"condition": "new",
"store_name": "My Store",
"seller_url": "https://store.com",
"return_policy": "https://store.com/returns",
"return_window": 30,
"target_countries": ["US", "CA"],
"store_country": "US",
"group_id": "SKU-001",
"listing_has_variations": false,
"seller_privacy_policy": "https://store.com/privacy",
"seller_tos": "https://store.com/terms"
}| ACP Field | Commerce Source | Notes |
|---|---|---|
item_id |
sku |
Unique product identifier |
title |
name |
Max 150 chars |
description |
description or shortDescription |
HTML stripped, max 5000 chars |
url |
url |
Product page URL (HTTPS required) |
price |
price.regular.amount.value |
Format: "99.99 USD" |
availability |
inStock (boolean) |
true → "in_stock" |
image_url |
images[role="image"].url |
Primary image (HTTPS required) |
product_category |
attributes[name="category_path"].value |
Category path |
brand |
attributes[name="manufacturer"].value |
Brand/manufacturer |
store_name |
config.merchant.store_name |
From configuration |
seller_url |
config.merchant.seller_url |
From configuration |
return_policy |
config.merchant.return_policy_url |
From configuration |
return_window |
config.merchant.return_window_days |
From configuration |
target_countries |
config.merchant.target_countries |
ISO 3166-1 alpha-2 codes |
store_country |
config.merchant.store_country |
ISO 3166-1 alpha-2 code |
# Run all tests (300 tests)
npm test
# Run tests with coverage
npm test -- --coverage
# Run specific test file
npm test -- test/actions/shared/acp-transformer.test.js# Start local development server
aio app run
# View logs
aio app logs
# Deploy to stage
cd src/commerce-backend-ui-1/web-src && npm run build && cd ../../..
aio app build --no-web-assets && aio app deploy --no-build --force-deploy# Check feed content
curl -s https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve | gunzip | head -1 | jq .
# Check sync status
curl -s "https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/product-commerce/serve?status=true" | jq .
# Test authentication requirement
curl -s https://<workspace-id>-<project-name>-<stage>.adobeioruntime.net/api/v1/web/acp-config/get
# Returns: {"error":"cannot authorize request, reason: missing authorization header"}| Issue | Solution |
|---|---|
| Sync Timeout | Increase batch_size or reduce max_parallel_workers in config |
| Feed Empty | Check if products are enabled and visible in Commerce |
| Auth Errors | Verify OAuth credentials in .env |
| Admin UI Not Loading | Ensure extension is deployed and registered in Commerce Admin |
| Build Fails | Use the manual build workaround (see Quick Start) |
# View runtime logs
aio app logs
# View specific action logs
aio runtime activation logs <activation-id>
# List recent activations
aio runtime activation list| Aspect | SaaS (Catalog Service) | PaaS (Legacy) |
|---|---|---|
| GraphQL Endpoint | api.commerce.adobe.com |
Store URL /graphql |
| Products Query | products(skus: [...]) |
products(filter: {...}) |
| Product Types | SimpleProductView, ComplexProductView |
SimpleProduct, ConfigurableProduct |
| Price Structure | price.regular.amount.value |
price_range.minimum_price.regular_price.value |
| Stock Status | inStock (boolean) |
stock_status (enum) |
| Authentication | Magento-* headers + Environment ID | Store header only |
- OpenAI Agentic Commerce Protocol
- Adobe Commerce Integration Starter Kit
- Admin UI SDK Overview
- Admin UI SDK Menu Extension
- Experience Cloud Shell
- App Builder Database
Apache-2.0