Ecommerce

Akeneo Product Import & Export: CSV, XLSX, Jobs & Channel Feeds

How to design reliable Akeneo product imports and exports—templates, validation, media, job profiles, and channel feeds that survive real catalog volume.

Akeneo Product Import & Export: CSV, XLSX, Jobs & Channel Feeds
Ecommerce 12 min read

Akeneo product import and export is where strategy meets operations. Beautiful family models fail if suppliers cannot load data, or if Amazon and Shopify receive incomplete feeds. This guide covers practical patterns for CSV/XLSX imports, media handling, Akeneo job profiles, and outbound channel syndication that hold up under growth.

An import template is a contract with your catalog—treat it like an API.

Design import templates as contracts

Every import column should map to a known attribute code, locale, and scope (global vs channel). Document required fields, allowed option codes, unit formats, and association columns. Version your templates. When a supplier sends “Blue / blue / BLU,” your import validation should reject or normalize—not silently create three option values that break filters forever.

  • Use stable attribute codes; never rename casually after go-live
  • Keep locale-scoped columns explicit (description-en_US, description-hi_IN)
  • Normalize sizes, colors, and materials into controlled option lists
  • Include a unique product identifier strategy (SKU / UUID) from day one

Import jobs, validation, and iterative cleansing

Run Akeneo import jobs in waves: structure first (families, attributes, categories), then products, then associations and media. Review job reports for missing required attributes and invalid options. Teach enrichers to fix source files or PIM records based on those reports. Iterative cleansing beats heroic one-shot imports that leave half the catalog incomplete.

Media and asset imports

Product images and documents need naming conventions, role mapping (hero, gallery, lifestyle, size chart), and link integrity. Whether you import via paths, DAM connectors, or Akeneo Asset Manager (EE), define what “complete media” means per family. Channel exports often fail because assets are missing—not because titles are wrong.

Export profiles for channels and partners

Outbound Akeneo product exports should be channel-specific. Magento may want HTML descriptions and configurable variants; a marketplace may want flat files with restricted character lengths; a retailer may want EDI-friendly attributes. Build export profiles that filter by completeness and category, transform attribute codes, and exclude draft or discontinued products.

  • Gate exports on completeness scores and required media roles
  • Keep transform rules documented next to each channel profile
  • Schedule exports during low-traffic windows when payloads are large
  • Retain export artifacts for audit and dispute resolution

API vs file-based interchange

Files remain useful for agency workflows and partners with limited engineering. APIs shine for continuous sync and smaller deltas. Many mature Akeneo architectures use both: nightly export jobs for certain channels, plus REST updates for priority SKUs via the official Akeneo API reference.

When you choose API interchange, authenticate once, then create or upsert products with UUID endpoints instead of rebuilding CSV templates for every micro-update. When you need custom file jobs (notify-after-export, XML formats, CSV cleaning), see creating a custom Akeneo connector based on the official create-connector guide:

POST /api/oauth/v1/token Official docs

Get an authentication token

Exchange connection credentials for a Bearer access token. No prior Bearer auth is required for this call.

Headers

  • Content-Type: application/json (or application/x-www-form-urlencoded)
  • Authorization: Basic {base64(client_id:client_secret)}

Parameters

Name In Type Required Description
username body string Yes PIM connection username
password body string Yes PIM connection password
grant_type body string Yes Must be password

Example request

curl -X POST "https://YOUR_PIM_HOST/api/oauth/v1/token" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic $(echo -n 'CLIENT_ID:CLIENT_SECRET' | base64)" \
  -d '{
    "username": "your_connection_username",
    "password": "your_connection_password",
    "grant_type": "password"
  }'

Response — 200 OK

Returns an authentication token used as Authorization: Bearer on later calls.

{
  "access_token": "ZTZmYjU4ZmQxZWNmMzk1M2NlYzA5NmFhNmIzVjExMzE4NmJmODBkZGIyYTliYmQyNjk2ZDQwZThmNjdiZDQzOQ",
  "expires_in": 3600,
  "token_type": "bearer",
  "scope": null,
  "refresh_token": "M3FlODI0OTE3ODMyNjViMzRiOWE5ODMyNWViMThkNDU5YzJjNjFiZjNkZWFjMzIyYjc4YTgzZWY1MjE5ZTY5Mw"
}

Response — 400 Bad Request

Malformed JSON or invalid request framing.

{
  "code": 400,
  "message": "Invalid JSON message received"
}

Response — 422 Unprocessable Entity

Validation failed (wrong grant_type, bad credentials shape, etc.).

{
  "code": 422,
  "message": "Property \"grant_type\" expects a valid grant type. Check the expected format on the API documentation."
}
POST /api/rest/v1/products-uuid Official docs

Create a new product (UUID)

Create a product. If uuid is omitted, Akeneo generates one. Returns 201 with Location header.

Headers

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Parameters

Name In Type Required Description
create_missing_options query string No When present, auto-create missing simple/multi-select options if attribute allows
uuid body string No Optional product UUID
enabled body boolean No Default true
family body string|null No Family code
categories body array[string] No Category codes
groups body array[string] No Group codes
parent body string|null No Parent product model for variants
values body object No Attribute values (locale/scope aware)
associations body object No Product/model/group associations
quantified_associations body object No Quantified associations with quantities

Example request

curl -X POST "https://YOUR_PIM_HOST/api/rest/v1/products-uuid" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "25566245-55c3-42ce-86d9-8610ac459fa8",
    "enabled": true,
    "family": "tshirt",
    "categories": ["summer_collection"],
    "groups": [],
    "parent": null,
    "values": {
      "sku": [{"data": "top", "locale": null, "scope": null}],
      "name": [
        {"data": "Top", "locale": "en_US", "scope": null},
        {"data": "Débardeur", "locale": "fr_FR", "scope": null}
      ],
      "description": [
        {"data": "Summer top", "locale": "en_US", "scope": "ecommerce"}
      ],
      "color": [{"data": "black", "locale": null, "scope": null}],
      "size": [{"data": "m", "locale": null, "scope": null}]
    }
  }'

Response — 201 Created

Product created. Body is empty; Location header points to the new resource.

Headers:
Location: /api/rest/v1/products-uuid/25566245-55c3-42ce-86d9-8610ac459fa8

Body: (empty)

Response — 422 Unprocessable Entity

Validation failed (unknown family, invalid attribute value, etc.).

{
  "code": 422,
  "message": "Validation failed.",
  "errors": [
    {
      "property": "values",
      "message": "The color attribute requires an option that exists in the PIM."
    }
  ]
}
PATCH /api/rest/v1/products-uuid/{uuid} Official docs

Update/create a product (UUID)

Upsert by UUID: updates if present, creates if missing. Supports add_categories / remove_categories. EE may create a draft when rights are limited.

Headers

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Parameters

Name In Type Required Description
uuid path string Yes Product UUID
create_missing_options query string No Auto-create missing select options when allowed
update_parent_values query boolean No When true, allow updating parent model values while patching a variant
enabled body boolean No Enable/disable product
family body string|null No Family code
categories body array[string] No Replace category set
add_categories body array[string] No Add categories (preserve existing)
remove_categories body array[string] No Remove categories (preserve others)
parent body string|null No Parent product model
values body object No Partial attribute values to merge

Example request

curl -X PATCH "https://YOUR_PIM_HOST/api/rest/v1/products-uuid/25566245-55c3-42ce-86d9-8610ac459fa8" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "add_categories": ["winter_collection"],
    "values": {
      "name": [
        {"data": "Top — refreshed", "locale": "en_US", "scope": null}
      ],
      "description": [
        {"data": "Updated summer top copy", "locale": "en_US", "scope": "ecommerce"}
      ]
    }
  }'

Response — 204 No Content

Product updated successfully (empty body).

Body: (empty)

Response — 201 Created

No product existed for UUID; product was created. Location header returned.

Headers:
Location: /api/rest/v1/products-uuid/25566245-55c3-42ce-86d9-8610ac459fa8

Body: (empty)

Response — 422 Unprocessable Entity

Validation failed on patched payload.

{
  "code": 422,
  "message": "Validation failed.",
  "errors": [
    {
      "property": "values",
      "message": "The name attribute requires a value in the locale en_US."
    }
  ]
}

For list/export-style pulls (instead of flat files), use GET /api/rest/v1/products-uuid with filters and pagination—see the full parameter table in our Akeneo API integration guide.

GET /api/rest/v1/products-uuid Official docs

Get list of products (UUID)

Preferred product list endpoint. Paginated, filterable, and permission-aware. Prefer pagination_type=search_after for large catalogs.

Headers

  • Authorization: Bearer {access_token}
  • Accept: application/json

Parameters

Name In Type Required Description
search query string (JSON) No Filter products (see Filters docs)
scope query string No Return scopable values for this channel (+ non-scopable)
locales query string No Comma-separated locales for localizable values
attributes query string No Comma-separated attribute codes to return
pagination_type query string No page (default) or search_after
page query integer No Page number when pagination_type=page (default 1)
search_after query string No Cursor for search_after pagination (do not invent manually)
limit query integer No Page size (default 10)
search_scope query string No Default scope for multi-attribute filters
search_locale query string No Default locale for multi-attribute filters
with_count query boolean No Include items_count (can be expensive)
with_attribute_options query boolean No Include option labels (linked_data)
with_quality_scores query boolean No Include quality scores
with_completenesses query boolean No Include completenesses
with_root_parent query boolean No Include root parent model code for variants

Example request

curl -G "https://YOUR_PIM_HOST/api/rest/v1/products-uuid" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Accept: application/json" \
  --data-urlencode 'pagination_type=search_after' \
  --data-urlencode 'limit=20' \
  --data-urlencode 'scope=ecommerce' \
  --data-urlencode 'locales=en_US,fr_FR' \
  --data-urlencode 'attributes=sku,name,description' \
  --data-urlencode 'with_completenesses=true' \
  --data-urlencode 'search={"updated":[{"operator":">","value":"2026-01-01 00:00:00"}]}'

Response — 200 OK

Paginated product collection with navigation links.

{
  "_links": {
    "self": {
      "href": "https://YOUR_PIM_HOST/api/rest/v1/products-uuid?pagination_type=search_after&limit=20"
    },
    "first": {
      "href": "https://YOUR_PIM_HOST/api/rest/v1/products-uuid?pagination_type=search_after&limit=20"
    },
    "next": {
      "href": "https://YOUR_PIM_HOST/api/rest/v1/products-uuid?pagination_type=search_after&search_after=CURSOR&limit=20"
    }
  },
  "_embedded": {
    "items": [
      {
        "_links": {
          "self": {
            "href": "https://YOUR_PIM_HOST/api/rest/v1/products-uuid/25566245-55c3-42ce-86d9-8610ac459fa8"
          }
        },
        "uuid": "25566245-55c3-42ce-86d9-8610ac459fa8",
        "enabled": true,
        "family": "tshirt",
        "categories": ["summer_collection"],
        "groups": [],
        "parent": null,
        "values": {
          "sku": [{"data": "top", "locale": null, "scope": null}],
          "name": [
            {"data": "Top", "locale": "en_US", "scope": null},
            {"data": "Débardeur", "locale": "fr_FR", "scope": null}
          ]
        },
        "created": "2026-01-05T10:00:00+00:00",
        "updated": "2026-03-01T12:30:00+00:00",
        "completenesses": [
          {"scope": "ecommerce", "locale": "en_US", "data": 100}
        ]
      }
    ]
  }
}

Response — 401 Unauthorized

Missing/expired token or invalid credentials.

{
  "code": 401,
  "message": "Authentication is required"
}

Response — 422 Unprocessable Entity

Invalid search JSON or unsupported query combination.

{
  "code": 422,
  "message": "Property \"search\" expects a valid search. Check the expected format on the API documentation."
}

Operational excellence

Monitor job duration trends, error rates, and SKU counts. Alert when an export shrinks unexpectedly (often a filter bug) or when import failures spike after a supplier format change. Spygar builds Akeneo import/export pipelines with the same discipline as payment systems: contracts, tests, observability, and clear ownership—because product data is revenue infrastructure.

Ready to start your next project?

Let's work together to bring your ideas to life.