---
title: Revoking consent agreements
related:
  - https://docs.kentico.com/k12sp/developing-websites/developing-web-parts/creating-new-web-parts.md
  - https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/creating-consents.md
  - https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/working-with-consents.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

> **Info:** **Kentico EMS required**
>
> Features described on this page require the **Kentico EMS** license.

Kentico does not provide any built-in components that give visitors an option to revoke their [consent agreements](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/working-with-consents.md).

To comply with the [requirements of the GDPR](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance.md), you need to develop and maintain custom components that allow visitors to revoke consent agreements on your website. This way, you can create a solution that best reflects the state of [personal data](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/personal-data-in-kentico.md) processing on your website.

> **Info:** "It shall be as easy to withdraw as to give consent."
>
> (Source: [GDPR Article 7](http://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32016R0679#d1e2001-1-1), Paragraph 3)

To manage consent agreements in the code of your custom components, use the default implementation of the **IConsentAgreementService** interface. The interface provides the following methods:

- **GetAgreedConsents(ContactInfo)** – returns a collection of all consents with which the specified contact has agreed. The returned _Consent_ objects provide the _GetConsentText_ method, which automatically gets either the current texts of the given consent or the texts of the archived consent version for which the agreement was given.
- **Agree(ContactInfo, ConsentInfo)** – creates a consent agreement for a specified contact and consent.
- **Revoke(ContactInfo, ConsentInfo)** – revokes the consent agreement for a specified contact and consent (if such an agreement exists).
- **IsAgreed(ContactInfo, ConsentInfo)** – evaluates whether a specified contact has agreed with a given consent.

> **Note:** **Clearing personal data for revoked consents**
>
> When a visitor revokes a consent agreement, you may also need to delete or anonymize certain types of [personal data](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/personal-data-in-kentico.md) stored by the system.
>
> To perform additional actions of this type whenever a consent agreement is revoked, assign a custom handler to the system's **DataProtectionEvents.RevokeConsentAgreement** [global event](https://docs.kentico.com/k12sp/custom-development/handling-global-events/reference-global-system-events.md).
>
> See also: [Implementing personal data erasure](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/implementing-personal-data-erasure.md)

> **Note:** **Revoking tracking consent through the API**
>
> Consent with the [tracking of contacts](https://docs.kentico.com/k12sp/on-line-marketing-features/managing-your-on-line-marketing-features/contact-management/working-with-contacts.md) and their [activities](https://docs.kentico.com/k12sp/on-line-marketing-features/managing-your-on-line-marketing-features/contact-management/tracking-contact-activities.md) is controlled by the [cookie level](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/working-with-cookies.md) allowed by each visitor.
>
> By default, visitors can manage their tracking consent and cookie level through the **Cookie law and tracking consent** web part. However, if you wish to revoke the tracking consent through the API, you also need to implement code that lowers the visitor's cookie level (below the _Visitor_ level).
>
> ```csharp
>
> using CMS.Core;
> using CMS.Helpers;
>
> ...
>
> ICurrentCookieLevelProvider cookieLevelProvider = Service.Resolve<ICurrentCookieLevelProvider>();
> cookieLevelProvider.SetCurrentCookieLevel(cookieLevelProvider.GetDefaultCookieLevel());
>
> ```

## Example – Creating a web part for revoking consent agreements

The following example demonstrates how to [create a web part](https://docs.kentico.com/k12sp/developing-websites/developing-web-parts/creating-new-web-parts.md) that displays all consents with which the current visitor (contact) has agreed and allows them to be revoked.

Start by implementing the web part code:

1. Open your web project in Visual Studio using the **WebSite.sln** (or **WebApp.sln**) file.
2. Right-click the **CMSWebParts** folder in the Solution Explorer and click **Add -> New Folder**.
3. Name the sub-folder _CustomWebParts_.
4. Create a **Web User Control** named _RevokeConsents.ascx_ in the _CustomWebParts_ folder.
5. Copy the following code into the control's markup:

   ```csharp

   <%@ Control Language="C#" AutoEventWireup="true" 
                             CodeFile="~/CMSWebParts/CustomWebParts/RevokeConsents.ascx.cs"
                             Inherits="CMSWebParts_CustomWebParts_RevokeConsents" %>

   <cms:LocalizedLabel ID="lblInfo" runat="server"
                                    Text="Consent was successfully revoked."
                                    EnableViewState="false"
                                    Visible="false" />
   <cms:LocalizedLabel ID="lblNoData" runat ="server"
                                      Text="You have not given any consents yet."
                                      EnableViewState="false" />

   <asp:Repeater runat="server" ID="rptConsents">
     <ItemTemplate>
       <h3 class="consent-heading">
           <%# HttpUtility.HtmlEncode(Eval("ConsentDisplayName")) %>
       </h3>
       <cms:LocalizedButton runat="server" ID="btnRevoke"
                                           Text="Revoke"
                                           CommandArgument='<%# Eval("ConsentID") %>'
                                           OnClick="btnRevoke_Click" />
       <p>
         <%# Eval("ConsentShortText") %>
       </p>
     </ItemTemplate>
   </asp:Repeater>

   ```
6. Open the control's code behind file (_RevokeConsents.ascx.cs_) and use the following code:

   ```csharp

   using System;
   using System.Linq;
   using System.Collections.Generic;
   using System.Web.UI.WebControls;

   using CMS.ContactManagement;
   using CMS.Core;
   using CMS.DataProtection;
   using CMS.Helpers;
   using CMS.Localization;
   using CMS.PortalEngine.Web.UI;

   public partial class CMSWebParts_CustomWebParts_RevokeConsents : CMSAbstractWebPart
   {
       private IConsentAgreementService consentAgreementService;
       private ContactInfo currentContact;

       // Actions performed when the page is loaded
       public override void OnContentLoaded()
       {
           base.OnContentLoaded();

           // Prepares an instance of the default IConsentAgreementService implementation for managing consents
           consentAgreementService = Service.Resolve<IConsentAgreementService>();

           // Gets the current contact
           currentContact = ContactManagementContext.CurrentContact;

           LoadConsentData();
       }

       // Loads and displays the consent agreements for the current contact
       private void LoadConsentData()
       {
           // Does not attempt to load consent data if the current contact is not available
           // This occurs if contact tracking is disabled or for visitors who have not agreed with the tracking consent
           if (currentContact == null)
           {
               return;
           }

           // Gets all consents with which the current contact has agreed
           IEnumerable<Consent> consents = consentAgreementService.GetAgreedConsents(currentContact);

           // Prepares a data source for the internal repeater control from the loaded consents
           var dataSource = consents.Select(consent => new
           {
               // Each data item contains the ID, display name and short text of the given consent
               ConsentID = consent.Id,
               ConsentDisplayName = consent.DisplayName,
               ConsentShortText = consent.GetConsentText(LocalizationContext.CurrentCulture.CultureCode).ShortText
           });        

           // Binds the data source to the repeater
           rptConsents.DataSource = dataSource;
           rptConsents.DataBind();

           // Displays a message if the current contact has not agreed with any consents
           lblNoData.Visible = !consents.Any();        
       }

       // Revokes a specified consent agreement for the current contact
       protected void btnRevoke_Click(object sender, EventArgs e)
       {
           // Gets the consent based on an ID parameter provided by the clicked revoke button
           Button btn = (Button)sender;
           int consentId = ValidationHelper.GetInteger(btn.CommandArgument, 0);
           ConsentInfo consent = ConsentInfoProvider.GetConsentInfo(consentId);

           if (consent != null)
           {
               // Revokes the specified consent and displays a message to inform the user
               consentAgreementService.Revoke(currentContact, consent);
               LoadConsentData();
               lblInfo.Visible = true;
           }
       }
   }

   ```
7. Save the new files (if you have a web application installation, build the _CMSApp_ project).

After creating the web part code, you need to [register the web part in the system](https://docs.kentico.com/k12sp/developing-websites/developing-web-parts/creating-new-web-parts.md#registering-the-web-part-in-the-system) (you do not need to set up any web part properties) and [add an instance of the web part](https://docs.kentico.com/k12sp/developing-websites/developing-websites-using-portal-engine/using-and-configuring-web-parts.md) to a page on your website.

To test the functionality of the web part:

1. Open your live site in a different browser or an incognito/private window.
2. Agree with some [consents](https://docs.kentico.com/k12sp/configuring-kentico/data-protection/gdpr-compliance/working-with-consents.md).
3. Navigate to the page with the web part.

The web part displays a list of the accepted consents, and buttons that allow you to revoke individual consents.

![Webpart example](https://docs.kentico.com/docsassets/k12sp/revoking-consent-agreements/webpart_example.png)
