> ## Documentation Index
> Fetch the complete documentation index at: https://product-discovery.developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Catalog entity format overview

> Detailed reference for catalog entities, including product groups, products, variants, content, translations, and market and locale handling.

The catalog consists of structured product data, content, and translations. This section provides a detailed overview of these entities as well as how to work with market- and locale-specific information.

<Tip>
  Most models in this section are expanded as JSON for improved readability. When provided as part of imports, each operation, including all inner models, must be provided as a single [JSON line](/elevate/docs/integration/catalog-imports/catalog-imports#json-lines).
</Tip>

**Related articles**

* Guidance on working with catalog import files — [catalog import overview](/elevate/docs/integration/catalog-imports/catalog-imports).
* Complete schemas and request requirements — [import specification](/elevate/docs/api/admin/v4/import/catalog).
* Contextualized, complete examples for common import scenarios — [import examples](/elevate/docs/integration/catalog-imports/import-examples).
* Import strategies and scheduling — [scheduled imports](/elevate/docs/integration/catalog-imports/scheduling#scheduled-imports).

## Product model

Items available for purchase are structured as [product groups](#product-group), which contain [products](#product), each with one or more [variants](#variant).

### Product group

The product group is the top level of the product model and represents a single article. It acts as a container for one product model with visible differences. The product group itself does not contain any attributes (apart from optional [duplicate suppression](/elevate/docs/api/admin/v4/import/catalog#productgroup)).

```jsonc title="ProductGroup" icon="code" theme={null}
{
  "key": "1001",
  "productGroup": {
    "suppressDuplicates": "false",
    "products": {
      // As described in the product section
    }
  }
}
```

Each product group is identified by a unique key, which is referenced in any instruction that modifies the product group.

Related schemas: [ProductGroup](/elevate/docs/api/admin/v4/import/catalog#productgroup).

### Product

A product represents a specific variation within a product group and includes attributes that distinguish it from other products in the same group. These are typically visible characteristics such as color, pattern, material, or visible size-related aspects like mattress thickness, which help customers easily differentiate products in listings or search results. A good rule of thumb is that products within a group typically have their own images.

Each product must contain at least one [variant](#variant) and should have at least one [image](#images).

```jsonc title="Product" icon="code" expandable theme={null}
{
  "1001-100": {
    "markets": ["uk"],
    "colorInitial": ["#FF0000"],
    "defaults": {
      // Product data
    },
    "overrides": {
      "*|sv-SE": {
        // Product data
      }
    },
    "images": {
      // As described in the images section
    },
    "variants": {
      // As described in the variant section
    }
  }
}
```

Each product is identified by a unique key, which is referenced in the product group's `products` map and in any instruction that modifies the product. Some attributes are provided directly on the product object, while most are defined in inner `productData` objects that can be supplied as [defaults and overrides](#defaults-and-overrides).

```jsonc title="ProductData" icon="code" expandable theme={null}
{
  "url": "/products/1001-100",
  "title": "Louisa black coat",
  "ontology": "Clothing > Outerwear > Coats",
  "category": ["c1", "c2"],
  "brand": "Luis Vitton",
  "sizeType": "Clothing",
  "description": "A fine coat for any occasion",
  "releaseDate": "2023-06-20T00:00:00+02:00",
  "rating": 5,
  "customLabels": {
    // As described in the custom attributes section
  },
  "customLengths": {
    // As described in the custom attributes section
  }
}
```

In this example, two translation identifiers are provided in the `category` attribute. See [translation](#translation) for more information.

Related schemas: [Product](/elevate/docs/api/admin/v4/import/catalog#product), [ProductData](/elevate/docs/api/admin/v4/import/catalog#productdata).

#### Images

An image object defines a single image and may include multiple URLs representing different resolutions of the same image. These variations help optimize bandwidth usage and are especially useful for thumbnails. Each image must include at least one URL.

```jsonc title="Image" icon="code" expandable theme={null}
{
  "i1": {
    "typeInitial": "model",
    "defaults": {
      // Image data
    },
    "overrides": {
      "*|sv-SE": {
        // Image data
      }
    }
  }
}
```

```jsonc title="ImageData" icon="code" expandable theme={null}
{
  "urls": [
    {
      "url": "//cdn.example.com/products/p1?preset=200x200",
      "widthInitial": 200
    },
    {
      "url": "//cdn.example.com/products/p1?preset=600x600",
      "widthInitial": 600
    }
  ],
  "caption": "The model is 176 cm tall and is wearing size S",
  "alt": "The model is 176 cm tall and is wearing size S",
  "tags": ["hero"],
  "customData": {
    "user": "u1",
    "type": "Instagram"
  }
}
```

Each image is identified by a combination of its parent product key and its own unique image key in the product's `images` map and in any instruction that modifies the image. Some attributes are provided directly on the image object, while most are defined in inner `imageData` objects that can be supplied as [defaults and overrides](#defaults-and-overrides).

Related schemas: [Image](/elevate/docs/api/admin/v4/import/catalog#image), [UrlMeta](/elevate/docs/api/admin/v4/import/catalog#urlmeta).

### Variant

A `variant` represents a stock-keeping unit (SKU) and includes attributes specific to that SKU. It typically reflects a difference in physical size, but can also represent variations like memory capacity or other product-specific features.

```jsonc title="Variant" icon="code" expandable theme={null}
{
  "1001-100-1": {
    "defaults": {
      // Variant data
    }
  },
  "overrides": {
    "se|*": {
      // Variant data
    }
  }
}
```

Each variant is identified by a unique key, which is referenced in the product's `variants` map and in any instruction that modifies the variant. The variant attributes are defined in inner `variantData` objects that can be supplied as [defaults and overrides](#defaults-and-overrides).

```jsonc title="VariantData" icon="code" expandable theme={null}
{
  "url": "/products/1001-100-1?size=S",
  "stock": 12,
  "sellingPrice": 129.0,
  "listPrice": 199.0,
  "cost": 55.0,
  "size": ["S"],
  "storeStock": {
    "stockholm": 23
  },
  "customLabels": {
    // As described in the custom attributes section
  }
}
```

#### Sizes

A single physical size can be expressed in several formats. For example, a shirt can be considered both a size S and sizes 34 and 36 simultaneously. If multiple formats are known, all should be provided using `sizeFormats` instead of `size`. Multiple variants with the same format and value are allowed, as long as there is one format with a unique single value.

```jsonc title="sizeFormats" icon="code" theme={null}
"sizeFormats": {
  "sml": ["S"],
  "eu": ["34", "36"]
}
```

#### Custom prices

Custom prices allow a single variant to have multiple prices. They are associated with price IDs, which must also be included when querying.

```jsonc title="customPrices" icon="code" theme={null}
"customPrices": {
  "VIP": {
    "sellingPrice": 99.0,
    "listPrice": 199.0
  }
}
```

#### Store stock

The default stock level defines the online stock availability, while `storeStock` allows a variant to have store specific stock information. Store specific stock levels are associated with store IDs, which must also be included when querying.

```jsonc title="storeStock" icon="code" theme={null}
"storeStock": {
  "stockholm": 23,
  "lund": 2
}
```

Related schemas: [Variant](/elevate/docs/api/admin/v4/import/catalog#variant), [VariantData](/elevate/docs/api/admin/v4/import/catalog#variantdata), [Price](/elevate/docs/api/admin/v4/import/catalog#price).

Related articles: [Custom prices feature](https://help.elevate.voyado.com/hc/en-gb/articles/27609462141596-Additional-features#custom-prices) <Icon icon="external-link" size={12} />, [Store specific stock](/elevate/docs/guides/feature-concepts/store-specific-stock-numbers).

## Content

Content enables visitors to find editorial content items on a site, such as FAQs, shipping, and contact information.

```jsonc title="Content" icon="code" expandable theme={null}
{
  "key": "842",
  "content": {
    "markets": ["se", "uk"],
    "type": "article",
    "defaults": {
      // Content data
    },
    "overrides": {
      "*|sv-SE": {
        // Content data
      },
      "se|*": {
        // Content data
      }
    },
    "image": {
      // As described in the images section
    }
  }
}
```

Each content item is identified by a unique key, which is referenced in any instruction that modifies the content. Some attributes are provided directly on the content object, while most are defined in inner `contentData` objects that can be supplied as defaults and overrides.

```json title="ContentData" icon="code" theme={null}
{
  "url": "uk/articles/its-finally-sweater-season-2020-11-20/",
  "title": "It's finally sweater season",
  "releaseDate": "2023-08-20",
  "description": "Warm, comfortable, and stylish when it matters the most.",
  "customLabels": {
    "season": ["S1"]
  }
}
```

Related schemas: [Content](/elevate/docs/api/admin/v4/import/catalog#content), [ContentData](/elevate/docs/api/admin/v4/import/catalog#contentdata), [Image](/elevate/docs/api/admin/v4/import/catalog#image).

## Translation

Translation is a separate entity that can be imported within a catalog feed. A translation is a mapping of an ID for a specific property to a localized value. Translations apply to all `Product`, `Variant`, and `Content` properties that match.

Using IDs in filters and product selections with translations as a means to localize the presentational information ensures stable filters and product selections. This means that localized presentational values can be altered via translations, without changing filter definitions or product selections. Translations also enable stable cross-market and locale filters and product selections, meaning the same ID can be used in multiple markets while still having differently localized presentational values.

If a property supporting translation lacks a translation for a locale, the ID itself will be used as the presentational value. Translation support is currently limited to the attributes `category`, `age`, `gender`, `series`, `department`, `pattern`, `name`, `brand`, and custom label attributes, for example `customLabels.season`.

```json title="Translation" icon="code" theme={null}
{
  "translation": {
    "locale": "en-GB",
    "attribute": "customLabels.season",
    "id": "AUT",
    "value": "Autumn"
  }
}
```

When this translation is supplied, the value `Autumn` will be searchable and used for presentation by Elevate in the Apps as well as returned in queries using `en-GB` as locale for any matching catalog items.

Related schemas: [Translation](/elevate/docs/api/admin/v4/import/catalog#translation).

## Shared models

### Custom attributes

Catalog items support several types of custom attributes. Each type offers specific features tailored to the kind of data it represents.

#### customLabels

Supports filters and facets, and works with translations. Useful for defining custom filtering or faceting options beyond standard attributes.

```jsonc icon="code" theme={null}
"customLabels": {
  "season": ["AUT"]
}
```

#### customLengths

Supports range queries and metric conversion. Can be used for secondary measurements, such as shipping size.

```jsonc icon="code" theme={null}
"customLengths": {
  "packageWidth": {
    "amount": 3.0,
    "unit": "dm"
  }
}
```

#### customNumbers

Supports numeric range queries. Useful for numeric attributes like the number of items in a package or other count-based values.

```jsonc icon="code" theme={null}
"customNumbers": {
  "pieces": 100.0
}
```

#### customJson

Supports raw JSON values. Useful for including flexible, presentational, or miscellaneous data that should be returned as-is in JSON responses.

```jsonc icon="code" theme={null}
"customJson": {
  "cardStyle": { "theme": "dark" }
}
```

#### customData

Handles non-facetable metadata. Used specifically for supplying additional data for image objects.

```jsonc icon="code" theme={null}
"customData": {
  "user": "u1",
  "type": "Instagram"
}
```

Refer to each item's schema to see which custom attribute types it supports.

### Predefined measurements

Predefined measurements like `width`, `height`, `length`, `depth`, `weight`, and `volume` share product and variant values in facets, product selections, and sorting. This means that there is a single facet for, for example, `width` that holds all `width` values regardless of whether they are provided at product or variant level.

In catalog imports, each product must have its predefined measurements specified, either at the product level or the variant level. If measurements are provided at the variant level, then all variants of the product must include values for the relevant measurements.

Each measurement consists of an `amount` and a `unit`, where valid units depend on the type of measurement.

Related schemas: [Length](/elevate/docs/api/admin/v4/import/catalog#length), [Weight](/elevate/docs/api/admin/v4/import/catalog#weight), [Volume](/elevate/docs/api/admin/v4/import/catalog#volume).

## Markets and locales

<Note>
  [Market identifiers](/elevate/docs/integration/essentials/markets-and-locales#markets) and keys for product groups, products, and variants must be consistent across the catalog imports, the order notifications, and the order history. All keys are case sensitive.
</Note>

Market availability for `content` and `products` is specified in the attribute `markets`. All variants that belong to a product will automatically become available on all the markets that the product is available on. A `productGroup` will be available for markets where at least one of its products is available, and will only include the products available for that market.

All product data and content will be available on all locales that are supported by a market according to the configuration, unless explicitly limited. Note that only `content` and imagery support explicit locale limitations.

### Example

Given the product group example below, requests to the following markets would yield the following results:

* Market `uk` — Product group `pg1`, containing products `p1` and `p2`
* Market `se` — Product group `pg1`, containing product `p2`
* Market `us` — No product groups

The variants `p1-v1` and `p1-v2` will always be returned when `p1` is returned, and `p2-v1` when `p2` is returned.

```json title="Product group example" icon="code" expandable theme={null}
{
  "key": "pg1",
  "productGroup": {
    "products": {
      "p1": {
        "markets": ["uk"],
        "...": "omitted for brevity",
        "variants": {
          "p1-v1": {
            "...": "omitted for brevity"
          },
          "p1-v2": {
            "...": "omitted for brevity"
          }
        }
      },
      "p2": {
        "markets": ["uk", "se"],
        "...": "omitted for brevity",
        "variants": {
          "p2-v1": {
            "...": "omitted for brevity"
          }
        }
      }
    }
  }
}
```

### Defaults and overrides

When making a request to Voyado Elevate, a market and locale are always supplied. The entities which can be returned are determined by the [market and locale availability](#markets-and-locales), but the data that the entities contain is determined by how the data is supplied within each entity.

Structural information such as included imagery and variants, as well as a selected few properties, such as content type and product colors, are provided on the entities themselves. This means that the information cannot differ for different market and locale request contexts. But the majority of properties can vary with the request context. These attributes are located within entity-specific data objects called `defaults`, and can be overridden using `overrides`. Entities that support defaults and overrides include `content`, `product`, `variant`, and `image`.

Properties provided within `defaults` are returned for all request contexts with the correspondingly provided default value, unless overridden. In such cases, the overridden value of the property is returned.

Overrides are provided as a map of [data keys](#data-keys) to the properties to override, where the data key determines when to apply the override. Overrides are only relevant for retailers that have or plan on supporting multiple markets or locales.

#### Data keys

Data keys consist of a market identifier and a locale, separated by a pipe `[market]|[locale]`. The asterisk `*` is a special identifier that signifies it is applicable for all markets or locales, for example `[market]|*` or `*|[locale]`.

#### Locale overrides

Locale overrides refer to overrides that apply for a specific locale, regardless of market. Data keys for such overrides are constructed using `*` instead of a specific market, followed by the locale. A good rule of thumb is that locale overrides should be used for all localized text information that isn't intended for, or supported in, filters and product selections. Good examples include `title` and `description`.

Data key example: `*|en-GB`.

#### Market overrides

Market overrides refer to overrides that apply for a specific market, regardless of locale. Data keys for such overrides are constructed by the market identifier, followed by using `*` instead of a specific locale. Market overrides should be used to override properties that will be used in filters and product selections, as well as any attribute that is connected to the market rather than the locale.

Some properties can only be overridden using market overrides; this is true for attributes which require locale consistency, such as `rating`, `releaseDate`, and `stock`. Properties used in filters and product selections with localized values should be localized using [translations](#translation).

Data key example: `uk|*`.

#### Distinct overrides

Distinct overrides refer to overrides that apply for a specific locale in a specific market. Data keys for such overrides are constructed by the market identifier, followed by the specific locale.

Distinct overrides should **not** be used at all in the majority of integrations. When used, it is for very specific circumstances or use cases. If distinct overrides are used a lot, the catalog feed is likely modeled incorrectly. One use case where distinct overrides are reasonable to use is for URLs given specific circumstances, for example URLs that include both market and locale, where no post-processing of them is done on the site.

Data key example: `uk|en-GB`.

#### Value evaluation order

Values of properties are resolved according to the following priority:

1. [Distinct overrides](#distinct-overrides)
2. [Market overrides](#market-overrides)
3. [Locale overrides](#locale-overrides)
4. `defaults`

This means that if a property is included in a distinct, market, and locale override, the value in the distinct override will be the resulting value for requests with that market and locale combination. However, overridden values should under normal circumstances only be provided as a single type of override.

### Guidelines

* Aim for the highest level of abstraction when modeling defaults and overrides.
* For all properties that are shared across markets and locales for an entity, use defaults.
* When using overrides, place data where it naturally belongs when possible.
* Distinct overrides should only be used in very rare cases.
* Localize values using translations for all properties that are used as filters and product selections.
* Follow [best practices](/elevate/docs/integration/essentials/best-practices).

#### Specific use cases

##### Defaults as fallback

An optional usage of `defaults` is to use it as fallback data. This can be applicable when all properties are well-defined for the entities in a certain market and locale and are acceptable to use for other market and locale combinations as well, when no other data is present.

##### Unique locales per market

When having exactly one locale per market and no locales are ever reused, all overrides can be supplied for each market and locale combination using market overrides. If locales start being reused across markets, it is strongly recommended to generalize the locale information to locale overrides at that point.

Note that distinct overrides are **not** recommended for this use case.
