Found in AI answers?Hire Theory Road
Theory Road.

Microsoft Ads API Settings Not Saving? Six Causes, In Order.

The Microsoft Advertising API will tell you a write succeeded when part of it did not. Here is the order we check things when a setting does not stick, from SOAP serialization to bid strategy rules to the account flags only the web interface shows.

By October 18, 202610 min read

When a Microsoft Advertising API call returns success but the setting does not stick, the cause is almost always one of six things: SOAP elements sent out of the order the WSDL defines, so an optional field is ignored; a field the service accepts but does not apply, which you only catch by reading the entity back; keyword or ad group bids sent to a campaign on an automated bid strategy, which Microsoft ignores; a bid strategy that needs a conversion goal (with revenue, for Maximize Conversion Value) the account does not have; partial errors inside a response you treated as a clean success; or an account level issue that shows in the web interface and not in the API. Fix it by serializing in WSDL order, checking PartialErrors on every write, and reading back every entity you change.

The Microsoft Advertising API (still called the Bing Ads API, now on version 13) is a set of web services, Campaign Management, Bulk, Reporting, Customer Management and Ad Insight, that you call with SOAP or REST. A write such as UpdateCampaigns, AddAdExtensions or AddConversionGoals sends a list of entities and gets back a list of IDs plus a PartialErrors array. A successful HTTP response only means the request was processed; it does not mean every entity, or every field, was saved. We build and manage Microsoft Ads accounts through this API, and every item below is something we hit and then checked against Microsoft's documentation.

The six causes we find most often.

  • SOAP element order: Microsoft documents that optional elements out of WSDL order may be ignored, so a field can vanish without an error
  • Fields accepted but not applied: a value inside the documented range succeeds and reads back different
  • Bids sent to an automated campaign: under automated strategies Microsoft ignores ad group and keyword bids, so the update succeeds and changes nothing
  • Bid strategy without a qualifying conversion goal: Maximize Conversion Value refuses to save without a UET tag and a revenue tracking goal
  • Partial errors ignored: batch writes succeed for some entities and fail for others, and the failures sit in PartialErrors, not in a fault
  • Account issues the API does not show: in our accounts we have seen a policy flag in the web interface that never surfaced through the API

Does SOAP element order matter in the Microsoft Ads API?

Yes. Microsoft documents that SOAP elements must be in the same order as the WSDL; required elements out of order fail the call, and optional elements out of order may fail the call or be ignored. That second half is the trap: no error, so your code thinks the field saved. If business logic requires that element, the service then reports it as missing, which looks like a validation bug and is a serialization bug.

We ran into this building sitelink extensions by hand. The order has two layers. Inherited elements from the base AdExtension object come first (DevicePreference, ForwardCompatibilityMap, Id, Scheduling, Status, Type, Version), then the SitelinkAdExtension elements in their own sequence: Description1, Description2, DestinationUrl, DisplayText, FinalAppUrls, FinalMobileUrls, FinalUrlSuffix, FinalUrls, TrackingUrlTemplate, UrlCustomParameters. Note that FinalUrlSuffix comes before FinalUrls in the schema, even though the reference table lists them the other way. Put FinalUrls ahead of DisplayText and the service can drop it, then tell you FinalUrls is required. Copy the order from the Syntax block on each data object page, not from the table.

The official SDKs serialize in the right order. This mostly hits hand built XML and generic SOAP clients. The same discipline applies to offline conversion uploads, covered in our CRM offline conversions guide.

Why does a Microsoft Ads conversion goal save with a different value than I sent?

Microsoft documents ConversionWindowInMinutes as accepting 1 to 129600 minutes (90 days), but a value that is accepted is not always a value that is applied, so read the goal back after every write. On one of our own accounts, AddConversionGoals took a 90 day window, returned the new goal ID with no partial error, and the goal read back at 30 days. Microsoft does not document that behavior. It fits an optional element being dropped, but we treat the cause as unconfirmed and the read back as mandatory.

Two more documented behaviors cause the same symptom. On UpdateConversionGoals, a nil or empty Revenue element leaves revenue untouched, but any non empty Revenue element replaces all existing revenue properties, so sending only a currency can wipe the value type. And ad extensions do not support partial update: Microsoft says any optional element you leave out of an update is in effect deleted. Send the full sitelink every time, or you will clear its descriptions while changing its URL. Our piece on primary versus biddable conversion goals covers how goal settings change what bidding optimizes toward.

Why do keyword bid updates succeed but change nothing?

When a campaign uses an automated bid strategy, Microsoft ignores ad group and keyword bids, so UpdateKeywords and UpdateAdGroups return success while delivery stays the same. Microsoft's bid strategy guide says that with some bid strategy types your bid and ad rotation settings are ignored. Separately, since April 2021 you cannot set a bid strategy on an ad group or keyword at all: the request is ignored without error and the entity inherits the campaign's strategy. Manual CPC on an unsupported campaign type is also ignored without error and set to Enhanced CPC.

The fix is to change the campaign's BiddingScheme first (Enhanced CPC or Manual CPC where supported, or Maximize Clicks with a MaxCpc cap), then set keyword bids. Our article on a new Microsoft Ads account that is not spending covers the most common place this bites: an imported campaign on Maximize Conversions with no conversion history.

Why will Maximize Conversion Value not save through the API?

Maximize Conversion Value needs a UET tag and a conversion goal that tracks revenue; without them the campaign update fails with a bid scheme error. Microsoft's error code list includes CustomerHasNoUETForMaxConversionValueBiddingScheme (1166), AccountHasNoRevenueConversionGoalForMaxConversionValueBiddingScheme (1167) and ConversionGoalCriteriaNotMetForBiddingScheme (4733, "There must be a conversion goal set up to use this bid strategy"). We hit 4733 trying to move a campaign whose only goals were count based leads with no revenue value. Adding a goal with a fixed or variable Revenue value, attached to the account's UET tag, cleared it.

Target ROAS has a stricter documented bar. Error 4728 says there must be at least 15 conversions in the last 30 days, and error 4729 says revenue tracking must be set up with revenue greater than zero in the last 30 days. Maximize Conversions and Target CPA need a UET tag and a conversion goal, and Microsoft says both stop optimizing bids when a campaign falls below 30 conversions in any 30 day period.

How to verify what actually saved.

Three checks, in this order.

Capture the raw request and response. Every official SDK can log the SOAP envelope (TraceBehavior in .NET, the suds logger in Python, __getLastRequest in PHP). Compare your request against the Request SOAP template on the operation's reference page, element by element. Keep the TrackingId from the response header; support asks for it.

Read the entity back. After UpdateCampaigns call GetCampaignsByIds, after AddConversionGoals call GetConversionGoalsByIds (up to 100 IDs per call, with ConversionGoalTypes set), after AddAdExtensions call GetAdExtensionsByIds. Diff every field. Some goal fields, such as AttributionModelType, only come back if you request them in ReturnAdditionalFields.

Open the web interface. Check the conversion goal settings and read account notifications. This is the only check that catches flags the API does not expose.

Diagnose top to bottom.

This is the order we run. Each step stops at one layer.

Check for a fault first.
A SOAP fault (HTTP 500 with AdApiFaultDetail, ApiFaultDetail or EditorialApiFaultDetail) means nothing in the call was applied. Look the error code up before changing code.
Read PartialErrors on every write.
Iterate the PartialErrors array. Each BatchError carries an Index pointing at the failed entity in your request, plus Code, ErrorCode and FieldPath. A null ID at that index in the returned ID list confirms the entity was not saved.
Diff the request against the WSDL order.
Log the outgoing XML and compare it to the Syntax block of each data object, base class elements first, then derived elements in their sequence.
Read every changed entity back.
Call the matching Get operation and compare field by field. A difference with no partial error is an ignored element or undocumented behavior.
Check the campaign bid strategy.
If the change was a bid, read the campaign BiddingScheme. Automated means bids are ignored.
Check conversion goal prerequisites.
For bid strategy errors, confirm the UET tag is active and a goal exists with the type the strategy needs, with Revenue set for Maximize Conversion Value and Target ROAS. Our conversion tracking audit checklist covers the tag side.
Open the web interface.
Read account notifications, policy flags and campaign status.
Microsoft Ads API settings not saving: symptoms, likely causes and fixes
SymptomLikely causeFix
Call succeeds, field is blank on read backOptional SOAP element out of WSDL order, ignoredSerialize in the Syntax block order, base class elements first
Error says a field is missing that you sentElement dropped for order, then validated as absentMove the element into sequence (for sitelinks, FinalUrls after FinalUrlSuffix)
Conversion goal reads back with a different windowField accepted but not appliedRead back with GetConversionGoalsByIds, then UpdateConversionGoals and verify again
Sitelink loses its descriptions after a URL editAd extensions do not support partial updateSend the full extension on every update
Keyword bid update succeeds, CPCs unchangedCampaign on an automated bid strategyChange campaign BiddingScheme first, then set bids
Error 4733 or 1167 on bid strategy changeNo conversion goal, or no goal with revenueCreate a UET based goal with a Revenue value, then retry
Some entities in a batch missingPartialErrors ignored in a successful responseCheck PartialErrors and null IDs on every write
Script says healthy, account not servingFlag visible only in the web interfaceRead notifications in the UI before trusting API status

What is normal and what is a red flag?

As of October 2026, Microsoft documents that the Campaign Management service throttles per user per minute and returns error 117 (CallRateExceeded), after which you can resubmit once you wait 60 seconds. That is normal under load and is not a save failure. Ads and keywords pending editorial review are normal too, and Microsoft says budget changes generally take effect within an hour or so.

Red flags are different. A field that reads back with a value you did not send. A PartialErrors entry you did not log. A bid change on a campaign whose BiddingScheme is anything other than Manual or Enhanced CPC. A restriction in the web interface that no API call reports. Each means the automation and the account have drifted apart. For the Google side of API syncs, see Google Ads API RESOURCE_EXHAUSTED errors covers the quota side there.

Key terms.

PartialErrors: the array of BatchError objects a write returns, one per failed entity, each with an Index into your request. WSDL sequence: the fixed element order SOAP requests must follow. Read back: a Get call after a write to confirm the stored value.

Why is my Microsoft Ads API update returning success but not saving?

Check PartialErrors first, then read the entity back. If the value still differs with no partial error, suspect a SOAP element out of WSDL order. If it was a bid, check for an automated bid strategy.

What is the maximum conversion window in the Microsoft Ads API?

Microsoft documents ConversionWindowInMinutes as 1 to 129600 minutes, which is 90 days. The view through window maxes out at 43200 minutes, which is 30 days. Always read the goal back after creating it, because in our accounts a 90 day value was accepted and the goal came back at 30 days.

What does ConversionGoalCriteriaNotMetForBiddingScheme mean?

It is error 4733, and Microsoft's description is that a conversion goal must be set up to use the bid strategy. For Maximize Conversion Value you also need a goal that tracks revenue (error 1167 if missing) and a UET tag (error 1166). Create the goal, then retry.

Does element order matter if I use the Bing Ads SDK?

Usually not, since the official SDKs serialize in WSDL order. It matters when you build SOAP by hand or generate XML from a dictionary whose key order you do not control.

Why do sitelink fields disappear when I update one value?

Microsoft documents that ad extensions do not support partial update, so any optional element left out of the update request is in effect deleted. Send the complete extension, including both descriptions, every time you update it.

Work with us

Let’s talk about what’s next.

A short note on where the business is and where it needs to go. A senior partner replies within one business day.

t@theoryroad.com

Step 1 of 2

How can we help you get found?

What do you need help with?

Next: name, email and budget. That’s it.