Skip To Content

Kentico Extensibility: Logging Contact Activities in a Headless Architecture

Kentico’s extensibility and its support for deep customizations set it apart from other platforms. While many platforms claim to be extensible and to have a powerful API, there really is a broad spectrum of capabilities in this area. Where a platform falls on this spectrum can determine whether it is able to satisfy unique business requirements or whether obstacles will prevent implementing desired features. Kentico's support for deep customization, through an extensible architecture, robust API, and dependency injection is a practical differentiator that makes it shine.

I recently encountered an example of this extensibility that surprised me. Our team is working on a headless implementation of Kentico EMS, in which Kentico is used to provide the marketing content for a large, established e-commerce site. While Kentico is not rendering the website, it is providing the content through a Web API. However, Kentico is not only providing the content, its online marketing features are being used as well. For example, with Kentico's EMS features enabled through a Web API, form data can be submitted, and contact activities can be logged through Web API endpoints.

The Challenge

This project includes a Web API for form data submitted by end users. This endpoint not only writes the data to the custom Kentico form, it also records the “form submission” contact activity. After creating this endpoint, a problem was soon discovered: Contact activities for the form submissions listed the API endpoint (e.g. “”) as the page URL. Furthermore, the URL referrer field was always blank. This problem was creating bad data for marketers when analyzing users’ activities and interests on the site.

Kentico admin activity details screen

The Solution

To solve this problem, I first thought we would either need to create a custom implementation of IActivityLogService, or handle the ActivityProcessedInLogService system event in order to update ActivityInfo properties after they’re created. This would have included ActivityURL, ActivityURLReferer, as well as the ActivityURLHash property. While this seemed feasible, it was not a convenient solution.

However, I was happily surprised to discover that Kentico makes customizing the URL values much easier, by providing an IActivityUrlService Interface. This feature allowed us to inject a custom implementation of IActivityUrlService that supported exactly what we needed and nothing more – a GetActivityUrl method and a GetActivityUrlReferrer method. As a result, here’s what our complete solution looked like:

  • Parameters for the Activity URL and Referrer URL were added to the Web API endpoint.
  • The Web API stores these URL parameters in the HttpContext Items collection, so that they can be retrieved by any component in the HTTP request pipeline.
  • The custom IActivityUrlService retrieves the URL values stored in the HttpContext when called by Kentico’s ActivityLogService.

To demonstrate how easily Kentico allowed this customization to be developed, here’s a simplified version of the custom IActivityUrlService:

/// <summary>

/// A custom IActivityUrlService that returns URLs stored in the HttpContext,

/// by the custom Web API endpoints.

/// </summary>

public class CustomActivityUrlService : IActivityUrlService


    public CustomActivityUrlService()

    { }

    /// <summary>

    /// Get the ActivityUrl from the HttpContext Items collection.

    /// </summary>

    public string GetActivityUrl()


        return CMSHttpContext.Current.Items["ActivityUrlKey"]?.ToString();


    /// <summary>

    /// Get the ActivityUrlReferrer from the HttpContext Items collection.

    /// </summary>

    public string GetActivityUrlReferrer()


        return CMSHttpContext.Current.Items["ActivityUrlReferrerKey"]?.ToString();



After creating the custom component, we registered it with Kentico, so that Kentico would use it instead of its default implementation:

Service.Use<IActivityUrlService, CustomActivityUrlService>();

As a result, marketers now have access to accurate data when analyzing contact activities in Kentico:

kentico admin activity detail screen for campaign

Endless Extensibility

This is just one of the many ways we’ve been able to leverage Kentico’s support for deep customizations in the headless implementation of Kentico CMS. Because Kentico has implemented its API and extensible architecture so well, we have never been prevented from using any marketing automation features due to the headless architecture. This incredible extensibility may be one of the most unsung features of the Kentico platform.

Have questions on how to get the most out of your Kentico implementation? Drop me a line on Twitter (@HeyMikeWills), or contact our BlueModus team of experts.