---
title: "Walkthrough: Creating a contact and an interaction"
slug: "walkthrough--creating-a-contact-and-an-interaction"
abstract: "How to create a contact and an interaction in Sitecore xConnect."
---
# Walkthrough: Creating a contact and an interaction

This walkthrough is part one of the [Extending the xConnect collection model walkthrough series](https://doc.sitecore.com/xp/en/developers/104/sitecore-experience-platform/extending-the-xconnect-collection-model-walkthrough-series.html "Extending the xConnect collection model walkthrough series") and describes how to create a contact and an interactions.

Before you can complete this walkthrough, you must install the full Sitecore Experience Platform, including xConnect and xDB.

This walkthrough describes how to:

- Create the `Sitecore.Documentation` solution and console app
- Establish contact between the `Sitecore.Documentation` app and your XConnect instance
- Create a contact with a known identifier
- Create an interaction with a single event

> [!note]
> In Sitecore 9.1.0, in the `Sitecore.Xdb.Common.Web` namespace:
>
> -   `Certificate**WebRequest**HandlerModifierOptions` became `Certificate**HttpClient**HandlerModifierOptions`.
>
> -   `Certificate**WebRequest**HandlerModifier` became `Certificate**HttpClient**HandlerModifier`.

## Create the Sitecore.Documentation solution and console app

To create the `Sitecore.Documentation` solution and console app:

1. In Visual Studio with administrator privileges, create a new solution and console app for .NET Framework project called `Sitecore.Documentation`:

    ![The Configure your new project dialogue box in Visual Studio.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/104/sitecore-experience-platform/images/xconn-tut1-new-proj.png)

2. In Solution Explorer, right-click **References** and click **Add Reference**.
3. In the **Reference Manager** window, click **Browse** and add the following references from your `<xConnect instance>\bin\` folder:
    - `Sitecore.Framework.Conditions.dll`
    - `Sitecore.XConnect.Core`
    - `Sitecore.XConnect.dll`
    - `Sitecore.XConnect.Client.dll`
    - `Sitecore.XConnect.Collection.Model.dll`
    - `Sitecore.XConnect.Search.dll`
    - `Sitecore.Xdb.Common.Web.dll`
4. In Solution Explorer, right-click **References** and click **Manage NuGet Packages**.
5. In the **NuGet** window, click **Browse** and add the following references:
    - `Microsoft.AspNet.WebApi.Client` - version: 5.2.6
    - `Microsoft.Extensions.Configuration.Abstractions` - version: 2.1.1
    - `System.Interactive.Async.Providers` version: 3.1.1
    - `Newtonsoft.Json ` - version: 11.0.2

## Establish contact between the Sitecore.Documentation app and your XConnect instance

To establish contact between the `Sitecore.Documentation` app and your xConnect instance:

1. In Solution Explorer, double-click the `Program.cs` file and replace the content with the following code:

    ```csharp
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS =
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";

            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";

            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }

            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);

                var certificateModifier = new CertificateHttpClientHandlerModifier(options);

                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);

                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );

                try
                {
                    await cfg.InitializeAsync();

                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);

                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }

                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        // This is where we add content in later code samples
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }
                }
            }
        }
    }
    ```

2. Edit the `CERTIFICATE_THUMBPRINT` and the `XCONNECT_URL` constants.
3. Save the `Program.cs` file.
4. Press **F5** to run the app. If the connection is established, the app writes `END OF PROGRAM` in the terminal:

    ![A terminal with END OF PROGRAM in the app output.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/104/sitecore-experience-platform/images/xconn-tut1-code1.png)

## Create a contact with a known identifier

To create a contact with a known identifier:

1. In Visual Studio, in Solution Explorer, double-click the `Program.cs` file and replace the content with the following code:

    ```csharp
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS =
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";

            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";

            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }

            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);

                var certificateModifier = new CertificateHttpClientHandlerModifier(options);

                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);

                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );

                try
                {
                    await cfg.InitializeAsync();

                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);

                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }

                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        // Identifier for a 'known' contact
                        var identifier = new ContactIdentifier[]
                        {
                            new ContactIdentifier(
                                "twitter",
                                "myrtlesitecore" + Guid.NewGuid().ToString("N"),
                                ContactIdentifierType.Known
                            )
                        };

                        // Print out the identifier that is going to be used
                        Console.WriteLine("Contact Identifier: " + identifier[0].Identifier);

                        // Create a new contact with the identifier
                        Contact knownContact = new Contact(identifier);

                        client.AddContact(knownContact);

                        // Submit contact and interaction - a total of two operations
                        await client.SubmitAsync();

                        // Get the last batch that was executed
                        var operations = client.LastBatch;

                        // Loop through operations and check status
                        foreach (var operation in operations)
                        {
                            Console.WriteLine(
                                operation.OperationType
                                + operation.Target.GetType().ToString()
                                + " Operation: "
                                + operation.Status
                            );
                        }

                        Console.ReadLine();
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }
                }
            }
        }
    }
    ```

2. Edit the `CERTIFICATE_THUMBPRINT` and the `XCONNECT_URL` constants.
3. Save the `Program.cs` file.
4. Press **F5** to run the app. If the connection is established, the app writes the following in the terminal:
    - The contact identifier.
    - That the contact was added.

    ![A terminal with the contact details in the app output.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/104/sitecore-experience-platform/images/xconn-tut1-code2.png)

## Create an interaction with a single event

The next step is to create an interaction with a single event such as a goal.

> [!warning]
> This code sample pollutes your database, because:
>
> -   All interactions require a channel GUID. You define these in Sitecore, but xConnect lets you pass a random channel GUID.
>
> -   All events require an event GUID. You define these in Sitecore, but xConnect lets you pass a random event GUID.
>
>
> If you want to keep your database clean, you must manually delete the interaction and the event created here.

To create an interaction with a single event, for example, a goal:

1. In Visual Studio, in Solution Explorer, double-click the `Program.cs` file and replace the content with the following code:

    ```csharp
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS =
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";

            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";

            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }

            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);

                var certificateModifier = new CertificateHttpClientHandlerModifier(options);

                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);

                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );

                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );

                try
                {
                    await cfg.InitializeAsync();

                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);

                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }

                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        var offlineGoal = Guid.Parse("ad8ab7fe-ab48-4ea9-a976-ae7a268ae2f0"); // "Watched demo" goal
                        var channelId = Guid.Parse("110cbf07-6b1a-4743-a398-6749acfcd7aa"); // "Other event" channel

                        // Identifier for a 'known' contact
                        var identifier = new ContactIdentifier[]
                        {
                            new ContactIdentifier(
                                "twitter",
                                "myrtlesitecore" + Guid.NewGuid().ToString("N"),
                                ContactIdentifierType.Known
                            )
                        };

                        // Print out the identifier that is going to be used
                        Console.WriteLine("Identifier: " + identifier[0].Identifier);

                        // Create a new contact with the identifier
                        Contact knownContact = new Contact(identifier);

                        client.AddContact(knownContact);

                        // Create a new interaction for that contact
                        Interaction interaction = new Interaction(knownContact, InteractionInitiator.Brand, channelId, "");

                        // Add events - all interactions must have at least one event
                        var xConnectEvent = new Goal(offlineGoal, DateTime.UtcNow);
                        interaction.Events.Add(xConnectEvent);

                        // Add the contact and interaction
                        client.AddInteraction(interaction);

                        // Submit contact and interaction - a total of two operations
                        await client.SubmitAsync();

                        // Get the last batch that was executed
                        var operations = client.LastBatch;

                        // Loop through operations and check status
                        foreach (var operation in operations)
                        {
                            Console.WriteLine(
                                operation.OperationType
                                + operation.Target.GetType().ToString()
                                + " Operation: "
                                + operation.Status
                            );
                        }

                        Console.ReadLine();
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }

                }
            }
        }
    }
    ```

2. Edit the `CERTIFICATE_THUMBPRINT` and the `XCONNECT_URL` constants.
3. Save the `Program.cs` file.
4. Press **F5** to run the app. If the connection is established, the app writes the following in the terminal:
    - The contact identifier.
    - That the contact was added.
    - That the interaction with the event was added.

    ![A terminal with the contact and interaction event details in the app output.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/104/sitecore-experience-platform/images/xconn-tut1-code3.png)

Go to the next walkthrough to learn how to [set contact and interaction facets](https://doc.sitecore.com/xp/en/developers/104/sitecore-experience-platform/walkthrough--setting-contact-and-interaction-facets.html "Walkthrough: Setting contact and interaction facets").