---
title: "Create a contact processor"
slug: "create-a-contact-processor"
abstract: "How to create and register a contact processor."
---
# Create a contact processor

This topic demonstrates how to create and register your own contact processor.

<details>
<summary><h2>Inherit ContactProcessingProcessor</h2></summary>

All contact processors inherit from `Sitecore.Analytics.Aggregation.Pipeline.ContactProcessingProcessor`:

```csharp
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
    }
}
```

</details>

<details>
<summary><h2>Specify contact facets to retrieve</h2></summary>

The processing pipeline uses the [xConnect Client API](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-platform/xconnect-client-api-overview.html "xConnect Client API overview") to retrieve contacts. You must specify which contact facets to retrieve by decorating your processor with `UsesContactFacets`.

Example of usage:

```json
[UsesContactFacets("Personal", "Classification")]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
    }
}
```

It is recommended that you do not hard-code facet keys - Sitecore’s [built-in facet names](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-platform/use-core-collection-model-facets.html "Use core collection model facets") are located on the facet object itself - such as `PersonalInformation.DefaultFacetKey`.

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
}
```
> [!important]
> If you do not explicitly request a particular facet, it will not be available during processing. To understand why, read more about the role of expand options when [getting contacts](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-platform/get-contacts.html "Get contacts").

</details>

<details>
<summary><h2>Using ContactProcessingArgs</h2></summary>

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
    }
}
```

### Accessing the contact

The contact is available directly on the `args`:

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
        var contact = args.Contact;
    }
}
```

If you requested any contact facets, they can be accessed via the `.GetFacet<T>` extension method:

```csharp
var personalFacet = args.Contact.GetFacet<PersonalInformation>(PersonalInformation.DefaultFacetKey);

Alternatively, use the extension methods found in `Sitecore.XConnect.Collection.Model`:
```

```csharp
var personalFacet = args.Contact.Personal();
```

### Access processing reason

The `args.ProcessingReason` property returns an `enum` of type `Sitecore.Analytics.Processing.ProcessingReason`, which tells you why the contact is being processed in the first place.

- `Created`: The contact is new
- `Updated`: The contact was updated
- `Obsoleted`: The contact identifier has been obsoleted
- `Unknown`: Reason for processing is unknown

### Accessing other APIs

Every processor has access to the following APIs via `args.Sources`:

- xConnect Client API
- Reference Data Service
- Defintion managers
- Taxonomy managers

> [!important]
> In the context of a contact processor, all service end points - xConnect, definitions, taxonomy, and the reference data service - should be treated as read-only.

#### Accessing xConnect

A read-only instance of the xConnect Client API is accessed via `args.Sources.Collection`. You can search or get contact data:

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
        // Searching
        var contacts = args.Sources.Collection.Contacts.Where(x => x.Identifiers.Any(c => c.IdentifierType == ContactIdentifierType.Known));
    }
}
```
> [!note]
> Remember that the contact is available via `args.Contact`.

#### Accessing definition managers

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
        var goalManager = args.Sources.Definitions.GetDefinitionManager<IGoalDefinition>();
    }
}
```

#### Accessing taxonomy managers

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
        var assetTaxonomyManager = args.Sources.Taxonomies.GetManager<AssetTaxonomyManager>();
    }
}
```

#### Accessing the reference data service

```json
[UsesContactFacets(PersonalInformation.DefaultFacetKey, Classification.DefaultFacetKey)]
public class SampleProcessor : ContactProcessingProcessor
{
    protected override void OnProcess(ContactProcessingArgs args)
    {
        var definitionType = args.Sources.Reference.EnsureDefinitionType("alpha");
        var criteria = new DefinitionCriteria("enterprise", definitionType)
        {
            Culture = new CultureInfo("da")
        };

        Definition<string, string> definition = args.Sources.Reference.GetDefinition<string, string>(criteria, true);
    }
}
```
> [!note]
> The contact processing pipeline uses a read only version of the reference data service API - it does not use the client API.

</details>

<details>
<summary><h2>Configuring a contact processor</h2></summary>

Add your processor to the contact processing pipeline as shown:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <sitecore>
<pipelines>
  <group groupName="analytics.aggregation">
    <pipelines>
      <contacts>
        <processor type="Sitecore.Analytics.Aggregation.Tests.Processors.FakeContactProcessingProcessor, Sitecore.Analytics.Aggregation.Tests" />
      </contacts>
    </pipelines>
  </group>
</pipelines>
    </sitecore>
</configuration>
```

</details>