---
updatedAt: 2025-05-14T08:33:43.000Z
agentTools:
  projectIndex: https://docs.ometria.com/llms.txt
---

# Website personalisation: Sending data to Ometria

# Models

## Category

Categories are the main organisational unit for **[Products](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products) and [Pages](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#pages)** and are represented as a hierarchical tree.

A product (or page) can be contained in multiple categories.

<Image align="center" src="https://files.readme.io/fdeed84171e8ad9a7e8e32a40a813f96f9ae33b9f4f6062175aecb7c6f8a909c-Screenshot_2025-02-18_at_10.17.46.png" />

<Image align="center" width="1px" src="https://files.readme.io/b9f58256b05f5642323db64a83e526d5d652792e01c0798d49717ea960311417-Screenshot_2025-02-18_at_10.17.46.png" />

### Categories data schema

Categories are [DITMAP structures](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema).

```json
{
    "descriptions": /* See DITMAP */,
    "id": /* See DITMAP */,
    "titles": /* See DITMAP */,
    "media": /* See DITMAP */,
    "abstracts": /* See DITMAP */,
    "properties": /* See DITMAP */,
    "enabled": true,
    "include_in_search": true,
    "type": "manual" /* "manual" or "dynamic" or "seo" */,
    "slugs": {
        "de-de": "blumenkleid",
        "en-us": "multicolor-floral-dress",
        "en-gb": "multicolour-floral-dress",
        "th-th": "ดอกไม้-ชุด"
    },
    "urls": {
        "de-de": "/kleidung/kleider/blumenkleid",
        "en-us": "/clothing/dresses/multicolor-floral-dress",
        "en-gb": "/clothing/dresses/multicolour-floral-dress",
        "th-th": "/เสื้อผ้า/ชุด/ดอกไม้-ชุด"
    },
    "meta": {
        "de-de": {
            "title": "Leichte florale Sommerkleid",
            "description": "Formal oder lässig"
        },
        "en-us": {
            "title": "Multicolor Floral dress collection",
            "description": "Formal or casual",
            "keywords": "clothing, dresses, format, casual"
        },
        "en-gb": {
            "title": "Multicolour Floral dress collection",
            "description": "Formal or casual",
            "keywords": "clothing, dresses, format, casual"
        },
        "th-th": {
            "title": "คอลเล็คชั่นชุดเดรสลายดอกไม้หลากสี"
        }
    },
    "tags": ["clothing", "dresses"],
    "version": 127,
    "children": {
        "categories": [
            { "id": "tops", "sequence": 1 },
            { "id": "dresses", "sequence": 2 },
            { "id": "accessories", "sequence": 3 }
        ],
        "products": [
            { "id": "6648024301746", "sequence": 1 },
            { "id": "6560262226098", "sequence": 2 },
            { "id": "6560241647794", "sequence": 3 },
            { "id": "6560262127794", "sequence": 4 },
            { "id": "6560262193330", "sequence": 5 }
        ],
        "pages": [
            {"id": "help", "sequence": 1 },
            {"id": "deliveries", "sequence": 2 },
            {"id": "returns", "sequence": 3 }
        ]
    },
    "product_filters": {
        "set": {
            "match": "and",
            "rules": [
                {
                    "condition": "equals",
                    "target": "brand",
                    "values": ["acme"]
                }
            ]
        }
    }
}

```

<Table align={["left","left","left","left"]}>
  <thead>
    <tr>
      <th>
        Field
      </th>

      <th>
        Required?
      </th>

      <th>
        Type
      </th>

      <th>
        Details
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        enabled
      </td>

      <td>
        Optional
      </td>

      <td>
        Boolean
      </td>

      <td>
        If disabled then this category will no longer appear in any results.  

        If no value is supplied a default value of "true" will be used.
      </td>
    </tr>

    <tr>
      <td>
        include\_in\_search
      </td>

      <td>
        Optional
      </td>

      <td>
        Boolean
      </td>

      <td>
        If set to true then the category will be searchable in the search results and autocomplete.  

        If no value is supplied a default value of "true" will be used.
      </td>
    </tr>

    <tr>
      <td>
        type
      </td>

      <td>
        Optional
      </td>

      <td>
        String
      </td>

      <td>
        A string containing either "manual" or "dynamic".  

        If no value is supplied a default value of "manual" will be used.
      </td>
    </tr>

    <tr>
      <td>
        slugs
      </td>

      <td>
        Optional
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-slug.  

        A slug is the most granular part of the url for a given category.  

        * \*See also:\*\* [Slugs vs. URLs](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#slugs-vs-urls)
      </td>
    </tr>

    <tr>
      <td>
        urls
      </td>

      <td>
        Optional
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-url.  

        This is for defining full URLs.  

        * \*See also\*\*: [Slugs vs. URLs](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#slugs-vs-urls)
      </td>
    </tr>

    <tr>
      <td>
        meta
      </td>

      <td>
        Optional
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing a language tree with a collection of meta tags (key-value pairs) as the leaf nodes.  

        The each key-value pair represents a language specific meta tag to be displayed within the &lt;head&gt; section.  

        In most cases this will not be required.
      </td>
    </tr>

    <tr>
      <td>
        tags
      </td>

      <td>
        Optional
      </td>

      <td>
        Array
      </td>

      <td>
        An array containing a simple string list of tags.
      </td>
    </tr>

    <tr>
      <td>
        version
      </td>

      <td>
        Optional
      </td>

      <td>
        Integer
      </td>

      <td>
        An integer containing a version number for this record.  

        If not supplied then Ometria creates and tracks the version number starting at 1.
      </td>
    </tr>

    <tr>
      <td>
        children
      </td>

      <td>
        **Required**
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing details of child [categories](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#category), [products](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products) and [pages](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#pages).
      </td>
    </tr>

    <tr>
      <td>
        children/action
      </td>

      <td>
        Optional
      </td>

      <td>
        String
      </td>

      <td>
        A string specific to [delta](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#delta-updates), to define the [atomicity](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#atomicity) of the children.  

        E.g.: `"action":"purge"` makes sure that only the children supplied are attributed to the category.  

        Orphaned dependencies in the platform will be removed.  

        * \*See also: \*\*[children/action](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#children-action)
      </td>
    </tr>

    <tr>
      <td>
        children/categories
      </td>

      <td>
        Required
      </td>

      <td>
        Array
      </td>

      <td>
        An array of [categories](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#category) that are children of the current category.\
        Each category object should contain an "id" and optionally a "sequence".  

        * \*See also:\*\* [children/categories action](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#childrencategories-action)
      </td>
    </tr>

    <tr>
      <td>
        children/products
      </td>

      <td>
        Required
      </td>

      <td>
        Array
      </td>

      <td>
        An array of [products](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products) that are children of the current category.  

        Each product object should contain an "id" and optionally a "sequence".  

        * \*See also:\*\* [children/products](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#children--products-action)
      </td>
    </tr>

    <tr>
      <td>
        children/pages
      </td>

      <td>
        Required
      </td>

      <td>
        Array
      </td>

      <td>
        An array of [pages](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#pages) that are children of the current category.\
        Each page object should contain an "id" and optionally a "sequence".  

        * \*See also: \*\*children / pages
      </td>
    </tr>

    <tr>
      <td>
        parents
      </td>

      <td>
        Optional
      </td>

      <td>
        String array
      </td>

      <td>
        A string array specific to [delta](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#delta-updates), of parent category "id"s that the current category is assigned to.  

        * \*See also:\*\* [parents](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#parents)
      </td>
    </tr>

    <tr>
      <td>
        product\_filters
      </td>

      <td>
        Optional
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing details of product filters.  

        product\_filters are only required when the **type** field is set to dynamic or seo.  

        If **type** is set to manual then this field is ignored.
      </td>
    </tr>
  </tbody>
</Table>

#### Slugs vs URLs

Sometimes it's useful to use a slug rather than a url.

For example, by referring to the slug you can generate a different product URL in different categories for the same product.

URLs can be useful when you don't have any category context, e.g. in a search page.\
If in doubt, use both.

#### Children action

```
{    
    "children": {
        "action": "purge"
        "categories": [
            { "id": "tops", "sequence": 1 },
            { "id": "dresses", "sequence": 2 },
            { "id": "accessories", "sequence": 3 }
        ],
        "products": [
            { "id": "6648024301746", "sequence": 1 },
            { "id": "6560262226098", "sequence": 2 },
            { "id": "6560241647794", "sequence": 3 },
            { "id": "6560262127794", "sequence": 4 },
            { "id": "6560262193330", "sequence": 5 }
        ],
        "pages": [
            {"id": "help", "sequence": 1 },
            {"id": "deliveries", "sequence": 2 },
            {"id": "returns", "sequence": 3 }
        ]
    }
}
```

#### Children/categories action

Optional

A string specific to [delta](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#delta-updates), to define whether a child category is to be removed.

Example "action":"delete":

```
{    
   "children": {
       "categories": [
           { "id": "tops", "sequence": 1 },
           { "id": "dresses", "sequence": 2 },
           { "id": "accessories", "sequence": 3, "action": "delete" }
       ]
   }
}
```

#### children / products action

Optional.

A string specific to [delta](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#delta-updates), to define whether a child product is to be removed.

Example "action":"delete"

```
{    
    "children": {
        "products": [
            { "id": "6560262193330", "sequence": 5, "action": "delete" }
        ]
    }
}
```

#### children / pages action

Optional.

A string specific to [delta](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#delta-updates), to define whether a child page is to be removed.

Example "action":"delete"

```
{    
    "children": {
        "pages": [
            {"id": "help", "sequence": 1 },
            {"id": "returns", "sequence": 3, "action": "delete" }
        ]
    }
}
```

#### parents

```
{
    "descriptions": /* See DITMAP */,
    "id": /* See DITMAP */,
    "titles": /* See DITMAP */,
    "media": /* See DITMAP */,
    "abstracts": /* See DITMAP */,
    "properties": /* See DITMAP */,
    "enabled": true,
    "include_in_search": true,
    "type": "manual" /* "manual" or "dynamic" or "seo" */,
    "slugs": {},
    "urls": {},
    "meta": {},
    "tags": [],
    "version": 1,
    "children": {
        "categories": [],
        "products": [
            { "id": "6648024301746", "sequence": 1 }            
        ],
        "pages": []
    },
    "parents": ["parentId","parentId"]    
}
```

## Products

Here is a simple view of the product data model and its relations:

<Image align="center" src="https://files.readme.io/10fe11d84a0bace6be1956080eff1dde925062741165a3869ad70ff57f65d021-Screenshot_2025-02-18_at_14.41.19.png" />

### Attributes

Attributes are data objects that contain full definitions for both features and variants of a product.

Attributes are structured objects that conform to the [DITMAP](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema) structure.

As structured data, **[Variants](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#variants)** and **[Features](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#features)** can be used in [Merchandising blends](https://support.ometria.com/hc/en-gb/articles/21984670698653-Merchandising-blends), [Merchandising concepts](https://support.ometria.com/hc/en-gb/articles/21986281771677-Merchandising-concepts), [Facets](https://support.ometria.com/hc/en-gb/articles/21986908031901-Facets), [Search](https://support.ometria.com/hc/en-gb/sections/23238079175325-Website-search) etc. and so are extremely powerful when configured in Ometria Web Personalisation.

#### Variants

Variants are [Attributes](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#attributes) that customers can select before adding a product to their basket, e.g. colour, size, etc.

Variant attributes can be hierarchical, if needed. E.g. colour x size.

There is no limit to the depth of variant attributes.

#### Features

Features are [Attributes](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#attributes) that customers can't select, e.g. a product's material; cotton, polyester, etc.

This is a feature of the product, not a choice the customer can make.

### Properties

Like features, properties are not selectable options (choices for the customer).

However, properties are not mapped to attributes, and have simpler data structures.

In most cases, properties are key value pairs, but they can be any valid JSON.

Use properties for simple data where there is no requirement to use them as part of your merchandising strategies, e.g. defining settings for the templating engine.

### Products data schema

Products are [DITMAP](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema) structures.

```
{
    "descriptions": /* See DITMAP */,
    "id": /* See DITMAP */,
    "titles": /* See DITMAP */,
    "media": /* See DITMAP */,
    "abstracts": /* See DITMAP */,
    "properties": /* See DITMAP */,
    "sku": "top80671",
    "enabled": true,
    "include_in_search": true,
    "stock": 78, /* Now Deprecated - see Warehousing */
    "product_type_id": "tops",
    "prices": {
        "EUR": {
            "price": 14.99,
            "cost": 19.60,
            "rrp": 16.50,
            "was": 15.99
        },
        "USD": {
            "price": 17.99,
            "cost": 23.56,
            "rrp": 19.99,
            "was": 18.99
        },
        "GBP": {
            "price": 12.99,
            "cost": 17.00,
            "rrp": 14.50,
            "was": 14.00
        }
    },
    "slugs": {
        "en-us": "cotton-tshirt"
    },
    "urls": {
        "en-us": "/clothing/tops/cotton-tshirt"
    },
    "meta": {
        "en-us": {
            "title": "Cotton T-Shirt",
            "description": "Non-shrink, long lasting t-shirt"
        }
    },
    "tags": ["top", "tshirt", "cotton"],
    "version": 127,
    "features": [
        {
            "hierarchy": ["vendor", "londonthings"]
        },
        {
            "hierarchy": ["material", "cotton"]
        },
        {
            "hierarchy": ["material", "leather"],
            "properties": {
                "waterproof": true
            }
        }
    ],
    "variants": [
        {
            "id": "abc123", /* Should be globaly unique */
            "sku": "41504229-blue-size-one",
            "stock": 1473, /* Now Deprecated - see Warehousing */
            "hierarchy": ["color", "blue", "size", "one-size"],
            "titles": {
                "en-us": {
                    "default": "Blue TShirt"
                }
            },
            "media": {
                "default": {
                    "src": "/images/blue-dress.jpg",
                    "width": 640,
                    "height": 640
                }
            },
            "prices": {
                "GBP": {
                    "price": 29.80,
                    "cost": 15.55,
                    "rrp": 32.99,
                    "was": 18.99
                }
            },
            "properties": {
                "weight": 0.0,
                "weight_unit": "lb"
            }
        },
        {
            "id": "41504229-black-size-one" /* Suggest repeating SKU if no specific ID */
            "sku": "41504229-black-size-one",
            "stock": 877, /* Now Deprecated - see Warehousing */
            "hierarchy": ["color", "black", "size", "one-size"],
            "titles": {
                "en-us": {
                    "default": "Black TShirt"
                }
            },
            "prices": {
                "GBP": {
                    "price": 17.77
                }
            }
        },
        {
            "id": "41504229-green-size-one" /* Suggest repeating SKU if no specific ID */
            "sku": "41504229-green-size-one",
            "stock": 1003,  /* Now Deprecated - see Warehousing */
            "hierarchy": ["color", "green", "size", "one-size"],
            "prices": {
                "GBP": {
                    "price": 17.77
                }
            }
        }
    ],
    "warehousing": [
        {
          "warehouse_id": "*",
          "variant_id": "ABC123",
          "stock": 1473,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
        },
        {
          "warehouse_id": "Lon",
          "variant_id": "41504229-black-size-one",
          "stock": 400,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
          }
        },
        {
          "warehouse_id": "Bir",
          "variant_id": "41504229-black-size-one",
          "stock": 477,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
          }
        },
        {
          "warehouse_id": "*",
          "variant_id": "41504229-green-size-one",
          "stock": 1003,
          "stock_threshold": -10,
          "allow_backorder": false,
          "un_metered": null
          }
        }
      ]
    }
}


```

> 📘 Note:
>
> Hierarchy is the only required field. All other fields are optional.

<Table align={["left","left","left"]}>
  <thead>
    <tr>
      <th>
        Field
      </th>

      <th>
        Type
      </th>

      <th>
        Details
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        sku
      </td>

      <td>
        String
      </td>

      <td>
        Stock keeping unit.
      </td>
    </tr>

    <tr>
      <td>
        enabled
      </td>

      <td>
        Boolean
      </td>

      <td>
        If disabled then this product won't appear in any results.  

        If no value is supplied a default value of "true" is used.
      </td>
    </tr>

    <tr>
      <td>
        include\_in\_search
      </td>

      <td>
        Boolean
      </td>

      <td>
        If set to true then the category will be searchable in the search results and autocomplete.  

        If no value is supplied a default value of "true" is used.
      </td>
    </tr>

    <tr>
      <td>
        stock
      </td>

      <td>
        Integer
      </td>

      <td>
        An integer representing the parent level stock count.  

        * \*Note\*\*: This field has been deprecated in favour of the  warehousing field.  
        * \*See: \*\*[Warehousing data schema](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#warehousing-data-schema)
      </td>
    </tr>

    <tr>
      <td>
        product\_type\_id
      </td>

      <td>
        String
      </td>

      <td>
        A string defining the product type id that this product is associated with.
      </td>
    </tr>

    <tr>
      <td>
        prices
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing a currency tree which represents the parent price.  

        Each currency node can set the properties:  

        * price Number (Required)
        * cost Number (Optional)
        * rrp Number (Optional)
        * was Number (Optional)

          * \*See also:\*\* [Custom prices](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#custom-prices)
      </td>
    </tr>

    <tr>
      <td>
        slugs
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-slug.  

        A slug is the most granular part of the URL for a given category.
      </td>
    </tr>

    <tr>
      <td>
        urls
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-url.  

        This is for defining full URLs.
      </td>
    </tr>

    <tr>
      <td>
        meta
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing a language tree with a collection of meta tags (key-value pairs) as the leaf nodes.  

        Each key-value pair represents a language specific meta tag to be displayed within the `<head>` section.  

        In most cases this will not be required.
      </td>
    </tr>

    <tr>
      <td>
        tags
      </td>

      <td>
        Array
      </td>

      <td>
        An array containing a simple string list of tags.
      </td>
    </tr>

    <tr>
      <td>
        version
      </td>

      <td>
        Integer
      </td>

      <td>
        An integer containing a version number for this record.  

        If not supplied then Ometria creates and tracks the version number starting at 1.
      </td>
    </tr>

    <tr>
      <td>
        features
      </td>

      <td>
        Array
      </td>

      <td>
        An array of [features](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#features).  

        Each feature is a [DITMAP](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema) object but also includes a hierarchy field (see below).
      </td>
    </tr>

    <tr>
      <td>
        variants
      </td>

      <td>
        Array
      </td>

      <td>
        An array of [variants](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#variants).  

        Each variant is a [DITMAP](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema) object but also includes a sku field (string), a price field (object) and a hierarchy field (see below).  

        You must provide a globally unique ID for each variant.  

        We recommend reusing SKU if you don't have a separate variant id.
      </td>
    </tr>

    <tr>
      <td>
        hierarchy
      </td>

      <td>
        Array
      </td>

      <td>
        Required.  

        An array that defines the path for a [feature](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#features) or [variant](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#variants).  

        The structure of the path is:\
        [attribute1\_id, attribute1\_option\_id, attribute2\_id, attribute2\_option\_id][attribute1_id, attribute1_option_id, attribute2_id, attribute2_option_id] etc.  

        Like other ID values, the attribute\_id and attribute\_option\_id should be lower case and URL safe.
      </td>
    </tr>

    <tr>
      <td>
        warehousing (product/variant)
      </td>

      <td>
        Array
      </td>

      <td>
        An array that has one record per variant (or product if no variants) per warehouse.  

        * \*See:\*\* [Warehousing data schema](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#warehousing-data-schema)
      </td>
    </tr>
  </tbody>
</Table>

#### Custom prices

If you'd like to send additional custom prices of your own you may do so using the following syntax where custom\_price\_1 etc. can be any string identifier of your choice:

```
"EUR": {
    "price": 14.99,
    "cost": 19.60,
    "rrp": 16.50,
    "was": 15.99,
    "custom_prices":{
      "custom_price_1": 10,
      "custom_price_2": 7.99,
      "custom_price_3": 3.99
    }
}
```

#### Warehousing data schema

Warehousing is used to represent the stock at either [variant](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#variants) or [product](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products) level.

Provide only **one per product**, i.e.

If your stock is tracked at a variant level then provide variant stock in the warehousing node.

If your product has no variants then provide the data at product level.

`product_id` is not required in the Warehousing node.  It is cascaded from its parent node.

This is a subset of the JSON from the **[Products data schema](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products-data-schema)**:

```
   "warehousing": [
        {
          "warehouse_id": "*",
          "variant_id": "ABC123",
          "stock": 1473,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
        },
        {
          "warehouse_id": "Lon",
          "variant_id": "41504229-black-size-one",
          "stock": 400,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
          }
        },
        {
          "warehouse_id": "Bir",
          "variant_id": "41504229-black-size-one",
          "stock": 477,
          "stock_threshold": 0,
          "allow_backorder": false,
          "un_metered": null
          }
        },
        {
          "warehouse_id": "*",
          "variant_id": "41504229-green-size-one",
          "stock": 1003,
          "stock_threshold": -10,
          "allow_backorder": false,
          "un_metered": null
          }
        }
      ]
```

<Table align={["left","left","left","left"]}>
  <thead>
    <tr>
      <th>
        Field
      </th>

      <th>
        Required?
      </th>

      <th>
        Type
      </th>

      <th>
        Details
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        warehouse\_id
      </td>

      <td>
        Required
      </td>

      <td>
        String
      </td>

      <td>
        A unique identifier for the warehouse.  

        If you have a single warehouse then \* is preferred for the warehouse id.  

        If you have multiple warehouses then you can use any string to identify the warehouse but you must use the same string when requesting data if you want to restrict it to the stock from a specific warehouse.
      </td>
    </tr>

    <tr>
      <td>
        variant\_id
      </td>

      <td>
        Required
      </td>

      <td>
        String
      </td>

      <td>
        A unique identifier for the variant.  

        The `variant_id`here must match the id used on the variants node in the [products data schema](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#products-data-schema).  

        If a product doesn't have variants then provide \* for the `variant_id` and provide the product level stock for the warehouse.  

        **Don't provide both product and variant level stock.  Product values will be ignored if variant values are supplied.**
      </td>
    </tr>

    <tr>
      <td>
        stock
      </td>

      <td>
        Optional
      </td>

      <td>
        Integer
      </td>

      <td>
        The quantity of stock available to sell.\
        This would normally be Required.\
        It is optional if you don't want Ometria to take account of stock on your site, or because you have set un\_metered to "true" for this product.
      </td>
    </tr>

    <tr>
      <td>
        stock\_threshold
      </td>

      <td>
        Optional
      </td>

      <td>
        Integer
      </td>

      <td>
        If not supplied this will default to 0.\
        A value of 10 means stop selling when the stock drops to 10.\
        A value of -10 means keep selling until the stock reaches -10.
      </td>
    </tr>

    <tr>
      <td>
        allow\_backorder
      </td>

      <td>
        Optional
      </td>

      <td>
        Boolean
      </td>

      <td>
        If not provided, this field defaults to null which acts as false.\
        If set to "true" the stock will keep selling even when stock is negative.
      </td>
    </tr>

    <tr>
      <td>
        un\_metered
      </td>

      <td>
        Optional
      </td>

      <td>
        Boolean
      </td>

      <td>
        If not supplied, this field defaults to null which acts as false.\
        Similar effect to allow\_backorder, but without the need to maintain a stock level at all.\
        E.g. for an electronic gift card.
      </td>
    </tr>
  </tbody>
</Table>

## Pages

Pages are informational units that represent a content page on a website (e.g. delivery information page, returns information page etc.)

<Image align="center" src="https://files.readme.io/4f1b49bb093eb5ad1486a1cdc9d422344eb7813138c76f3308d91e49457c0f0d-Screenshot_2025-02-18_at_15.09.41.png" />

### Pages data schema

Pages are [DITMAP](https://docs.ometria.com/docs/website-personalisation-sending-data-to-ometria#ditmap-data-schema) structures.

```
{
   "descriptions": /* See DITMAP */,
   "id": /* See DITMAP */,
   "titles": /* See DITMAP */,
   "media": /* See DITMAP */,
   "abstracts": /* See DITMAP */,
   "properties": /* See DITMAP */,
   "enabled": true,
   "include_in_search": true,
   "type": "information",
   "slugs": {
       "en-us": "delivery-information",
       "fr-ca": "informations-de-livraison"
   },
   "urls": {
       "en-us": "/help/delivery-information",
       "fr-ca": "/info/informations-de-livraison"
   },
   "meta": {
       "en-us": {
           "title": "Delivery Information"
       },
       "fr-ca": {
           "title": "Informations-de-livraison"
       }
   },
   "tags": ["delivery", "information", "contact"]
   "version": 127
}
```

> 📘 Note:
>
> All fields are **optional**.

<Table align={["left","left","left"]}>
  <thead>
    <tr>
      <th>
        Field
      </th>

      <th>
        Type
      </th>

      <th>
        Details
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        enabled
      </td>

      <td>
        Boolean
      </td>

      <td>
        If disabled then this page won't appear in any results.  

        If no value is supplied a default value of "true" will be used.
      </td>
    </tr>

    <tr>
      <td>
        include\_in\_search
      </td>

      <td>
        Boolean
      </td>

      <td>
        If set to true then the category will be searchable in the search results and autocomplete.  

        If no value is supplied a default value of "true" will be used.
      </td>
    </tr>

    <tr>
      <td>
        type
      </td>

      <td>
        String
      </td>

      <td>
        A string containing either "manual" or "dynamic".  

        If no value is supplied a default value of "manual" will be used.
      </td>
    </tr>

    <tr>
      <td>
        slugs
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-slug.  

        A slug is the most granular part of the url for a given category.
      </td>
    </tr>

    <tr>
      <td>
        urls
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing key-value pairs of language-url.  

        This is for defining full URLs.
      </td>
    </tr>

    <tr>
      <td>
        meta
      </td>

      <td>
        Object
      </td>

      <td>
        An object containing a language tree with a collection of meta tags (key-value pairs) as the leaf nodes.  

        Each key-value pair represents a language specific meta tag to be displayed within the `<head>` section.  

        In most cases this will not be required.
      </td>
    </tr>

    <tr>
      <td>
        tags
      </td>

      <td>
        Array
      </td>

      <td>
        An array containing a simple string list of tags.
      </td>
    </tr>

    <tr>
      <td>
        version
      </td>

      <td>
        Integer
      </td>

      <td>
        An integer containing a version number for this record.  

        If not supplied then Ometria creates and tracks the version number starting at 1.
      </td>
    </tr>
  </tbody>
</Table>

### Delta updates

A delta update is a software update that requires the user to download only those parts of the software's code that are new, or have been changed from their previous state, instead of  having to download the entire program.

## DITMAP data schema

DITMAP is a common structure/pattern in Ometria's Web Personalisation feature.

It stands for:

* Descriptions
* Id
* Titles
* Media
* Abstracts
* Properties

### Field order

The order in which you insert your fields is not important.

For example, id can come before descriptions or any other field.

Most objects are based on this pattern.

```
{
   "descriptions": {
       "en-gb": {
           "default": "<p>Light floral summer dress</p><p>Great for parties</p>",
           "washing_instructions": "<p>Machine washable and tumble dryer ready</p>"
       },
       "de-de": {
           "default": "<p>Leichte florale Sommerkleid</p><p>Ideal für Partys</p>",
           "washing_instructions": "<p>Maschinenwaschbarer und Wäschetrockner bereit</p>"
       }
   },
   "id": "186917",
   "titles": {
       "en-gb": {
           "default": "Floral Dress",
           "alt_title": "Summer Dress"
       },
       "de-de": {
           "default": "Blumenkleid",
           "alt_title": "Sommerkleid"
       }
   },
   "media": {
       "default": {
           "src": "https://mysite.com/images/floral-dress.jpg",
           "width": 400,
           "height": 400
       },
       "front": {
           "src": "https://mysite.com/images/floral-dress-front-large.jpg",
           "width": 1600,
           "height": 1600
       },
       "back": {
           "src": "https://mysite.com/images/floral-dress-back.jpg",
           "width": 550,
           "height": 550
       },
       "with_model": {
           "src": "https://mysite.com/images/floral-dress-with-model.jpg",
           "width": 550,
           "height": 550
       },
       "alt1": {
           "src": "https://mysite.com/images/floral-dress-alt1.jpg",
           "width": 550,
           "height": 550
       }
   },
   "abstracts": {
       "en-gb": {
           "default": "<p>Light floral summer dress</p>",
           "occasion": "<p>Formal or casual</p>"
       },
       "de-de": {
           "default": "<p>Leichte florale Sommerkleid</p>",
           "occasion": "<p>Formal oder lässig</p>"
       }
   },
   "properties": {
       "washable": true,
       "extra_info": "stain resistant",
       "warranty": "1 year",
       "occasion": [
         "Formal",
         "Casual"
       ]
   }
}
```

## descriptions

**Optional**.

An object containing a language tree with a collection of descriptions (key-value pairs) as the leaf nodes.

Language specific objects require that the language be defined at the first level and the individual values be defined at the second level.

The "descriptions" object can contain an unlimited number of descriptions.

The main description is labelled "default".

Description keys are defined using snake\_case.

Descriptions typically contain HTML.

```
descriptions
    lang_a
        default_description
        additional_description
        ...
    ...
    lang_z
        default_description
        additional_description
        ...
```

## id

**Required**.

A string or number containing the unique identifier for an object.

Always use lowercase, URL safe values for all ID fields.

## titles

**Optional**.

An object containing a language tree with a collection of titles (key-value pairs) as the leaf nodes.

Language specific objects require that the language be defined at the first level and the individual values be defined at the second level.

The titles object can contain an unlimited number of titles.

The main title is labelled "default".

Title keys are defined using snake\_case.

"titles" typically contain plain text.

```
titles
    lang_a
        default_title
        alt_title_1
        alt_title_2
        ...
    ...
    lang_z
        default_title
        alt_title_I
        alt_title_II
        ...
```

## media

**Optional**.

An object containing a collection of abstracts (key-object pairs).

The media object can contain multiple objects.

The main object is labelled "default".

If an item has no items then the media object will be omitted from the response.

Each object in the key-object pairs can contain multiple key-value pairs, but there is normally a "src" key-value pair.

```
media
    default
        src
        width (optional)
        height (optional)
        another_property (optional)
        ...
    ...
    another_key
        src
        width (optional)
        height (optional)
        another_property (optional)
        ...
```

## abstracts

**Optional**.

An object containing a language tree with a collection of abstracts (key-value pairs) as the leaf nodes.

Language specific objects require that the language be defined at the first level and the individual values be defined at the second level.

The "abstracts" object can contain an unlimited number of abstracts.

The main abstract is labelled "default".

Abstract keys are defined using snake\_case.

Abstracts will typically contain HTML.

```
abstracts
    lang_a
        default_abstract
        another_abstract
        yet_another_abstract
        ...
    ...
    lang_z
        default_abstract
        another_abstract
        yet_another_abstract
        ...
```

## properties

**Optional**.

An object containing either a collection of properties (key-value pairs) or any valid custom JSON.

The values can be of any of the simple (expanded) JSON data types:

* Number
* String
* Boolean
* Date

# CRUD operations

[CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) stands for create, read, update, and delete.

## Atomicity

All Web Personalisation data records stored with Ometria are [atomic](https://en.wikipedia.org/wiki/Atomicity_\(database_systems\)) at the root level.

This means that in order to update a branch or child item the whole "field" must be updated.

In the example below, we're just updating the subtitle "en-gb/washing\_instructions" and adding a new property to explain that the product can be tumble dried.

Because the data is atomic to the root level, we only need to supply two fields, but those fields must be fully formed.

```
{
  "descriptions": {
    "en-gb": {
      "default": "<p>Light floral summer dress</p><p>Great for parties</p>",
      "washing_instructions": "<p>Machine washable</p>"
    },
    "de-de": {
      "default": "<p>Leichte florale Sommerkleid</p><p>Ideal für Partys</p>",
      "washing_instructions": "<p>Maschinenwaschbarer und Wäschetrockner bereit</p>"
    }
  },
  "id": "186917",
  "titles": {
    "en-gb": {
      "default": "Floral Dress",
      "alt_title": "Summer Dress"
    },
    "de-de": {
      "default": "Blumenkleid",
      "alt_title": "Sommerkleid"
    }
  },
  "media": {
    "default": {
      "src": "https://mysite.com/images/floral-dress.jpg",
      "width": 400,
      "height": 400
    },
    "alt1": {
      "src": "https://mysite.com/images/floral-dress-alt1.jpg",
      "width": 550,
      "height": 550
    }
  },
  "abstracts": {
    "en-gb": {
      "default": "<p>Light floral summer dress</p>",
      "occasion": "<p>Formal or casual</p>"
    },
    "de-de": {
      "default": "<p>Leichte florale Sommerkleid</p>",
      "occasion": "<p>Formal oder lässig</p>"
    }
  },
  "properties": {
    "machine_washable": true,
    /* Insert new property here */
    "extra_info": "stain resistant",
    "warranty": "1 year",
    "occasion": [
      "formal",
      "casual"
    ]
  }
}
```

### Atomic updates

```
{
  "descriptions": {
    "en-gb": {
      "default": "<p>Light floral summer dress</p><p>Great for parties</p>",
      "washing_instructions": "<p>Machine washable and tumble dryer ready</p>"
    },
    "de-de": {
      "default": "<p>Leichte florale Sommerkleid</p><p>Ideal für Partys</p>",
      "washing_instructions": "<p>Maschinenwaschbarer und Wäschetrockner bereit</p>"
    }
  },
  "id": "186917",
  "properties": {
    "machine_washable": true,
    "tumble_dryer_ready": true,
    "extra_info": "stain resistant",
    "warranty": "1 year",
    "occasion": [
      "formal",
      "casual"
    ]
  }
}
```

### After updating

If the payload above was applied to the original record, then the data stored in Ometria would look like this:

```
{
  "descriptions": {
    "en-gb": {
      "default": "<p>Light floral summer dress</p><p>Great for parties</p>",
      "washing_instructions": "<p>Machine washable and tumble dryer ready</p>"
    },
    "de-de": {
      "default": "<p>Leichte florale Sommerkleid</p><p>Ideal für Partys</p>",
      "washing_instructions": "<p>Maschinenwaschbarer und Wäschetrockner bereit</p>"
    }
  },
  "id": "186917",
  "titles": {
    "en-gb": {
      "default": "Floral Dress",
      "alt_title": "Summer Dress"
    },
    "de-de": {
      "default": "Blumenkleid",
      "alt_title": "Sommerkleid"
    }
  },
  "media": {
    "default": {
      "src": "https://mysite.com/images/floral-dress.jpg",
      "width": 400,
      "height": 400
    },
    "alt1": {
      "src": "https://mysite.com/images/floral-dress-alt1.jpg",
      "width": 550,
      "height": 550
    }
  },
  "abstracts": {
    "en-gb": {
      "default": "<p>Light floral summer dress</p>",
      "occasion": "<p>Formal or casual</p>"
    },
    "de-de": {
      "default": "<p>Leichte florale Sommerkleid</p>",
      "occasion": "<p>Formal oder lässig</p>"
    }
  },
  "properties": {
    "machine_washable": true,
    "tumble_dryer_ready": true,
    "extra_info": "stain resistant",
    "warranty": "1 year",
    "occasion": [
      "formal",
      "casual"
    ]
  }
}
```

## Null values

When data is uploaded via the [Batch API](https://docs.ometria.com/docs/batch-api), content is treated like a [PATCH](https://en.wikipedia.org/wiki/PATCH_\(HTTP\)) operation.

This means that if a field is omitted from the data file then that field won't be updated.

If you want to remove the value of a field you must set it to null.

Here's an example:

```
{
    "descriptions": {
        "en-gb": {
            "default": "<p>Fully waterproof, all terrain tent</p>",
        }
    },
    "id": "186917",
    "titles": {
        "en-gb": {
            "default": "Waterproof Tent"
        }
    },
    "media": {
        "default": {
            "src": "https://mysite.com/images/tent.jpg",
            "width": 400,
            "height": 400
        }
    },
    "abstracts": {
        "en-gb": {
            "default": "<p>Quick build tent</p>",
        }
    },
    "properties": {
        "waterproof": true,
        "build_type": "quick"
    }
}
```

To remove the "abstracts" field, post:

```
{
    "id": "186917",
    "abstracts": null
}
```

This removes the "abstracts field", and all other fields remain as they were before.

Example:

```
{
    "descriptions": {
        "en-gb": {
            "default": "<p>Fully waterproof, all terrain tent</p>",
        }
    },
    "id": "186917",
    "titles": {
        "en-gb": {
            "default": "Waterproof Tent"
        }
    },
    "media": {
        "default": {
            "src": "https://mysite.com/images/tent.jpg",
            "width": 400,
            "height": 400
        }
    },
    "abstracts": null,
    "properties": {
        "waterproof": true,
        "build_type": "quick"
    }
}
```