product-information-management
Centralize product data in a PIM system like Akeneo or Salsify and syndicate enriched content to all your sales channels automatically
Best use case
product-information-management is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Centralize product data in a PIM system like Akeneo or Salsify and syndicate enriched content to all your sales channels automatically
Teams using product-information-management should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/product-information-management/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How product-information-management Compares
| Feature / Agent | product-information-management | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Centralize product data in a PIM system like Akeneo or Salsify and syndicate enriched content to all your sales channels automatically
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Product Information Management
## Overview
A Product Information Management (PIM) system is the single source of truth for product data — names, descriptions, images, attributes, and digital assets — across all channels (website, marketplaces, print catalogs). Akeneo and Salsify are the dominant PIM platforms. This skill covers connecting a PIM as the authoritative source for product enrichment, implementing sync between the PIM and your commerce platform, and building a pipeline that transforms PIM data into channel-specific formats.
## When to Use This Skill
- When product data is inconsistent across your website, marketplace listings, and internal systems
- When the merchandising team manages product content in a PIM and the commerce platform needs to reflect it
- When building a new headless storefront that needs a source of enriched product data
- When adding a new sales channel (marketplace, B2B portal) that needs channel-specific product data
- When auditing product data quality and identifying missing attributes across the catalog
## Core Instructions
### Step 1: Determine your platform and PIM integration approach
| Platform | PIM Integration Option | What It Syncs |
|----------|----------------------|--------------|
| **Shopify** | Akeneo's official **Shopify connector** (free, Akeneo Marketplace) or **Salsify Syndication for Shopify** | Product names, descriptions, images, and attributes → Shopify product metafields; Shopify variants mapped to Akeneo product models |
| **WooCommerce** | **Akeneo WooCommerce Connector** (open-source, GitHub) or custom REST API sync | Product data pushed to WooCommerce via the Products REST API; images uploaded to WordPress media library |
| **BigCommerce** | **Akeneo BigCommerce Connector** (Akeneo Marketplace) or **Salsify for BigCommerce** | Product attributes pushed to BigCommerce custom fields and variants; image syndication to BigCommerce CDN |
| **Custom / Headless** | Direct REST API integration with Akeneo or Salsify | Full control over data mapping; incremental sync via `updated` filter; image upload to your CDN during sync |
### Step 2: Platform-specific PIM integration
---
#### Shopify
**Connect Akeneo to Shopify using the official connector:**
1. In your Akeneo instance, go to **Connect → Marketplace** and install the **Shopify Connector** (free, by Akeneo)
2. Configure a **Connection** in Akeneo (under **Connect → Connections**) with read permissions for Products, Media files, and Attribute options
3. In the connector settings, map your Akeneo channels/locales to your Shopify markets (e.g., Akeneo `en_US` scope → Shopify default language)
4. Map Akeneo attribute codes to Shopify fields:
- `name` → Shopify product title
- `description` → Shopify body HTML
- `price` → Shopify variant price
- Custom attributes → Shopify product metafields (configure under **Settings → Custom data** in Shopify admin)
5. Run an initial full sync and then schedule incremental syncs — the connector pulls only products with `updated > last_sync_at`
**Verify the sync:**
- Go to a product in your Shopify admin and check that the title, description, and images match what's in Akeneo
- Check metafields in the Shopify product page under **Metafields** section
---
#### WooCommerce
**Sync Akeneo to WooCommerce using the REST API:**
The open-source Akeneo WooCommerce Connector (available at github.com/akeneo/woocommerce-connector) provides a starting point, but many merchants build a custom sync script:
1. Set up a cron job (daily or hourly) that:
- Fetches products from Akeneo updated since the last sync using `GET /api/rest/v1/products?search={"updated":[{"operator":">","value":"..."}]}`
- Checks if the product exists in WooCommerce using `GET /wp-json/wc/v3/products?sku={sku}`
- Creates or updates the WooCommerce product using `POST` or `PUT /wp-json/wc/v3/products/{id}`
2. Map Akeneo fields to WooCommerce fields:
- Akeneo `name` (en_US) → WooCommerce `name`
- Akeneo `description` → WooCommerce `description`
- Akeneo `images` → Download and upload to WordPress media library, then set as WooCommerce product images
- Akeneo custom attributes → WooCommerce product attributes or ACF custom fields
3. After each sync, clear WooCommerce's transient cache: `wp transient delete-all` via WP-CLI to ensure updated products appear immediately
---
#### BigCommerce
**Connect Akeneo using the BigCommerce connector:**
1. In Akeneo Marketplace, install the **BigCommerce Connector** and configure your BigCommerce API credentials (Client ID, Client Secret, Access Token from **Advanced Settings → API Accounts**)
2. Map Akeneo families to BigCommerce product types in the connector configuration
3. Configure attribute mappings:
- Akeneo attributes → BigCommerce custom fields or variant option sets
- Akeneo categories → BigCommerce category tree
4. Schedule regular incremental syncs from the connector settings
---
#### Custom / Headless
**Connect to the Akeneo REST API:**
```typescript
// lib/akeneo/client.ts
export class AkeneoClient {
private accessToken: string | null = null;
private tokenExpiry: number = 0;
constructor(private config: {
baseUrl: string; clientId: string; clientSecret: string;
username: string; password: string;
}) {}
async getToken(): Promise<string> {
if (this.accessToken && this.tokenExpiry > Date.now() + 60000) return this.accessToken;
const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString('base64');
const res = await fetch(`${this.config.baseUrl}/api/oauth/v1/token`, {
method: 'POST',
headers: { 'Authorization': `Basic ${credentials}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ grant_type: 'password', username: this.config.username, password: this.config.password }),
});
const data = await res.json();
this.accessToken = data.access_token;
this.tokenExpiry = Date.now() + data.expires_in * 1000;
return this.accessToken!;
}
async getAll(path: string): Promise<any[]> {
const items: any[] = [];
let nextUrl: string | null = path;
while (nextUrl) {
const token = await this.getToken();
const res = await fetch(`${this.config.baseUrl}${nextUrl}`, {
headers: { 'Authorization': `Bearer ${token}` },
});
const page = await res.json();
items.push(...(page._embedded?.items ?? []));
nextUrl = page._links?.next?.href?.replace(this.config.baseUrl, '') ?? null;
}
return items;
}
}
export const akeneo = new AkeneoClient({
baseUrl: process.env.AKENEO_BASE_URL!,
clientId: process.env.AKENEO_CLIENT_ID!,
clientSecret: process.env.AKENEO_CLIENT_SECRET!,
username: process.env.AKENEO_USERNAME!,
password: process.env.AKENEO_PASSWORD!,
});
```
**Transform Akeneo's locale/scope-scoped attribute format into a flat storefront product:**
```typescript
// lib/akeneo/product-transformer.ts
export function transformAkeneoProduct(akeneoProduct: any, locale = 'en_US', scope = 'ecommerce') {
const getValue = (attrCode: string, defaultValue: any = null) => {
const values = akeneoProduct.values[attrCode] ?? [];
const match = values.find(v => v.locale === locale && v.scope === scope)
?? values.find(v => v.locale === locale && v.scope === null)
?? values.find(v => v.locale === null && v.scope === scope)
?? values.find(v => v.locale === null && v.scope === null);
return match?.data ?? defaultValue;
};
return {
sku: akeneoProduct.identifier,
name: getValue('name', '') as string,
description: getValue('description', '') as string,
brand: getValue('brand', '') as string,
categories: akeneoProduct.categories,
attributes: {
color: getValue('color'),
size: getValue('size'),
material: getValue('material'),
},
enabled: akeneoProduct.enabled,
};
}
```
**Incremental sync job (fetch only updated products):**
```typescript
// jobs/akeneo-sync.ts
export async function syncAkeneoProducts() {
const lastSyncAt = await db.syncState.getLastSync('akeneo_products');
const syncStartTime = new Date();
const updatedAt = lastSyncAt?.toISOString() ?? '2020-01-01T00:00:00+00:00';
const products = await akeneo.getAll(
`/api/rest/v1/products?search={"updated":[{"operator":">","value":"${updatedAt}"}]}&limit=100&with_attribute_options=true`
);
let synced = 0, errors = 0;
for (const akeneoProduct of products) {
try {
const storefrontProduct = transformAkeneoProduct(akeneoProduct);
// Validate required fields before upserting
if (!storefrontProduct.name) {
console.warn(`Skipping ${akeneoProduct.identifier}: missing name`);
continue;
}
await db.products.upsert(storefrontProduct.sku, {
...storefrontProduct,
akeneoUpdatedAt: new Date(akeneoProduct.updated),
});
synced++;
} catch (err: any) {
errors++;
await db.syncErrors.insert({ productId: akeneoProduct.identifier, error: err.message });
}
}
await db.syncState.updateLastSync('akeneo_products', syncStartTime);
console.log(`Akeneo sync complete: ${synced} synced, ${errors} errors`);
}
```
**Webhook-triggered sync when Akeneo publishes a product** (Akeneo's Event API):
```typescript
// Register the webhook endpoint in Akeneo under: Connect → Webhooks
// POST /api/webhooks/akeneo
export async function POST(req: NextRequest) {
const event = await req.json();
if (event.event_type === 'product.updated' || event.event_type === 'product.created') {
const sku = event.data.resource.identifier;
const akeneoProduct = await akeneo.getAll(`/api/rest/v1/products/${sku}?with_attribute_options=true`);
const storefrontProduct = transformAkeneoProduct(akeneoProduct);
await db.products.upsert(sku, storefrontProduct);
// Purge CDN cache for this product's page
await revalidateProductPage(storefrontProduct.slug);
}
return NextResponse.json({ received: true });
}
```
## Best Practices
- **Treat the PIM as the source of truth — never write product content back from commerce to PIM** — data flows from PIM to commerce; only push back to PIM for data the PIM explicitly manages (e.g., SEO metadata your platform generates)
- **Use incremental sync, not full sync** — fetching all products every 15 minutes is expensive; use Akeneo's `updated` filter to fetch only changed products
- **Upload images to your own CDN during sync** — Akeneo media file URLs are internal API URLs requiring authentication; never serve them directly to customers; upload to S3/R2/Cloudinary during sync
- **Cache attribute options locally** — color, size, and material option label lookups change rarely; cache them in Redis and refresh hourly to avoid per-product API calls
- **Validate required attributes before syncing to the storefront** — a product without a name or primary image should not be published; add validation before upsert
## Common Pitfalls
| Problem | Solution |
|---------|----------|
| Sync fails on products with missing required attributes | Wrap each product sync in try/catch; log the product identifier with the error; skip and continue rather than aborting the entire sync |
| Images not available after sync | Akeneo media URLs require authentication; download and re-upload to your CDN during sync — never serve `akeneo-base-url/api/rest/v1/media-files/...` directly |
| Akeneo API rate limits | Use batched requests and run syncs off-peak; cache attribute options locally to reduce API calls per product |
| Category mapping out of sync after PIM reorganization | Build a category sync job that runs before the product sync; alert when an Akeneo category code has no mapping in your commerce platform |
| Shopify connector not syncing metafields | Ensure the metafield namespace and key in the connector configuration match what's configured in **Shopify admin → Settings → Custom data → Products** |
## Related Skills
- @marketplace-connectors
- @webhook-architecture
- @erp-integration
- @analytics-integrationRelated Skills
recently-viewed-products
Show shoppers the products they recently browsed using browser storage so they can easily pick up where they left off on your store
product-page-design
Design high-converting product detail pages with image galleries, variant selectors, social proof, and clear calls-to-action that drive add-to-cart
product-comparison
Let shoppers select multiple products and compare them side-by-side in a table with highlighted differences to help them make the right buying decision
coupon-management
Build a coupon system with percentage and fixed discounts, usage limits per customer, expiration dates, and bulk unique-code generation
payout-split-management
Manage complex payout splits for marketplaces and platforms with seller disbursements, commission calculation, tax withholding, and 1099 reporting
currency-hedging-management
Manage foreign exchange risk for multi-currency ecommerce with FX rate tracking, hedging strategies, and realized/unrealized gain-loss accounting
chargeback-management-prevention
Prevent and manage chargebacks with fraud scoring, compelling evidence automation, Visa CE 3.0 / Mastercom integration, and win-rate optimization
ugc-campaign-management
Source, curate, and display user-generated content at scale with rights management, brand safety moderation, and trust-building social proof galleries
product-launch-campaigns
Plan and execute multi-channel product launches with pre-launch waitlists, early access for VIPs, launch day orchestration, and post-launch momentum
returns-management
Process returns end to end — generate prepaid labels, apply refund or exchange logic, update inventory, and notify customers automatically
product-analytics
Track product performance with sell-through rates, views-to-purchase conversion, dead stock identification, and category-level reporting
product-reviews-ratings
Collect, moderate, and display customer reviews with star ratings, aggregate scores, and structured data markup for Google rich results