---
title: User notification examples
slug: cms-13/docs/user-notification-examples
docTags: 
createdAt: 2026-07-30T20:22:10.000Z
---

These examples demonstrate common tasks with the Notification and Subscription APIs in CMS 13. Each sample covers a self-contained scenario: posting messages, building custom formatters and providers, retrieving notifications, and managing subscriptions.

These examples require CMS 13 with the notification framework enabled. Add the relevant NuGet packages before running the code.

## Create and post a message

Post a notification message to a channel by calling `PostNotificationAsync` on `INotifier`.

```csharp
var notifier = ServiceLocator.Current.GetInstance<INotifier>();
INotificationUser receiver;
INotificationUser sender;

await notifier.PostNotificationAsync(new NotificationMessage() {
  ChannelName = "epi.example",
    Content = "A page has been improved!",
    Subject = "Improvement",
    Recipients = new [] {
      receiver
    },
    Sender = sender,
    TypeName = "PageChanged"
});
```

## Create a custom formatter

Build a formatter that joins multiple messages into a single combined message by implementing `INotificationFormatter`. This formatter concatenates the content of all incoming messages.

```csharp
[ServiceConfiguration(typeof (INotificationFormatter))]
public class StringJoinFormatter: INotificationFormatter {
  public string FormatterName {
    get {
      return "epi.stringjoinformatter";
    }
  }
  public IEnumerable<string>SupportedChannelNames {
    get {
      return new [] {
        "epi.example"
      };
    }
  }
  public Task<IEnumerable<FormatterNotificationMessage>>
    FormatMessagesAsync(IEnumerable<FormatterNotificationMessage>notifications,
      string recipient,
      NotificationFormat format,
      string channelName) {
      var message = new FormatterNotificationMessage(notifications.SelectMany(x => x.ContainedIDs)) {
        Subject = "Joined Message",
          Content = string.Join(Environment.NewLine, notifications)
      };
      return Task.FromResult((IEnumerable<FormatterNotificationMessage>) new [] {
        message
      });
    }
}
```

## Add user notification formatting

Extend a formatter with `IUserNotificationFormatter` to control how notifications render in the CMS 13 UI. This example applies blue text styling to the notification content.

```csharp
[ServiceConfiguration(typeof (IUserNotificationFormatter))]
public class BlueFormatter: IUserNotificationFormatter {
  public IEnumerable<string> SupportedChannelNames {
    get {
      return new [] {
        "epi.example"
      };
    }
  }
  public Task<UserNotificationMessage> FormatUserMessageAsync(UserNotificationMessage notification) {
    notification.Content = "<div style=\"color:#0000FF\">" + notification.Content + "</div>";
    return Task.FromResult(notification);
  }
}
```

## Retrieve user notifications

Query unread notifications for a specific channel by calling `GetUserNotificationsAsync` on `IUserNotificationRepository`. This example retrieves the 25 most recent unread notifications. The blue formatter from the previous example applies formatting to the content.

```csharp
INotificationUser user;
var repository = ServiceLocator.Current.GetInstance<IUserNotificationRepository>();
var query = new UserNotificationsQuery {
  ChannelName = "epi.example",
    User = user,
    Read = false
};
var notifications = repository.GetUserNotificationsAsync(query, 0, 25, UserNotificationFormattingMode.Required).Result;
```

## Create a custom provider

Build a provider that outputs notifications to the console by implementing `INotificationProvider` and `INotificationProviderStatus`. The `INotificationProviderStatus` interface enables runtime control to disable the provider during specific time windows.

```csharp
[ServiceConfiguration(typeof (INotificationProvider))]
public class PrintMessageProvider: INotificationProvider, INotificationProviderStatus {
  public string ProviderName {
    get {
      return "PrintMessage";
    }
  }
  public NotificationFormat GetProviderFormat() {
    return new NotificationFormat {
      MaxLength = 64, SupportsHtml = false
    };
  }
  public Task
  SendAsync(IEnumerable<ProviderNotificationMessage> messages,
    Action<ProviderNotificationMessage> succeededAction,
    Action<ProviderNotificationMessage,
    Exception > failedAction) {
    foreach(var item in messages)
    Console.WriteLine(item.Content);
    return Task.FromResult(true);
  }
  public bool IsDisabled {
    get {
      return DateTime.Now < DateTime.Today.AddHours(6);
    }
  }
  public string DisabledReason {
    get {
      return "No printing after midnight";
    }
  }
}
```

## Manage subscriptions

Use `ISubscriptionService` to manage subscriber lists for content-based notification keys. This example subscribes users to a content item and retrieves all subscribers except the sender.

```csharp
public IEnumerable<INotificationUser> HandleContentSubscibers(ContentReference content, IList<INotificationUser> users, INotificationUser sender) {
  // Make a subscriptionKey
  Uri subscriptionKey = new Uri(string.Format("epi://example/content/{0}", content.ID));

  // Subscribe all recipients of the notification, including the sender of the notification
  _subscriptionService.SubscribeAsync(subscriptionKey, users).Wait();
  _subscriptionService.SubscribeAsync(subscriptionKey, sender).Wait();

  // Get all subscribers except the sender of the notification
  var recipients = _subscriptionService.FindSubscribersAsync(subscriptionKey).Result;
  recipients = recipients.Where(u => !u.UserName.Equals(sender.UserName, StringComparison.OrdinalIgnoreCase));

  return recipients;
}
```
