Skip to main content
GUIDE · MICROSOFT ADS9 min read

Microsoft Ads Conversions API: the 2026 setup manual

A practical guide for sending Microsoft Advertising conversions from TrackLayer with clean OAuth, developer token headers, Microsoft Click ID capture, offline import fields, online UET CAPI events, Bing Ads UI validation, and production troubleshooting.

Context

Why Microsoft Ads CAPI

Microsoft Advertising is no longer just a legacy Bing search buy. It sits across the Microsoft-owned Bing search network, Edge, MSN, Outlook inventory, syndicated search partners, retail media surfaces, and audience products that can blend search intent with profile and workplace signals. That makes the conversion stream more valuable than a simple last-click report. If the browser tag loses the order, the bidding system loses the feedback loop that tells it which searches, audiences, and placements created real business value.

LinkedIn audience syndication is the reason B2B and high-consideration teams should take Microsoft Ads server events seriously. Microsoft can package LinkedIn-derived professional audience segments into Microsoft Advertising campaigns, while Bing search captures active demand. TrackLayer gives that media mix a server-side conversion record after forms, sales calls, subscriptions, and purchases are confirmed. The result is cleaner measurement for the Microsoft and LinkedIn audience surface without depending entirely on page scripts, third-party cookies, or checkout redirects.

Requirements

Prerequisites

01

Microsoft Advertising account access with permission to create conversion goals, inspect Conversion Tracking, and use the account that owns the campaigns.

02

Developer Token for the Microsoft Advertising API, stored server-side and sent with every Campaign Management or Bulk API request.

03

OAuth2 refresh_token for a user who can access the customer and account, plus a backend job that exchanges it for short-lived bearer tokens.

04

customer_account_id and customer_id values for the ad account and manager account context used in request headers.

Build

Step-by-step setup

Step 1

Create the conversion goal first

Start in Microsoft Advertising by creating the conversion goal that your server events will update. The ConversionName you send must match the goal name exactly, including case and spacing. For offline imports, wait at least two hours after goal creation before sending production data so Microsoft can apply the goal configuration.

{
  "goal": {
    "name": "Purchase",
    "type": "OfflineConversion",
    "revenue": "VariableValue",
    "count": "All",
    "conversionWindowInMinutes": 43200
  }
}
Step 2

Exchange the refresh token

Use the OAuth2 refresh_token from your Microsoft Advertising user to get an access token before calling the API. Cache the bearer token until it expires, but never put either token in client-side code. A token failure should stop the batch because partial retries without account headers are difficult to reconcile.

POST https://login.microsoftonline.com/common/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

client_id=00000000-0000-0000-0000-000000000000&
client_secret=CLIENT_SECRET&
grant_type=refresh_token&
refresh_token=M.R3_BAY...&
scope=https%3A%2F%2Fads.microsoft.com%2Fmsads.manage%20offline_access
Step 3

Apply offline conversions

For sales, qualified leads, calls, and CRM events that happen after the click, call the v13 offline conversion apply endpoint. Send the original user action time in UTC, not queue processing time. Microsoft accepts up to 1,000 offline conversions per request, so batch by account while preserving one stable source event ID in your own logs.

POST https://campaign.api.bingads.microsoft.com/CampaignManagement/v13/OfflineConversions/Apply
Authorization: Bearer ACCESS_TOKEN
DeveloperToken: DEVELOPER_TOKEN
CustomerAccountId: 123456789
CustomerId: 987654321
Content-Type: application/json

{
  "OfflineConversions": [
    {
      "ConversionName": "Purchase",
      "ConversionTime": "2026-04-23T10:15:30Z",
      "ConversionValue": 149.95,
      "ConversionCurrencyCode": "USD",
      "MicrosoftClickId": "dd4afcccb1c9a4cad9544dd7e5006"
    }
  ]
}
Step 4

Send real-time UET CAPI events when available

Microsoft also supports server-side UET events through the Conversions API endpoint. Use this for page load and custom website events that need near real-time delivery, deduplication by eventId, consent signals, hashed identifiers, and transaction IDs for online conversion adjustments.

POST https://capi.uet.microsoft.com/v1/123456789/events
Authorization: Bearer UET_API_TOKEN
Content-Type: application/json

{
  "data": [
    {
      "eventType": "custom",
      "eventName": "checkout_complete",
      "eventId": "ord_10492_purchase",
      "eventTime": 1776944130,
      "eventSourceUrl": "https://shop.example/checkout/complete",
      "pageLoadId": "bcf3000b-65fa-4cd2-808a-8a6cf2b1d0a5",
      "adStorageConsent": "G",
      "userData": {
        "anonymousId": "b171a9b06ce011ecafcd1b209be8601b",
        "msclkid": "dd4afcccb1c9a4cad9544dd7e5006",
        "em": "ec81f3ac7b2b19675bab9d54cf416f9f18cff87c97da5cca82c0f0891bc40602"
      },
      "customData": {
        "transactionId": "10492",
        "value": 149.95,
        "currency": "USD"
      }
    }
  ]
}
Step 5

Restate or retract corrections

Refunds, partial cancellations, and corrected revenue should not become new conversions. Use adjustment fields against the original conversion key. Restate changes the recorded value, while Retract removes the conversion count impact. Keep the original ConversionName, ConversionTime, and MicrosoftClickId identical.

{
  "OfflineConversionAdjustments": [
    {
      "ConversionName": "Purchase",
      "ConversionTime": "2026-04-23T10:15:30Z",
      "MicrosoftClickId": "dd4afcccb1c9a4cad9544dd7e5006",
      "AdjustmentType": "Restate",
      "AdjustmentTime": "2026-04-24T09:05:00Z",
      "AdjustmentValue": 99.95,
      "AdjustmentCurrencyCode": "USD"
    }
  ]
}
Schema

Required fields

Keep these fields explicit in the TrackLayer destination mapping. Normal conversion uploads use the conversion fields, while adjustment fields are used only when correcting or retracting a conversion that Microsoft has already received.

FieldRequirement
ConversionNameThe exact Microsoft Advertising conversion goal name. A mismatch prevents the event from applying to the intended goal.
ConversionTimeUTC timestamp for the original action. It must be after the ad click and inside the goal window and import lookback.
ConversionValueRevenue or business value for the conversion. Use the final value available at the moment you send the event.
ConversionCurrencyCodeThree-letter ISO currency such as USD, EUR, or GBP. If omitted, Microsoft may fall back to the goal default.
MicrosoftClickIdThe msclkid captured from the ad landing URL. It is the primary deterministic click attribution key for offline imports.
AdjustmentTypeUse Restate to correct value or Retract to remove an existing conversion. Required only for adjustment calls.
AdjustmentValueThe corrected value for Restate adjustments. Do not send it for normal conversion uploads or Retract adjustments.
Attribution key

The msclkid parameter

msclkid is Microsoft's click identifier. When auto-tagging is enabled, Microsoft appends it to the landing URL after an ad click. TrackLayer should extract it before redirects, checkout domain changes, consent banners, or client routing strip the query string. Store the newest value in a first-party cookie or server-side visitor profile and attach it to later purchases, leads, subscriptions, calls, and qualified CRM milestones.

Use 90-day persistence and overwrite the value when a newer msclkid arrives. That window is long enough for many considered purchase cycles while keeping attribution tied to the latest Microsoft Ads click. If you also send UET CAPI events, include msclkid in userData and keep the same TrackLayer event_id in your logs so online events, offline imports, and adjustments can be reconciled.

const params = new URLSearchParams(window.location.search);
const msclkid = params.get("msclkid");

if (msclkid) {
  document.cookie =
    "msclkid=" + encodeURIComponent(msclkid) +
    "; Path=/; Max-Age=7776000; SameSite=Lax; Secure";
}
Routing

Offline vs Online conversions

Pick the endpoint from the event's business timing. Offline conversion imports are for events that become true after the click and often outside the browser. Online UET CAPI is for server-side web events that mirror or replace browser UET behavior.

TypeEndpointBest forTiming
Offline conversions/CampaignManagement/v13/OfflineConversions/ApplyCRM-qualified leads, phone sales, delayed ecommerce validation, subscriptions, and imports keyed by MicrosoftClickId.Can be batched, with original UTC conversion time preserved.
Online UET CAPI/v1/{tagID}/eventsServer-side website events, page loads, custom events, enhanced conversions, and transactionId-based online adjustments.Best sent near real time, with eventTime in epoch seconds.
Validation

Testing with Bing Ads UI

1

Confirm the goal is active

Open Tools → Conversion Tracking → Conversion goals and verify the goal name, type, revenue setting, and attribution window before sending test events.

2

Upload one controlled event

Use a known test msclkid, one conversion name, and one timestamp. Check the API response for PartialErrors and save the TrackingId with the TrackLayer event log.

3

Review diagnostics after processing

Return to Conversion Tracking after Microsoft has processed the event and compare accepted, unattributed, and duplicate counts against the source events.

Diagnostics

Troubleshooting

AuthenticationFailed

Refresh the access token, confirm the token belongs to a user with account access, and verify DeveloperToken, CustomerAccountId, and CustomerId headers are all present.

QuotaExceeded

Batch up to the allowed request size, reduce parallel workers per account, and retry with exponential backoff instead of creating new conversion records.

InvalidConversionName

Match the conversion goal name exactly and confirm the goal is active. Newly created offline goals should age for two hours before production uploads.

DuplicateMicrosoftClickId

Reuse the same TrackLayer event ID on retries and avoid sending the same MicrosoftClickId, ConversionName, and ConversionTime combination twice.

ConversionTimeTooOld

Send the original event time within the supported lookback and inside the goal attribution window. Do not use old CRM close dates as conversion times for fresh imports.

FAQ

Common questions

Is Microsoft Ads CAPI the same as offline conversions?

No. Offline conversions are a Campaign Management API import keyed mainly by MicrosoftClickId. UET CAPI is a server-side event endpoint for online page load and custom events. Many production setups use both.

Can I send conversions without msclkid?

For offline conversion imports, msclkid is the key field. For UET CAPI, hashed email, phone, anonymousId, IP, user agent, and consent fields can help, but click-level attribution is strongest when msclkid is present.

How long should TrackLayer store msclkid?

Use a 90-day first-party cookie or server-side profile field and overwrite it whenever a newer msclkid arrives. That mirrors Microsoft guidance and keeps attribution tied to the most recent ad click.

Should purchase refunds be negative conversions?

No. Use Restate to correct the conversion value or Retract to remove the conversion. Negative new conversions usually create confusing reporting and duplicate keys.

Where should consent checks run?

Run consent checks before dispatch in TrackLayer. For UET CAPI, pass adStorageConsent when you have an explicit state. For offline imports, apply your policy before retaining or sending click and customer identifiers.

Next reads

Related implementation guides

We use essential cookies to keep the site secure and functional. Analytics and third-party tags run only with your consent. See our Cookie Policy.

We use essential cookies to keep the site secure and functional. Analytics and third-party tags run only with your consent. See our Cookie Policy.