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

# Integration with Product Discovery

Voyado Product Discovery (formerly Voyado Elevate) is a powerful search and recommendation engine, tailor-made for e-commerce. It analyses shopper behaviour (clicks, searches, purchases) to make tailored product recommendations. Recommendations adapt in real time based on behaviour on the site.

With the Customer Engagement integration to Product Discovery, you can unlock a set of connected features where the two products work together in ways that aren’t possible on their own. This integration is powered by shared identification, contact data, and behavioral signals, enabling smarter personalization across channels. Examples include:

* **Connected recommendations** – Product Discovery generates dynamic product recommendations that can be used directly in Customer Engagement’s Design Studio.
* **Audience-driven personalization** – Product Discovery personalizes the on-site experience based on audiences created in Customer Engagement.
* **Current interest audiences** – Customer Engagement audiences can be built using real-time behavioral data from Product Discovery.
* **Smarter recommendations** – Product Discovery's recommendations are enhanced with in-store purchase data captured by Customer Engagement.

By making Customer Engagement and Product Discovery agree on who a particular contact is, data such as audiences and behavior can be easily shared between the two products. This is done with a unified identifier called `discoveryKey`.

<Tip>
  The `discoveryKey` attribute is used to connect the same contact in Customer Engagement and Product Discovery.
</Tip>

This article looks at how this integration is done.

## Customer key

In Product Discovery, the `customerKey` is the unique identifier for a visitor on the website.

A `customerKey` is required for every request to the Product Discovery API, whether for notifications or queries. To link a visitor in Product Discovery to a Customer Engagement contact, the `customerKey` from Product Discovery should be stored in the `discoveryKey` contact attribute within Customer Engagement. This enables cross-platform understanding of the visitor and enhances personalization capabilities across both Product Discovery and Customer Engagement.

## Identifying the visitor

There are two general ways a visitor can be identified:

* Upon entry
* During the session

<AccordionGroup>
  <Accordion title="1 - Identification upon entry">
    When a visitor enters the site, they may arrive wither organically, from a referral or through a newsletter.

    What happens next in this case depends on the `customerKey`:

    * If a `customerKey` is already available (stored client-side or retrieved from `softId`), use it in all Product Discovery calls
    * If no `customerKey` exists, create one, store it client-side (localStorage or cookie) and then use it in Product Discovery calls
    * If a visitor arrives via `softId` (from a Customer Engagement newsletter), you'll need to decode the `softId`, retrieve the matching `customerKey`, and overwrite the local value of `customerKey` if it is different

    <Frame caption="The customer key">
      <img src="https://mintcdn.com/voyado/hA0bH-u93Mtgbfj0/images/customerkey01.png?fit=max&auto=format&n=hA0bH-u93Mtgbfj0&q=85&s=2c1df3ddde00a65c9d33b4a8e080c3de" alt="The customer key&#x22;" width="695" height="359" data-path="images/customerkey01.png" />
    </Frame>

    For detailed behavior, see the specific visitor types below.
  </Accordion>

  <Accordion title="2 - Identification during session">
    If the customer is not identified at entry (see above), they can be identified during the session if they:

    * Creating an account
    * Logging in to an existing account
    * Signing up for a newsletter, wishlist, or reminder
    * Placing an order

    <Frame caption="Visitor identification">
      <img src="https://mintcdn.com/voyado/hA0bH-u93Mtgbfj0/images/customerkey02.png?fit=max&auto=format&n=hA0bH-u93Mtgbfj0&q=85&s=a706b9c81254eaf164ef4d26dbf8fa73" alt="Visitor identification" width="617" height="405" data-path="images/customerkey02.png" />
    </Frame>
  </Accordion>
</AccordionGroup>

### After identification

When the visitor has been identified, check if they exist in Customer Engagement.

* If they don't exist, create the contact and assign `discoveryKey` to the `customerKey` value
* If they do exist, retrieve and compare the `discoveryKey` to the client's `customerKey` and if the values are different, overwrite the client-side `customerKey` with the Customer Engagement `discoveryKey`

For detailed behavior, see the specific visitor types below.

### Best practices for identification

* Ensure Customer Engagement is updated with the `discoveryKey` for all members (visitors who can sign in)
* All `discoveryKey` values must be unique; duplicate values in Customer Engagement prevent personalization
* Always call Product Discovery with the existing `customerKey` when a visitor is identified
* Use Customer Engagement's `softId` for newsletters to maximize identification rate and cross-system linking
* Define a single source of truth for the `customerKey`, for example the `discoveryKey` in Customer Engagement, to resolve conflicts between local and server values

## Integration flows

Now we will examine the different flows for the three types of visitor:

* New visitors
* Returning visitor
* Newsletter visitors

### New visitor flow

<Steps>
  <Step title="The visitor enters">
    When the visitor enters the site:

    * Generate a new `customerKey`
    * Store that `customerKey` value on the client side
  </Step>

  <Step title="The visitor browses">
    When the visitor browses, for example, a category or product page:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor clicks">
    When the visitor clicks on, for example, a navigation link, add to cart or add favorite:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor signs up">
    When the visitor signs up:

    * Read `customerKey` from the client side
    * Create user account with `customerKey`
    * Call Customer Engagement API to create new contact with `discoveryKey`
    * Update user account with `contactId` from Customer Engagement This should create a mapping between the user account, the Product Discovery `customerKey`, and the Customer Engagement `contactId`.
  </Step>
</Steps>

<Frame caption="New visitor flow">
  <img src="https://mintcdn.com/voyado/hA0bH-u93Mtgbfj0/images/customerkey03.png?fit=max&auto=format&n=hA0bH-u93Mtgbfj0&q=85&s=304e0bd74469eb0de5fa6535336942c6" alt="New visitor flow" width="1902" height="1796" data-path="images/customerkey03.png" />
</Frame>

<Tip>
  This scenario also covers situations where an unknown visitor makes a purchase and a contact is created in Customer Engagement.
</Tip>

### Returning visitor flow

<Steps>
  <Step title="The visitor enters">
    When the visitor enters the site:

    * Read `customerKey` from the client side
  </Step>

  <Step title="The visitor browses">
    When the visitor browses, for example, a category or product page:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor clicks">
    When the visitor clicks on, for example, a navigation link, add to cart or add favorite:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor signs in">
    When the visitor signs in:

    * Read `customerKey` from user account
    * Call Customer Engagement API to update contact with `discoveryKey`
    * Update the client side with `customerKey` The visitor is now identified, and the existing `customerKey` from the user account may differ from the `customerKey` on the client side. Therefore it is important to use the `customerKey` from the user account when calling the Customer Engagement API and to update the client side value accordingly
  </Step>
</Steps>

<Frame caption="Returning visitor flow">
  <img src="https://mintcdn.com/voyado/hA0bH-u93Mtgbfj0/images/customerkey04.png?fit=max&auto=format&n=hA0bH-u93Mtgbfj0&q=85&s=d356668d663ac943710f43a75dc0eb7a" alt="Returning visitor flow" width="1902" height="1654" data-path="images/customerkey04.png" />
</Frame>

### Newsletter visitor flow

<Steps>
  <Step title="The visitor enters">
    When the visitor enters the site:

    * Decode `softId` and identify visitor
    * Read `discoveryKey` or `customerKey` from decoded `softId` or from user account
    * Update the client side with `customerKey`
  </Step>

  <Step title="The visitor browses">
    When the visitor browses, for example, a category or product page:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor clicks">
    When the visitor clicks on, for example, a navigation link, add to cart or add favorite:

    * Read `customerKey` from the client side
    * Call Product Discovery API with `customerKey`
  </Step>

  <Step title="The visitor signs in">
    When the visitor signs in:

    * Read `customerKey` from user account
    * Call Customer Engagement API to update contact with `discoveryKey`
    * Update the client side with `customerKey`
  </Step>
</Steps>

<Frame caption="Newsletter visitor flow">
  <img src="https://mintcdn.com/voyado/hA0bH-u93Mtgbfj0/images/customerkey05.png?fit=max&auto=format&n=hA0bH-u93Mtgbfj0&q=85&s=0b32b30bde2ed09917456b860a799895" alt="Newsletter visitor flow" width="1902" height="1703" data-path="images/customerkey05.png" />
</Frame>

## Identifying email traffic by discoveryKey

The `discoveryKey` is an integral part of the Customer Engagement soft login (previously called auto-login) and needs to be activated by your Customer Engagement specialist.

Soft login is critical for maximizing identification across Customer Engagement, Product Discovery, and between the two products. A high identification rate is the foundation for realizing the full value of the integrated setup.

The soft login happens via an encrypted query string parameter named "eclub" which holds information about the contact who has clicked on a link, such as a URL in an email campaign.

The target site back-end can listen to this query parameter and decrypt it. The decryption of the soft login should never be done on the client side for security reasons and GDPR concerns. The encryption key property in the module settings should also never be shared or made accessible in client implementations.

A soft (auto) login URL might look like this:

```http Example of soft login theme={null}
https://ourdemostore.com/?vtid=9cle0_ctRE25K6kMABznMg&amp;eclub=FwoE65oCjhuc70IBFnszvhZJ0R37pdOYIy0x3KYzsbj3kWtwP2ByD2KP4kuRvWtx7JlyrJpaYnIvI4yAnDbFcVfMJDsXW24MgIrDyqoSw09_7KIMxGri8dYkIhW7FdFFm98n4Vq87I77mA9EsBWI6ExC_MQQkHHqa0h-7pmicZtpQMl7-WJOZCsVV0aEU6E6EX7REldFBFGfHpoWw5fukAaK7nJcg68j_f1OlBgHnwM
```

The result of the server-side decryption will be an object with the following properties, containing the `discoveryKey` which is the identification key (`customerKey`) used in interactions with Product Discovery.

```json Decrypted payload theme={null}
{
    "id": "60333",
    "email": "withnail@voyado.com",
    "contactId": "d35ec9f5-2df7-4d44-b92b-a90c001ce732",
    "dateTime": "2022-05-11T13:15:40Z",
    "discoveryKey": "0b05119e-eeb8-418a-bbfb-defa0dde417e"
}
```

### Soft identification

A customer website running both Customer Engagement and Product Discovery must decrypt the soft login server-side and use the resulting `discoveryKey` as the `customerKey` in all subsequent calls to Product Discovery.

This ensures that traffic originating from Customer Engagement (for example email campaigns) is correctly identified in Product Discovery, allowing personalization, tracking, and recommendations to be applied consistently from the first page view.

If the decrypted payload does not contain a `discoveryKey`, it indicates that the contact has not previously been identified in Product Discovery and should be treated as a new or anonymous visitor.

## SKU and variant key need to match

In Customer Engagement the SKU (stock-keeping unit) is a standard article property. Product Discovery, however, refers to articles as *products*, and the variations of products as *variants*.

<Card icon="right" horizontal href="https://docs.apptus.com/elevate/4/integration/data-feed/format-specification/#variant" title="Read about variants in Product Discovery" />

Each product and variant has a unique key and must use a `variantKey` that corresponds to the article `SKU` in Customer Engagement.

Several features depend on these values being aligned. For example, Customer Engagement retrieves product metadata from Product Discovery to render product recommendations, and matching keys are also required for Product Discovery to consume in-store purchase data from Customer Engagement.

If the Customer Engagement and Product Discovery feeds are not aligned, contact your Customer Engagement representative to discuss next steps. Be aware that some features will be unavailable until the feeds are aligned.

## Verifying discoveryKey implementation

The e-com platform/site should include `discoveryKey` in every create/update contact request made to the Customer Engagement API.

<Frame caption="The discovery key">
  <img src="https://mintcdn.com/voyado/dhpj7gpcKbeEyWTO/images/discovery-key-01.png?fit=max&auto=format&n=dhpj7gpcKbeEyWTO&q=85&s=d37db584ebcdbef4e30e1286e1684168" alt="The discovery key" width="469" height="118" data-path="images/discovery-key-01.png" />
</Frame>

There are three ways this identification can be done:

### Verify by API

Verification can be done by API requests. The following endpoints include `discoveryKey` in the response:

```http theme={null}
GET /api/v3/contactoverview
```

```http theme={null}
GET /api/v3/contacts
```

<Frame caption="Discovery key in API response">
  <img src="https://mintcdn.com/voyado/dhpj7gpcKbeEyWTO/images/discovery-key-02.png?fit=max&auto=format&n=dhpj7gpcKbeEyWTO&q=85&s=9ccf71ced8291ce808110a9c1e2d867c" alt="Discovery key in API response" width="1638" height="1216" data-path="images/discovery-key-02.png" />
</Frame>

### Verify end-to-end

This is a simple way to test the `discoveryKey` implementation end-to-end.

1. Go to the contact card in Customer Engagement for your user. Note that the "Discovery key" field is empty.

<Frame caption="Contact card before">
  <img src="https://mintcdn.com/voyado/dhpj7gpcKbeEyWTO/images/discovery-key-03.png?fit=max&auto=format&n=dhpj7gpcKbeEyWTO&q=85&s=6d806d103406f184ef554b4d0df9f11f" alt="Contact card before" width="1638" height="576" data-path="images/discovery-key-03.png" />
</Frame>

2. Go to the storefront of the retailer
3. Identify yourself on the site, either by signing in or creating an account. If possible, take note of the `customerKey` or ID if that is stored for a contact in the e-com/back-end system. This may be needed for future reference or troubleshooting.
4. Now back to the Customer Engagement tenant. Confirm that the `discoveryKey` has been applied to the contact by checking the field in the contact card. If you have noted the `customerKey` or ID in step 3, verify that it matches.

<Frame caption="Contact card after">
  <img src="https://mintcdn.com/voyado/dhpj7gpcKbeEyWTO/images/discovery-key-04.png?fit=max&auto=format&n=dhpj7gpcKbeEyWTO&q=85&s=be0366bcfbd6b41b6f5616539f1d7ff9" alt="Contact card after" width="1638" height="732" data-path="images/discovery-key-04.png" />
</Frame>

5. This is an optional step you can do if the e-com/website creates a pre-membership account during newsletter sign-up. You can verify if the `discoveryKey` has been assigned to the pre-membership contact in the Customer Engagement tenant by signing up for a newsletter and checking the `discoveryKey` of the newly created contact in the Customer Engagement tenant.

### Verify in dev tools

Sometimes it is possible to verify that the Product Discovery `customerKey` matches the `discoveryKey` in the Customer Engagement contact card by using the browser's developer console. Here you can analyze network communication and browser storage for clues to confirm the match between the `customerKey` and `discoveryKey`.

This ensures that the correct user data is being used for current interests.

<Frame caption="Dev tools verification">
  <img src="https://mintcdn.com/voyado/dhpj7gpcKbeEyWTO/images/discovery-key-05.png?fit=max&auto=format&n=dhpj7gpcKbeEyWTO&q=85&s=ee9eade73eaf8f302192e1c04a9f4e45" alt="Dev tools verification" width="1638" height="808" data-path="images/discovery-key-05.png" />
</Frame>

## Handling duplicate discoveryKey values

All contacts in Customer Engagement must have unique a `discoveryKey` value. If a `discoveryKey` is not unique, this can block contact creation and prevent personalization from working correctly.

### When a validation error occurs

A `discoveryKey` validation error means that the `discoveryKey` you tried to save already exists in Customer Engagement. New or updated contacts are validated when added through the Contact API v2/v3. Other interfaces for creating or updating contacts, such as bulk endpoints, are not affected by this validation.

In this case, an error will be returned:

```json Error when discoveryKey is already in use theme={null}
{ 
  "errors": [ 
    { 
      "code": "DuplicateDiscoveryKey", 
      "message": "The discoveryKey already exists and must be unique." 
    } 
  ] 
}
```

If you receive this error repeatedly, it may indicate that your website is not assigning unique `discoveryKey` values to visitors. This can sometimes be related to how your site generates and stores identifiers, including through connection with integrations (for example, to Product Discovery).

### Resolving the issue

Your site must always assign visitors a new, unique `discoveryKey`. Once generated, this new `discoveryKey` must be used in:

* Contact API requests
* The visitor's cookie
* Any other system where `discoveryKey` is stored (such as databases, Customer Engagement, Product Discovery)

<Warning>
  How this is implemented is site-specific, but the goal is always the same: to ensure that every visitor and member has a unique `discoveryKey` across all systems.
</Warning>

### Cleaning up duplicates

Before cleaning up existing duplicates:

* Make sure no new duplicates are being added.
* Confirm that the normal flows for adding and updating contacts work correctly (without disabling validation)

Here are three important cases when handling duplicates:

<AccordionGroup>
  <Accordion title="When e-com / 3rd party system is the master">
    If your e-commerce platform or another system is the master of `discoveryKey`, duplicates must be resolved there first. Once corrected, you will then send the updated `discoveryKey` values to Customer Engagement.
  </Accordion>

  <Accordion title="When Customer Engagement is the master">
    If Customer Engagement is the master of `discoveryKey`, duplicates can be removed directly within Customer Engagement. Contact Voyado Support for assistance with this process.
  </Accordion>

  <Accordion title="Updating duplicates instead of removing them">
    If you prefer to update duplicate records rather than remove them, the master system must:

    * Identify which contacts to update.
    * Send the changes to Customer Engagement (via API or integration).

    Depending on the scale and complexity, this process may require assistance from Voyado Support to export duplicate lists or perform bulk updates.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.