
July 17, 2025
Microsoft Consent Mode. How to Configure it?
Updated: July 17th, 2025
This article was written by Rick Beijen, who was kind to share his tips with Analytics Mania’s readers
If you are using Microsoft Ads (also known as Bing ads), you are now required to implement Microsoft Consent Mode. If you havenât implemented Microsoft consent mode already and are in the required locations, you probably noticed a drop in conversions attributed to campaigns. Implementing consent mode should get your conversion tracking and attribution up and running again.
This article provides step-by-step guidance for implementing Microsoft Consent Mode using Google Tag Manager or JavaScript and a way to test and verify your setup using the browser developer tools.

Table of Contents
Here’s what you will learn in this article
- #1. What is Microsoft Consent mode, and how does it work
- #2. Debugging with the browser developer tools
- #3. How to configure Microsoft Consent mode in Google Tag Manager
- Disable consent settings in the Microsoft ads tag
- Using Simo Ahavaâs Google consent mode tag template
- Advanced Consent mode – Setting the default
- Updating the consent when consent is given
- Testing the setup
- Basic Consent mode – Setting the default
- Updating the consent and firing the Micorosft tag
- Testing the setup
- #4. Using Markus Baerschâs Microsoft consent mode tag template
- #5. How to configure Microsoft Consent mode hardcoded
- Final words
Video tutorial
If you prefer video content, here’s a tutorial from my Youtube channel (it takes a slightly different approach than the one explained in this article).
#1. What is Microsoft Consent mode, and how does it work
Microsoft began enforcing its Consent Mode in late September 2024 across the European Economic Area, the UK, and Switzerland, making it a required part of their conversion tracking. Like Googleâs Consent Mode, it sets a default consent state and needs to be updated once the user provides consent.
This change from Microsoft is part of a larger, industry-wide shift towards various privacy regulations. Digital advertising platforms are now required to give users more explicit control over how their data is used. Consent Mode is the technical solution that allows advertisers to (somewhat) respect those user choices while still enabling a path for measurement and conversion modeling.
A key difference from Googleâs approach is that Microsoft uses only one parameter, ad_storage, which can be set to granted or denied. When an event is sent, it adds the asc parameter, indicating the user’s consent state:
- A value of G for granted
- A value of D for denied
If the ad_storage parameter looks familiar, that is because it is the same parameter used by Google Consent Mode to control advertising-related storage. This alignment between major platforms is a positive development for marketers. It means that the consent signals you collect from your Consent Management Platform (CMP) can be used to control both Google and Microsoft tags in a standardized way within Google Tag Manager, simplifying your overall consent configuration.
You can choose a basic or advanced implementation, similar to Google’s consent mode.
- Basic: Data is only sent to Microsoft after consent is given but then with the new parameters.
- Advanced: Data is sent to Microsoft without consent, but the Click ID isnât stored or sent. The Click ID (if in the URL) is stored and sent with the updated consent state if consent is given later.
Important to keep in mind
Itâs easy to assume you don’t need to implement Microsoft Consent Mode if your business operates outside the EEA, UK, or Switzerland. However, Iâve encountered cases where conversion data drops to zero, even in other regions.
This suggests that implementing Consent Mode is necessary regardless of your location. The key difference is that youâll need to adjust the default and updated consent states to align with the regulations and practices in your specific country.
Microsoft advanced consent mode
Letâs take a closer look at their advanced consent mode. There isnât a lot of documentation (or any), but I want to show some of my test results.
When visiting the website without giving your consent, the advanced consent mode sends non-consented requests with the asc parameter set to D (denied):
You can see the msclkid in the URL, but itâs not added as a parameter in the request. Also, there is no _uetmsclkid cookie saved with the click ID:
When I accept the cookies (with the click ID still available in the URL), an update command is sent with the click ID:
The cookie is stored, making the ID available for all subsequent events:
But, if we deny the cookies (or ignore the banner) on the first page and accept the cookies on the second page, the click ID is set to N, because itâs not available in the URL:
And again, no cookie:
This lets me believe that the advanced consent mode only works when you have some sort of URL passthrough mechanism for passing the click ID between pages like Google. But, it looks like Microsoft doesnât have that (at least not when Iâm writing this).
Which one to choose?
Legal and privacy concerns aside, I struggle to see any added value in choosing advanced consent mode, given the lack of documentation and how it works. The only use case I can see is if many users donât interact with your consent banner on the first page of their session. But even then, youâd need to implement your own passthrough mechanism.

#2. Debugging with the browser developer tools
First, I will show you what the data looks like in the developer tools, and later, Iâll explain the actual setup in Google Tag Manager.
I am using Google Chrome, but other browsers work similarly.
Checking the network requests
You can use the browser network request to see the request sent to the Microsoft ads servers.
To open the developer tools on any website, use the hotkeys (F12 on Windows or Option + â + I on Mac) or click the three vertically aligned dots at the top right corner of your Google Chrome window, then go to More tools > Developer tools.
Go to the Network tab.
Now reload the page, and youâll see all the network requests made from the browser:
This is where we will debug our setups.
Checking the consent state via the console
Besides checking the network requests, you can get the consent states from the UET script in the console.
You can find the console in the same developer tools:
Paste this code into the console:
console.table(uetq.uetConfig.consent)
This will display the consent state in the console in a nice table:
Here, you can see if consent mode is enabled and if itâs granted or denied.

#3. How to configure Microsoft Consent mode in Google Tag Manager
Configuring Microsoft Consent mode depends on how your consent management is set up. Iâve listed two methods that should cover most of the setups.
It is important to remember that Google Tag Manager does not manage the consent banner that visitors see on your website. That banner is controlled by a Consent Management Platform, or CMP, like Cookiebot, OneTrust, or CookieYes. The job of the CMP is to record the visitor’s choice. Our job in GTM is to “listen” for that choice and then tell our marketing tags, like the Microsoft UET tag, how to behave based on the consent that was given or denied.
Disable consent settings in the Microsoft ads tag
If you are using the Microsoft Advertising Universal Event Tracking template, a checkbox is enabled by default to listen for consent updates:
Disable this setting to manage consent updates manually. Uncheck the box so the tag looks like this:
Using Simo Ahavaâs Google consent mode tag template
First, you need to check if you are using Google Consent mode and if you are managing it using Simo Ahavaâs tag template. If you are, you should have these two tags in your container:
If you donât use that template, the second type of implementation is for you.
Luckily, Simo Ahava has incorporated Microsoft Consent mode into his Google Consent mode tag template. An important note here is that it works by setting the default consent state before the UET tag is loaded, which differs from what is described in the documentation. But it works just as fine.
Letâs look at the advanced and basic consent modes.
Advanced Consent mode – Setting the default
Open your default consent tag and click the âEnable Microsoft Consent Modeâ checkbox:
Scroll down and ensure the ad_storage state is set to your desired value. I want to use a variable that returns âgrantedâ or âdeniedâ based on the consent:
In my case, itâs a dataLayer variable that reads âcookiehub_marketingâ, but in your case, it can be a different event (depending on your CMP). This is the variable:
If your variable returns âtrueâ or âfalseâ like mine, you must convert those to âgrantedâ and âdeniedâ and set the default to âdeniedâ.
Set the trigger to âConsent Initialization – All Pagesâ:
The default command is now set up. One important step is to ensure that your UET tag triggers before consent is granted, for example, on âInitialization – All Pagesâ:
Updating the consent when consent is given
Open your update consent tag and enable the âEnable Microsoft Consent Modeâ checkbox:
Scroll down and set the ad_storage. I want to use that same variable here:
This will set the default and update consent states accordingly and will make sure the default state is âgrantedâ when there already is consent and for every page the user navigates to after giving consent.
Testing the setup
Now itâs time to test. Hit preview:
Wait for the website to open in preview mode and open the network tab in the developer tools:
Reload the page and search for âbingâ in the filter:
If you have not given any consent, the UET tag is loaded, and the default consent state is set to âDenied.â you should see at least these 4 requests:
- bat.js
- <yourid>.js
- A 0?= request for setting the default consent like this: âhttps://bat.bing.net/actionp/0?ti=00000000&…..&evt=consent&src=default&……&asc=Dâ
- A 0?= request to send a pageLoad like this:
âhttps://bat.bing.net/action/0?ti=00000&………&evt=pageLoad&sv=1&asc=DâŠâŠ.â
In my (and probably your) case, youâll see 5 requests. Microsoft is gradually enforcing a default consent state of âDeniedâ for European Economic Area visitors, the UK, and Switzerland. This means you could also see a request like this:
âhttps://bat.bing.net/actionp/0?âŠâŠ&evt=consent&src=enforcedâŠ&asc=Dâ
Itâs fine if you donât see this, as long as there is a default request.
The most important thing is to ensure that the asc parameter is included in every request to Microsoft (the 0?ti=… requests). Click on one of the requests, youâll find the parameter which should be D:
Now accept your cookies, an update request should be sent with G for asc:
When you now navigate to a new page, your pageLoad event (and every other event you implemented) has the same parameter:
When you check the table in the console, it should return this:
Most important are enabled and adStorageAllowed. Those should be true.
Basic Consent mode – Setting the default
There are multiple ways of implementing the basic consent mode. Whatâs important is that you only fire the Microsoft Ads tag when consent is given with the updated parameters. Iâll show you how I like to do it.
Considering that your consent is already implemented in GTM, we first need to set a default, such as advanced consent mode.
Open your default consent tag and enable the âEnable Microsoft Consent Modeâ checkbox:
Scroll down and ensure the ad_storage state is set to your desired value. I want to use the same dataLayer variable like I use in advanced:
The trigger for this tag should be set to âConsent Initialization – All Pagesâ:
Updating the consent and firing the Micorosft tag
Open your update consent tag and enable the âEnable Microsoft Consent Modeâ checkbox:
Scroll down and set the ad_storage. I want to use that same variable here:
Next, I want to enable the dataLayer event:
This will fire an event into the dataLayer when consent is updated. We can use this as a trigger for our Microsoft tag. The dataLayer push will look like this:
To use this, we first have to create a new trigger in Triggers > New:
Choose âCustom Eventâ:
And set the event name to âgtm_consent_updateâ:
Hit save, and now we add it as a trigger for our Microsoft ads tag and set the consent conditions to fire on ad_storage only:
Hit save, and weâre ready to test.
Testing the setup
Hit preview.
The default consent tag should fire first:
With Microsoft consent mode True and in consent denied:
Your update tag should fire on the consent update like this:
With these settings:
Finally, your Microsoft Tag should fire on the gtm_consent_update:
When thatâs working, open the network tab on your website:
Reload the website and search for âbingâ:
Open the pageLoad event. The asc parameter should be G:
And the table in the console should return something like this:
Most important are enabled and adStorageAllowed. Those should be true.

#4. Using Markus Baerschâs Microsoft consent mode tag template
If youâre not using Simoâs tag template or Google Consent Mode at all and need Microsoft Consent Mode in GTM, Marcus Baerschâs tag template is perfect. It makes switching between basic and advanced setups easy, so Iâll show the advanced setup and how to switch.
Microsoft Ads tag
For this method to work best, you must add the default command as a cleanup tag for your Microsoft Ads Tag. The Microsoft Ads tag should fire on a cookie consent dataLayer event. In my case, that trigger looks like this with Cookiehub:
And my Microsoft Ads tag is set to fire on âOnce per pageâ. You can do that in Advanced settings in your tag settings:
And then under Tag firing options:
Make sure your tag settings look the same and that it triggers on cookie consent update. This will differ per CMP but should be quite similar. When you have this, you can move forward.
Adding the Default tag
First, we must get the tag template from the community Template Gallery.
Create a new tag and click on the gallery:
Search for âMicrosoft UET Consent Modeâ and select the template from mbaersch:
Click âChoose templateâ:
This will open the new tag type:
Here, we can set the default consent state and add a timespan in milliseconds of how long UET tags should wait for an “Update” command. In my experience, it works best if you use a timespan of no longer than 2000 milliseconds and a variable to return either âgrantedâ or âdeniedâ in the default command like this:
The tag delays requests to Microsoft by 2 seconds to allow for consent updates and sends it when the update is received. Adjust the timing if needed, but keep in mind that any longer will risk not sending any event before the user navigates.
The variable for the ad_storage is a dataLayer variable that reads âcookiehub_marketingâ. In your case, it can be a different dataLayer event (depending on your CMP):
If your variable returns âtrueâ or âfalseâ like mine, you must convert those to âgrantedâ and âdeniedâ and set the default to âdeniedâ. The last thing to do is set this tag to also fire âOnce per pageâ in Advanced Settings:
You also have these checkboxes:
If you are using TCF, you can enable that checkbox. You can enable that checkbox if you are using Microsoft Clarity and want the tag to manage the Clarity consent. Keep in mind that this requires more configuration in Clarity, which I wonât be going into in this blog post.
You can check the last box if you want the tag to push an event into the dataLayer. It will push a uet_consent_default event with the tag settings like this:
Iâll keep that unchecked.
Save the tag without a trigger and open your Microsoft tag. Here, we can set this tag as the cleanup tag so it fires after the Microsoft tag like this:
Why are we using Tag Sequencing here while we did not use it with Simo Ahavaâs consent mode template?
According to the Microsoft documentation, the consent mode should be set after the UET tag. However, with Simoâs consent mode, itâs impossible (at least right now) to fire the MS consent mode data separately from Googleâs. Thatâs why we set the MS consent mode before the tags. Regardless of Microsoftâs documentation, it still worked fine for me.
But with Markus Baerschâs template, we have a separated MS consent mode, thus we can follow Microsoftâs documentation more thoroughly.
Adding the Update tag
Next to the default tag, we can add an âUpdateâ tag to send changes in consent. The setup is quite similar. First, letâs create a new Microsoft Consent Mode tag. The template should be in your list:
Change the consent command to âupdateâ and set the value. You can either set a static value of âgrantedâ or a variable containing the consent state (I recommend the latter option). In my case, I add my cookiehub_marketing variable:
I keep everything else unchecked. Now, we need to add the same cookie consent trigger trigger:
Iâll add this as a trigger. In the end, it should look something like this:
This tag must fire on âOnce per eventâ instead of âOnce per pageâ. This is the default, but you can double-check here:
Hit save.
Testing the setup
When everything is saved, you can hit preview:
You should see something like this:
If you already had accepted your cookie before, you should see âgrantedâ in both the default and update tags:
But letâs say you come as a new user, so you will default to âdeniedâ, and after a while, you accept your cookies. You should see a default of âdeniedâ on the first cookie_consent_update trigger:
And the update command should fire on the next cookie_consent_update trigger:
Which should then contain âgrantedâ:
To double-check everything, you can look at the network requests. Open the network tab on your website:
Reload the website and search for âbingâ:
Click on one of the requests. Youâll find the parameter, which should be D:
Now accept your cookies, an update request should be sent with G for asc:
When you now navigate to a new page, your pageLoad event (and every other event you implemented) has the same parameter:
When you check the table in the console, it should return this:
Most important are enabled and adStorageAllowed. Those should be true.
Switching Advanced to Basic
If you follow the steps above, you will have implemented the Advanced consent mode. If you want basic, you only need to add a blocking trigger to the Microsoft tag to not fire on events without consent. You can also remove the update tag. This is my blocking trigger:
Itâs set to fire on all events using the regular expression â.*â and when my cookiehub variable doesnât contain granted. I add this as a blocking trigger to my Microsoft tag:
After, you should only see network requests with a value of G for the asc parameter.

#5. How to configure Microsoft Consent mode hardcoded
Sometimes, you canât implement consent mode with GTM and must use JavaScript. This can be needed for many reasons, but itâs important to remember that you donât need both GTM and code. This is unnecessary if you have already implemented consent mode with GTM.
Consult a developer to ensure proper implementation.
Setting the default state
First, youâll need to set the default state. Youâll need to paste this code right after your UET tag code in the <head>:
<script> // UET tag is added here // You can set default consent mode right after the UET tag window.uetq = window.uetq || []; window.uetq.push('consent', 'default', { 'ad_storage': 'denied', 'wait_for_update': 2000 }); </script>
This must be set on every page. Adjust the timeout if needed.
Updating the consent after consent is given
When the user gives their consent, youâll need to update their consent state using this code:
<script> window.uetq = window.uetq || []; window.uetq.push('consent', 'update', { 'ad_storage': 'granted' }); </script>
When to fire this code depends on your consent banner. Itâs best to ask developers to fire this code on cookie consent (specifically the ads category); they will know what to do.
Optional: preventing UET to fire events using a cookie
If you have implemented the default state and the UET tag before consent is given, events will be sent to Microsoft. If you donât want this but you do want to load the UET tag, you can set a cookie named _uetmsdns with a value 1. This will prevent the UET tag from sending events to Microsoft. This is an example code to set the cookie:
document.cookie = "_uetmsdns=1; path=/; Secure; SameSite=Strict";
This will set the cookie, which will be removed when the session ends. Remember that when the user consents, this cookie must be removed.
Testing the setup
Once you have implemented the consent mode codes, itâs time to test the setup. Open the network tab on your website:
Reload the website and search for âbingâ:
If you have not given any consent, the UET tag is loaded, and the default consent state is set to âDenied.â you should see at least these 4 requests:
- bat.js
- <yourid>.js
- A 0?= request for setting the default consent like this: âhttps://bat.bing.net/actionp/0?ti=00000000&…..&evt=consent&src=default&……&asc=Dâ
- A 0?= request to send a pageLoad like this:
âhttps://bat.bing.net/action/0?ti=00000&………&evt=pageLoad&sv=1&asc=DâŠâŠ.â
In my (and probably your) case, youâll see 5 requests. Microsoft is gradually enforcing a default consent state of âDeniedâ for European Economic Area visitors, the UK, and Switzerland. This means you could also see a request like this:
âhttps://bat.bing.net/actionp/0?âŠâŠ&evt=consent&src=enforcedâŠ&asc=Dâ
Itâs fine if you donât see this, as long as there is a default request.
The most important thing is to ensure that the asc parameter is included in every request to Microsoft (the 0?ti=… requests). Click on one of the requests, youâll find the parameter which should be D:
Now accept your cookies, an update request should be sent with G for asc:
When you now navigate to a new page, your pageLoad event (and every other event you implemented) has the same parameter:
When you check the table in the console, it should return this:
Microsoft Consent Mode: Final words
We still donât know much about Microsoft Consent mode, and at the time of writing this blog post, there isnât a lot of documentation around it. For example, how Microsoft handles the denied requests isnât clear, and raises some privacy questions.
Implementing it can also be a bit of a hassle, but Iâm hoping this blog post will help you get on your way. Letâs hope Microsoft gives a little more information about their consent mode in the future.
20 COMMENTS
Hi Rick,
have you come across this article from Microsoft about using the GTM CoMo template: https://help.ads.microsoft.com/#apex/ads/en/60339/1-500 ?
Is this solution proper for Cookiebot CMS? I've read that Cookiebot is the first CMS to offer automatic implementation of MS Consent Mode.
Cookiebot fires the update command by itself. However, I did not notice that it would set the default command, so I do that with GTM
Hi,
I need to follow #4 instructions since I don't use Simo's tag template.
My website's CMS is Hubspot, and they provide an option for Google's consent mode, therefore I didn't have to use any type of CMP as it's all managed automatically through Hubspot cookie banner.
Inside my GTM, I never added a cookie consent dataLayer event - my Microsoft UET tag uses "All Page Views" as a trigger to be fired.
How can I implement the instructions from #4 considering I don't have a Custom Event for cookie consent or a CMP?
thank you!
If there is no consent information in the dataLayer then I would work with a developer to push it. Hubspot has a relatively simple JS api for that: https://developers.hubspot.com/docs/reference/api/analytics-and-events/cookie-banner/cookie-banner-api
You can push the consent information into the DL and then use it in the microsoft consent mode tag.
Hi,
Thanks for this, would this be the same when using Microsft Clairty tag rather than just Bing tags?
The documentaion for this from Microsoft is terrible.
No, this applies only to Bing tags. Clarity requires a different setup https://learn.microsoft.com/en-us/clarity/setup-and-installation/cookie-consent
Thats what worried me as that link talks about the code being directly on the website where as our code is in GTM.
I noticed that if you have multiple pixels deployed, each with a different UETQ tag, only the first pixel (the one with the default uetq 'uetq' value) will fire with the right asc: 'G' values after consent is updated. Do you have any recommendations on how to implement this so that all deployed pixels each fire with their own asc value based on the single consent provided by the user?
Hey Julius - the update timespan (Baersch), I don't get it.
The default push is denied -> now if someone updates consent it will be granted.
So with this timespan on the default push, am I changing the default value to granted if the user grants consent within the timespan, or will this push an update signal automatically?
Or does it just holds all UET Events until timespan is over (and if there is an update signal within 1500ms, we are good as we send the Tags with positive consent?)
Best
Christoph
Heyy Julius - the update timespan (Baersch), I don't get it.
The default push is denied -> now if someone updates consent it will be granted.
So with this timespan on the default push, am I changing the default value to granted if the user grants consent within the timespan, or will this push an update signal automatically?
Or does it just holds all UET Events until timespan is over (and if there is an update signal within 1500ms, we are good as we send the Tags with positive consent?)
Best
Christoph
Thanks a lot for this, was of great help.
Hi Julius/Rick,
I think you might have copied by accident the Simo Ahava setup screenshot to the 'Testing the setup' section for the alternative Markus Baersch setup... Could you update it with a correct screenshot? It's quite confusing this way.
Thanks,
Jeroen
Which exact screenshot? There are many of them in that section.
Hi Julius,
i need to handle the Bing CoMo in a custom html tag (your #5 way). Since i'm firing the bing tags - PageLoad and Config - when the ad_storage is granted (Basic), i've few questions:
- Do i need to add the Default and Update State?
- If not, Which state should i set?
- If yes, seems they told us to switch to Advanced, right?
Thanks
Hi Julius,
Our CMP CookieYes does MS consent mode out the box. Basically nothing fires until consent is granted which is fine. Is this basic consent mode?
In your video you suggest using a GTM template to set a default consent state. Is this advanced consent mode? However, I can't get this default state tag to fire as CookieYes tells you to set the UET trigger as cookie consent update so it only fires when consent is given.
Any help be appreciated!
For the hard coded implementation (No. 5) you need to correct the code to snake case. It must be 'wait_for_update' instead of 'Wait_for_update' (and the comment must be moved into the script tag).
Good catch. I fixed the errors. Thanks
Guys, this was incredibly helpful. This is not the first time you back me up with Consent mode, thank you so much.
Hello Julius and Rick,
In your example above, youâve set the trigger for the UET tag to âInitialization â All Pages.â However, this setup wouldnât work in a case where a user visits the site and gives consent afterward. Since the trigger fires before the consent is received, the UET tag wonât activate. It would only trigger on the next page load (e.g., after the user clicks to a new page).
There is a workaroundâtriggering the UET tag on consent updateâbut this is not ideal either, since the first consent update happens after initialization.
Do you have any tips on how to trigger the UET tag without a page reload and without creating complex triggers (like triggering on the second consent update only if consent wasn't given earlier)?