Table of contents

Microsoft Ads Conversions API: How to keep measuring when Safari blocks your UET tag

The Microsoft Ads Conversions API (CAPI) lets you send conversion events to Microsoft Advertising directly from your server instead of from the visitor's browser. It uses the same Universal Event Tracking (UET) event model as the JavaScript tag, so measurement continues when Safari or an ad blocker stops the browser tag from reaching Microsoft. Microsoft runs it as a pilot, so they have to enable it on your account before you can start.

Microsoft Ads still measures most websites with a Universal Event Tracking (UET) tag in the browser. That script reads the Microsoft Click ID (msclkid), writes cookies, and sends page loads and conversions to Microsoft from the visitor's device. For a long time, that was a reasonable default. Browsers tolerated third-party pixels, and the call to bat.bing.com usually arrived.

That path is now easy to break. In Safari 27, which is in beta and ships with iOS 27 and macOS 27, the connection to Microsoft's ad servers can be cut before any data leaves the device. Ad blockers drop the same request. Cookie limits expire the identity that remarketing and bidding still use. Campaigns keep spending. The conversion signal that should train automated bidding shows up late, or not at all.

When Microsoft Ads looks weaker than Google Ads, the channel is sometimes the real issue. A lot of the time the UET tag never made it out of the browser. That is a measurement infrastructure gap.

What is Universal Event Tracking (UET)?

Universal Event Tracking (UET) is Microsoft Advertising's website tracking layer. One tag on the site records what people do after an ad click, then Microsoft uses that feed for conversion goals, remarketing, and automated bidding.

The usual install is JavaScript. The browser loads Microsoft's tag, then talks to Microsoft's endpoints, most visibly bat.bing.com. Auto-tagging appends msclkid to the landing URL. The tag reads it, stores it, and attaches it to later events so a purchase can join back to the click.

Browser-only measurement used to be enough because those requests were allowed to complete. Destination URL goals watched page loads. Custom events fired on checkout. Remarketing pools filled because Microsoft could see returning visitors in the browser. The UET helper extension can still look healthy on Chrome while Safari and blocked browsers send almost nothing.

Why Safari and ad blockers break the Bing UET tag

UET is a client-side tag. If the script never loads, or the network call never completes, Microsoft never sees the visit.

Safari 27 is the sharp case. WebKit's tracking protection can block bat.bing.com at domain level and by IP range, at the network layer rather than by inspecting the page. The script can sit in Google Tag Manager (GTM). The connection still dies. A first-party proxy that only changes where the script loads from does not help, because the browser still has to reach Microsoft's ad servers. Those IPs are what Safari can cut. The Safari 27 tracking protection write-up covers that mechanism, including why Bing UET is on the exposed list with LinkedIn.

Ad blockers treat UET like any other ad pixel. EasyList-style filters drop the script or the bat.bing.com request, and strict tracking protection modes in Firefox and Edge do the same. The visitor still buys. Microsoft Ads never gets the purchase. How ad blockers hit measurement is the wider version of that story.

Cookies are a slower leak. Safari's Intelligent Tracking Prevention (ITP) caps many JavaScript cookies at seven days, and shorter in some cross-site landing patterns. Remarketing lists shrink. A conversion that happens on a return visit loses the click ID that UET stored in the browser.

Safari's Link Tracking Protection can also strip msclkid in Private Browsing and in links opened from Mail or Messages, the same way it strips gclid and fbclid. If the click ID never lands on the page, the UET tag has nothing to attribute even when the network call succeeds.

What the Microsoft Ads Conversions API does

The Microsoft Ads Conversion API (CAPI), also documented as the UET Conversion API, is the server path for the same UET event model. Instead of the browser posting to Bing, your backend (or a server GTM container) sends a POST to:

https://capi.uet.microsoft.com/v1/{tagId}/events

Authorization is a Bearer token tied to that UET tag. Microsoft's current guide is Conversions API (CAPI). Server-side GTM is listed there as a supported way to send the events.

Two event types matter for websites:

Page load events. One per page view, including single-page application (SPA) route changes. They carry the page URL, referrer, title, and a pageLoadId. Destination URL goals and a lot of remarketing context depend on these. Skipping them and only posting purchases is the most common incomplete setup.

Custom events. Purchases, leads, add-to-cart, search, whatever maps to your conversion goals. Richer fields live here: value, currency, transaction ID, product IDs.

Conversion goals have to exist before you start sending. CAPI delivers events into goals you have already created in Microsoft Ads. If no goal is tied to that UET tag and matching your eventName, Microsoft will accept your events with a 200 response and no conversion will appear in the interface.

One quirk to plan for: revenue cannot ride on a page load event. If a destination URL goal needs variable revenue, Microsoft's answer is a second custom event carrying only the revenue value and the matching pageLoadId.

Custom events should reuse the pageLoadId from the page they happened on. Microsoft wants that ID as a version 4 universally unique identifier (UUID). Without it, the conversion is an orphan next to the page context the JavaScript tag would have sent for free.

Microsoft recommends using CAPI with UET whenever possible. Their reason: UET captures browser-based activity and page context, and CAPI is the server path for additional events and details after UET fires. The same guide treats CAPI as an alternative when JavaScript cannot be used, which is the Safari and ad blocker case. The CAPI schema already has page URL, referrer, user agent, IP, msclkid, and hashed email. If the server container received those fields, they go on the POST. That server call is what still reaches Microsoft when bat.bing.com is blocked.

Events must be recent. eventTime is a UNIX timestamp in seconds, and Microsoft rejects timestamps older than seven days. Near real-time delivery is the useful mode. Overnight dumps fight bidding systems that want conversions while the click is still warm.

Hashed email and hashed phone (SHA-256, after Microsoft's normalization rules) improve matching when cookies and click IDs are missing. Microsoft calls that enhanced conversions. It travels on the same CAPI payload.

UET JavaScript tagConversions API
Where it runsVisitor's browserYour server
Blocked by Safari and ad blockersYesNo
Reads msclkid automaticallyYesYou store and send it
Page context (URL, referrer, title)AutomaticYou send it
Offline and CRM eventsNoYes
Available to every accountYesPilot accounts only

Access is not automatic

CAPI is documented in full, but it is still a pilot. Microsoft provisions it per account, and you cannot switch it on yourself. Microsoft's own support answers are blunt about this: the route in is to ask your account manager or Microsoft Advertising support to enroll the customer ID (CID).

Once the account is enrolled, the token sits under the UET tag in the Microsoft Advertising UI: edit the tag, choose Use Conversions API, copy the token. There is also a Campaign Management API call (UetTagAuthKey/Query) that returns the same kind of key.

Before enrollment, that option is simply not on the screen. Building the GTM tags first, then finding a blank token screen, is a familiar way to lose a week.

The flag lives on the customer account that owns the UET tag. An agency manager account can look fully set up while the client's CID still has no CAPI access.

The part teams skip: client-side ID sync

CAPI moves the event payload server-side. Identity matching for remarketing does not fully move with it.

Microsoft still wants a client-side ID sync pixel so it can map your visitor IDs to Microsoft IDs. Their docs say to fire it in the browser, not from the server, so Microsoft can read the browser context at sync time. The documented endpoint looks like:

https://c.bing.com/c.gif?vid={VID}&Red3=BACID_{customerId}

The fields are easy to mix up.

  • Red3 is required. Format is BACID_ plus the Microsoft customer ID. That CID is not the UET tag ID. One customer account can hold several UET tags. Accounts with more than one CID should use the primary CID unless Microsoft says otherwise.
  • VID (visitor ID) is required. Anonymous guest ID, preferably a version 1 UUID, which differs from pageLoadId where Microsoft asks for a version 4 UUID. The same value must go to CAPI as anonymousId. If they drift, Microsoft cannot join the server event to the sync.
  • UID is optional. An anonymized signed-in user ID. On the CAPI side that lines up with externalId.

Microsoft calls ID sync required for audience creation and remarketing, including dynamic remarketing. For conversion quality it is "highly recommended," especially when msclkid or hashed email and phone are missing. Microsoft wants it sitewide when practical, and at least once per user session.

This is the hybrid setup people miss: a thin client beacon for identity, and server-to-server events for the conversion payload browsers keep blocking.

ID sync is still a browser call to Microsoft. Safari and ad blockers can cut c.bing.com the same way they cut bat.bing.com. That is frustrating. It is also why hashed email, hashed phone, and msclkid still belong on the server event. The pixel helps when it fires. CAPI still has to stand on identifiers you control.

Why msclkid still matters

msclkid is Microsoft's click identifier. With auto-tagging on, Microsoft appends it to the landing URL after an ad click. UET JavaScript used to capture that for you. On CAPI, that job is yours.

Microsoft's guidance is specific: store the most recent msclkid per user (first-party cookie, local storage, or a server store), overwrite it when a new one arrives, keep it around for about 90 days, and send it on later UET events for that user. Format is a UUID. Visitor ID alone is a weak substitute when a click ID existed.

And yes, this is still worth doing even if hashed email is already in the payload. Click ID matching and enhanced conversions solve different gaps.

Without msclkid, CAPI events can still land in Microsoft's pipeline. Attribution to the click that actually paid for the visit gets worse. Automated bidding then trains on a fuzzier graph.

Safari can remove msclkid before the page runs, in the same Link Tracking Protection cases that already affect Google and Meta click IDs. Server-side GTM cannot recover a query parameter that never hit your site. The useful pattern is to store it on first landing when it is present. For the sessions where it is gone, hashed email and phone are the backup Microsoft can still match.

How to set up Microsoft CAPI in server-side GTM

Microsoft's docs treat a tag manager or server-side tag manager as a valid sending path. The architecture is the same one used for Meta CAPI or Google Ads server tags. The browser talks to a first-party domain you control. The server container POSTs to capi.uet.microsoft.com. Safari never sees that Microsoft call.

Placement follows the usual split. Conversion events belong in the server container. The ID sync pixel stays in the web container, because it has to run client-side. The server-side GTM (sGTM) platform checker is the broader map of web vs server placement. Microsoft CAPI is that same pattern: server for the event body, web for the identity beacon.

High-level path:

  1. Token and tag ID. Once CAPI is visible on the account, copy the UET tag ID and the auth token. Store both as server GTM variables. Current Microsoft guidance for dual-signal setups is to reuse the same UET tag ID, and to send the same eventId and eventName on the browser event and the CAPI event so Microsoft can deduplicate.
  2. Get site events into the server container. Web GTM reads the data layer (purchase, generate_lead, and the page view that should become a CAPI page load). Google Analytics 4 (GA4) is the usual transport into the server container. A data client can also accept webhooks from a shop or CRM. Keep names and revenue fields consistent with what you already send Google and Meta.
  3. Mint pageLoadId and eventId early. A new UUID for each page view or SPA navigation. Custom events on that page reuse it. Conversion eventId needs to be stable: the same string on the UET JavaScript event and the CAPI event if both fire. Order ID plus a suffix is fine if it stays unique.
  4. Send the CAPI POST from the server container. Server GTM ships a built-in HTTP Request tag. A POST to capi.uet.microsoft.com with a Bearer header and a JSON body is enough if you map the payload yourself. Community gallery templates exist if you want GA4-to-UET field mapping done for you. Some of those templates can also instruct the browser to fire the ID sync pixel. The request still needs the tag ID in the path, pageLoad and/or custom events, userData with at least one identifier, msclkid when you have it, and pageLoadId linking custom events to page loads. User agent, IP, hashed email, hashed phone, and anonymousId matching VID all help matching.
  5. Keep ID sync in the web container. Image pixel or equivalent with VID and Red3. Microsoft's docs say this has to be a client-side pixel, not a server HTTP request.
  6. Gate on consent. CAPI supports adStorageConsent: G for granted, D for denied. Denied events are not used for attribution or retargeting. If you omit the field, Microsoft treats consent as granted. Pass Consent Management Platform (CMP) signals into server GTM and align the Microsoft tag with the same ads-storage rules you already apply to Google and Meta.
  7. Test before you change bidding. GTM Preview on web and server. A 200 from CAPI is not the same as a conversion in the UI, and a 200 can still carry warnings for fields Microsoft dropped. Check Microsoft's conversion / UET diagnostics, then a test purchase or lead that carries a known msclkid. Watch batch behavior too: by default one invalid event fails the whole request, so set continueOnValidationError if you would rather have the good events processed and the bad ones reported. Compare browser-only vs server volume for a stretch before automated bidding starts learning from the new feed.

Where TAGGRS fits

Microsoft CAPI needs a server GTM container on a first-party domain, consent logic in one place, and a clean event stream you can send to Microsoft next to Google Ads, Meta and LinkedIn.

TAGGRS hosts that server container, maps a subdomain (or same-origin path) on your domain, and gives you one place to process events before they leave for ad platforms. The Microsoft token and payload mapping stay in GTM. Hosting, first-party delivery, and the operational layer that makes server-side tagging practical sit with TAGGRS.

If GA4 already flows into a TAGGRS server container, Microsoft CAPI is another destination tag on that stream. It is not a second tracking stack. The ID sync pixel stays in the web container either way.

Create a free TAGGRS account and have the server container running before your CAPI access comes back from Microsoft or book a demo if you would rather see the setup on your own site first.

Conclusion

Browser UET has become an unreliable default for Microsoft Ads measurement. Safari 27 and ad blockers stop a meaningful share of UET calls before they reach Microsoft, and cookie limits then expire the identity that remarketing depends on. The Conversions API moves those events onto a server path you control, with the UET JavaScript tag still running wherever it loads.

The blocker for most teams is access rather than implementation. CAPI is a pilot, so ask your Microsoft account manager to enable it on your customer ID, and use the waiting time to get the server container and event stream in place. If you already run Meta CAPI, this is the same category of work for a channel you are currently measuring with less accuracy than you think.

FAQ

Do I still need the UET JavaScript tag?

Yes, wherever it still loads. Microsoft's guidance is to run CAPI alongside UET, because the JavaScript tag observes browser activity and page context that a server event does not automatically carry. When both send the same conversion, use the same eventId, eventName and UET tag ID so Microsoft counts it once.

Microsoft also describes CAPI as the alternative when JavaScript cannot run, which is the Safari and ad blocker case covered above. A complete CAPI setup in their documentation has two parts: the server-to-server events, and the client-side ID sync pixel. Page URL, referrer, user agent, IP and msclkid are all part of the CAPI schema.

Is Microsoft CAPI generally available?

No. The documentation is public and complete, but access is still a pilot that Microsoft grants per account. If Use Conversions API is missing on the UET tag, that is the expected state for an account nobody has enrolled yet. Ask the Microsoft account manager or support to add the CID.

Can I send only purchases server-side?

You can POST only custom conversion events. Destination goals and audiences will look worse than they should. Plan page loads and custom events together.

My events return 200 but no conversions show up. Why?

In most cases the answer is the conversion goal. Check that a goal is present in Microsoft Ads, that it is attached to the same UET tag ID you are posting to, and that its event action matches your eventName exactly. Then check that eventTime falls inside the seven-day window and that msclkid or a hashed identifier is present on the event.

Does this replace offline conversion imports?

CAPI can also carry CRM, offline, and app events through the same endpoint. That is a different event source than website page loads. Classic offline import workflows still exist for conversions that land days later in a CRM. Website eventTime must be within the last seven days, so a stale CRM dump will fail validation.

Where does Microsoft CAPI belong in GTM?

Server container for the CAPI POST. Web container for the ID sync pixel. Microsoft also recommends keeping the UET JavaScript tag where it can load, with a shared eventId if both sides send the same conversion.

What if Safari also blocks the ID sync pixel?

Then Microsoft cannot join your visitor ID to its own IDs on those sessions, so remarketing lists miss that traffic. The conversion can still land, because the CAPI POST leaves from your server, not from Safari. Put msclkid, anonymousId, and hashed email or phone on that event so Microsoft can still match it to a click or a known user.

How do I stop double counting?

One eventId for the same conversion on UET JavaScript and CAPI, same UET tag ID, compatible eventName. Confirm both tags actually send that ID. Counts should be checked against orders or CRM, not only against the Microsoft Ads conversion column.

About the author

Recently published

magnifiercrossmenu linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram