# Product Catalog sync through API

## Introduction

This feature allows to keep knowledge about products up to date, by allowing you to send updates, creations and deletion operations about the product information your system holds. Upon receiving these events, we'll index the new knowledge such that your bot can use the very latest information to answer your visitors' questions.

To do so, we'll look into how you can create a knowledge source (your product catalog), and insert, update and delete knowledge items (your products information).

## Step 1: Recommended: Configure a product id custom data

Although this step is optional, we highly recommend you take the time to properly configure the custom data that holds the product id. This will enable the generative AI bots to automatically fetch the relevant product information based on the visitor's current page.

You'll find an article describing [how to set up a custom data here.](https://help.iadvize.com/hc/en-gb/articles/203401593-Create-and-use-the-custom-data) Take note of the custom data variable name, it will be useful during step 2.

## Step 2: Create a new KnowledgeSource

This operation will only need to be done once, therefore there is no need to write any code for it.

It consists in using GraphQL to create a new KnowledgeSource, and taking note of the identifier that was attributed to it. This identifier will be used during step 3.

{% tabs %}
{% tab title="Using Apollo" %}
You can open the GraphQL mutation [by clicking on this link](https://iadvize.link/UZ0HRF). You'll need to:

* Be logged in as an administrator.
* Replace the variables in the bottom panel with the identifier of your project, the name of the knowledge you're about to create ("API sync product catalog" for instance), and put the name of the custom data variable.
* Execute the query by clicking the KnowledgeSourceCreate blue button
* Write down the identifier of the KnowledgeSource that will appear in the right panel
  {% endtab %}

{% tab title="Manually" %}
{% code title="Graphql Mutation" %}

```graphql
mutation KnowledgeSourceCreate(
  $knowledgeSourceCreateInput: KnowledgeSourceCreateInput!
) {
  knowledgeSourceCreate(knowledgeSourceCreateInput: $knowledgeSourceCreateInput) {
    knowledgeSource {
      id
      name
    }
  }
}

```

{% endcode %}

{% code title="Variables" %}

```json
{
  "knowledgeSourceCreateInput": {
    "details": {
      "productApiSync": {
        "customDataName": "<custom data name>"
      }
    },
    "name": "<name>",
    "projectId": <project id>
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
If you are requesting our GraphQL API directly, do not forget to [get your GraphQL token](https://docs.iadvize.dev/technologies/graphql-api/authentication) first
{% endhint %}

## Step3: Synchronize your products with us

Now you have a KnowledgeSource, you can add, update or delete items within that source. In order to do this, you'll need to react to events within your system and call our GraphQL API.

### Create or update a product with upsert

You can use this mutation, bearing in mind you can submit up to 20 products in a single mutation.

When using the mutation `knowledgeProductsUpsert` to update a product, you need to send all the product's payload. If you want to only send fields which have changed (eg. price, availability, etc.), please refer to the `knowledgeProductsPatch` mutation [described below](#partially-update-products-patch).

{% hint style="info" %}
When upserting a large number of products or an entire catalog, ensure that you comply with the rate limit of 50 requests per second. This limit is enforced on a per-IP address basis.
{% endhint %}

Below is an example of request you can use to upsert products. **This example only references a subset of fields you can set for products**. Please refer to the [definition of each available field in our GraphQL documentation](https://graphql.iadvize.dev/types/KnowledgeProductInput) and to get the expected type and values for each field.

{% code title="Mutation" %}

```graphql
mutation KnowledgeProductUpsert($input: KnowledgeProductsUpsertInput!) {
  knowledgeProductsUpsert(input: $input) {
    knowledgeSource {
      name
    }
    upsertedProducts {
      productId
      status
    }
  }
}
```

{% endcode %}

{% code title="Variables" %}

```json
{
  "input": {
    "knowledgeSourceId": "<id from step 2>",
    "products": [
      {
        "id": "<product id in your system>",
        "availability": "IN_STOCK",
        "availabilityDate": "2024-01-09",
        "brand": "my brand",
        "color": "blue",
        "condition": "NEW",
        "description": "this is my product description",
        "gender": "UNISEX",
        "imageLink": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png",
        "additionalImageLink": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png",
        "itemGroupId": "my group id",
        "link": "https://www.google.com",
        "material": "cotton",
        "price": {
          "currency": "EUR",
          "value": "120.00"
        },
        "productTypes": [
          "t-shirt",
          "polo"
        ],
        "size": "XL",
        "title": "my product title",
        "productDetails": [
          {
            "attributeName": "my detail name",
            "attributeValue": "my detail value"
          }
        ],
        "salePrice": {
          "currency": "EUR",
          "value": "2.0"
        },
        "crossSellProducts": ["product-id-1", "product-id-2"],
        "compatibleWith": ["product-name-1", "product-name-2"]
      }
    ]
  }
}
```

{% endcode %}

### Partially update products (patch)

Use this mutation when you only need to change a subset of fields for products that already exist in the knowledge source. Unlike `knowledgeProductsUpsert`, you do not send a full product payload: for each field, **omit** it to leave the stored value unchanged, pass **`null`** to clear it, or pass a **value** to set or replace it.

<table><thead><tr><th width="311.47265625">Value passed in the query for one field</th><th width="371.984375">Effect on the product's field on iAdvize's side</th></tr></thead><tbody><tr><td>non-null value</td><td>the current <strong>field's value will be replaced with the new value.</strong> This behavior also impacts array fields (for example <code>productDetails</code>): setting a new value for the array will override the array. You can't just add or update one value of an array.</td></tr><tr><td><code>null</code> value</td><td>field's value will be <strong>cleared</strong></td></tr><tr><td>no value passed (not even <code>null</code>)</td><td>value will remain <strong>unchanged</strong></td></tr></tbody></table>

Each object in `products` must include the product `id` plus **at least one** other patchable field (otherwise the request is rejected).

You can patch up to **100** products in a single mutation (compared to 20 for upsert).

> **Note:** The response returns immediately with the list of products that were accepted for update, but indexing is **asynchronous**, like upsert. Respect the same rate limit (**50 requests per second** per IP address) when patching large catalogs.

**Mutation**

```graphql

mutation KnowledgeProductsPatch($input: KnowledgeProductsPatchInput!) {
  knowledgeProductsPatch(
    input: $input
  ) {
    knowledgeSource {
      name
    }
    upsertedProducts {
      productId
      status
    }
  }
}
```

**Variables**

For example if you want to:

1. Set product 1's availability to OUT\_OF\_STOCK
2. Set product 2's price to 14.99 EUR and its availability to IN\_STOCK
3. Remove product 3's brand information (a `null` value will remove the data)

```json
{
    "input": {
        "knowledgeSourceId": "<your knowledge source id>",
        "products": [
            {
                "id": "1",
                "availability": "OUT_OF_STOCK"
            },
            {
                "id": "2",
                "price": {
                    "value": "14.99",
                    "currency": "EUR"
                },
                "availability": "IN_STOCK"
            },
            {
                "id": "3",
                "brand": null
            }
        ]
    }
}
```

### Delete a product

{% code title="Mutation" %}

```graphql
mutation ($input: KnowledgeProductsDeleteInput!) {
  knowledgeProductsDelete(input: $input) {
    knowledgeSource {
      name
    }
    deletedProducts {
      productId
      status
    }
  }
}
```

{% endcode %}

{% code title="Variables" %}

```json
{
  "input": {
    "knowledgeSourceId": "<id from step 2>",
    "productIds": ["<product id in your system>"]
  }
}
```

{% endcode %}

###
