JSONata data mapping

Ask about this Page
Copy for LLM
View as Markdown

Use JSONata expressions in data mappings inside the Product sync module to transform your commercetools product data into the format required by the AI provider.

JSONata is a lightweight query and transformation language for JSON data. In AI Hub, JSONata expressions power the Data mapping configuration in the Product sync tab, where you define how product fields map to the target feed schema.

Each expression is evaluated against a single entry in the product feed. Expressions can access product fields directly, apply conditional logic, and call built-in helper functions called bindings.

For instructions on accessing the data mapping editor, see Configure Product sync.

Product data object

The product feed is flattened by variant: each entry in the feed represents one product variant, not a product. A product with two variants produces two separate feed entries. Your expressions always run in the context of a single variant entry.
The payload structure follows standard commercetools ProductProjection resource data. Each feed entry has the following top-level fields:
  • productData: the full ProductProjection for the current product.
  • variant: the Product Variant that this feed entry represents, extracted from the product's variants.
  • store: the Store context for the Agentic Channel.
  • shippingMethods: available ShippingMethod resources.
For ProductProjection data resolved in Store context, the variant usually includes a scoped price field (singular). For mapping expressions, prefer variant.price as the primary price source.

The following simplified example shows the structure of a single feed entry. Fields not relevant to data mapping are omitted.

Feed entryjson
{
  "productData": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": { "en-US": "Classic Running Shoe", "de-DE": "Klassischer Laufschuh" },
    "description": { "en-US": "A versatile everyday running shoe." },
    "slug": { "en-US": "classic-running-shoe" },
    "masterVariant": {
      "id": 1,
      "key": "classic-running-shoe-master",
      "sku": "CRS-001-BLK-42"
    },
    "variants": [
      {
        "id": 2,
        "key": "classic-running-shoe-v2",
        "sku": "CRS-001-BLK-43"
      }
    ]
  },
  "variant": {
    "id": 1,
    "key": "classic-running-shoe-master",
    "sku": "CRS-001-BLK-42",
    "price": {
      "id": "a1b2c3d4-5678-4abc-b3fc-2c963f66afa6",
      "value": { "centAmount": 12999, "currencyCode": "USD", "fractionDigits": 2 },
      "channel": { "id": "956d220a-fde7-44be-8496-c852fed723ca" }
    },
    "attributes": [
      { "name": "color", "value": "black" },
      { "name": "size", "value": 42 }
    ],
    "availability": {
      "isOnStock": true,
      "availableQuantity": 100
    }
  },
  "store": {
    "id": "store-ABC"
  },
  "shippingMethods": [
    {
      "id": "sm-standard"
    },
    {
      "id": "sm-express"
    }
  ]
}

This example shows how multiple resources are combined in a single feed entry. For full field-level details, refer to the API type definitions:

Default bindings

Bindings are values and helper functions available to expressions at runtime. Variable bindings are always injected from your Agentic Channel configuration as read-only values. Function bindings can be available in provider templates as reusable helpers.

Variable bindings

The following variable bindings are available in every expression. Their values are derived from the Store and Channel configuration of your Agentic Channel, and cannot be reassigned. They are always injected and read-only.

BindingTypeExample valueDescription
$countrystring"US"Country code from the Store configuration.
$localestring"en-US"Default locale from the Store configuration.

Function bindings

The following function bindings are common helper examples. Depending on the selected provider template, additional helper functions can be available, and some functions can differ.

BindingDescription
$getAttribute(attributes, name)Returns the value of a named attribute from a variant's attributes array.
$priceToAmount(price)Extracts the numeric price amount from the variant price object, accounting for fractionDigits.
$formatPrice(price)Returns a formatted price string from the variant price object (for example, "129.99").

Expression examples

The following examples show expressions of increasing complexity, from direct field access to derived transformations.

Access fields directly

The simplest expressions access a field directly from the product entry.

Get the variant SKU (feed product ID):
Get variant SKUtext
variant.sku
Get the product name in a specific locale:

Localized fields are plain objects keyed by locale. Use a string key with backticks when the locale contains a hyphen.

Get localized product nametext
productData.name.`en-US`
Get the product ID:
Get product IDtext
productData.id

Use bindings and conditionals

Intermediate expressions use bindings, conditionals, or string operations.

Get the product name in the configured locale:
Use the $locale variable binding and $lookup to access the localized value dynamically, without hardcoding a language.
Dynamic locale lookuptext
$lookup(productData.name, $locale)
Map stock availability to a feed-compatible string:

Use a conditional expression to return the string value expected by the provider.

Map stock availabilitytext
variant.availability.isOnStock ? "in_stock" : "out_of_stock"
Get a custom attribute value by name:
If your template provides $getAttribute, use it to retrieve a named attribute from the variant's attributes array.
Get attribute by nametext
$getAttribute(variant.attributes, "color")

Build derived values

Complex expressions combine multiple fields, optional helper functions, and logic to produce derived values.

Extract a numeric price amount:
Use $priceToAmount to correctly account for the currency's fractionDigits value.
Extract numeric pricetext
$priceToAmount(variant.price)
Alternatively, if you need manual control, divide centAmount by the appropriate power of 10 based on fractionDigits:
Manual fractionDigits conversiontext
variant.price.value.centAmount / $power(10, variant.price.value.fractionDigits)
Return a formatted price string:
If your template provides $formatPrice, you can format the same scoped price value.
Format price stringtext
$formatPrice(variant.price)
Build a title from the product name and variant attributes:

Combine the localized product name with custom attribute values to produce a richer title string.

Build composite titletext
$lookup(productData.name, $locale) & " - " & $getAttribute(variant.attributes, "color") & " / " & $string($getAttribute(variant.attributes, "size"))
If an expression evaluates to null or undefined, no value is included in the feed for that field. The effect depends on the field and the provider:
  • For required fields, the provider fails to process the product.
  • For optional fields, the provider removes any existing value, depending on its implementation.
Ensure your expressions handle missing data gracefully, for example, by providing fallback values with the JSONata $default operator or conditional logic.