September 21, 2026 · 9 min read
Engineering

Six Bing Ads API traps you only find by running the write chain

TL;DR

Microsoft Advertising's v13 REST API is a JSON transcoding of a SOAP contract, and the seams show. These six were found by running a complete write chain on a real account — campaign, ad group, responsive search ad, keywords, negatives, tracking, read-back, delete — not by reading documentation, which is precisely the point.

Why documentation was not enough

Every one of these passed a review of the reference docs. Several are cases where the documentation is correct about SOAP and the REST surface behaves differently; the rest are defaults that look sensible and fail on an ordinary account.

The chain that found them: create a campaign, an ad group, a responsive search ad, keywords and negative keywords; set a tracking template, final URL suffix and UTM parameters at three levels; read everything back; delete it. Created paused, named TEST, cleanup verified.

1. A prefix is not a name

Microsoft Advertising splits across service hosts — Campaign Management, Ad Insight, Customer Management. Inferring which one a resource belongs to by prefix-matching its name is the obvious shortcut, and it is wrong in a way that is nearly invisible.

Keywords/QueryByAdGroupId is a core Campaign Management read. Matched against a prefix list containing Keyword, it was routed to the Ad Insight host, where it is a bare HTTP 404 with no explanation. BidStrategies/QueryByIds went the same way via Bid. One missing word boundary broke every keyword read in the product.

How it was found is worth copying: a probe and the tool hit the same URL with different outcomes — 400 versus 404. The first hypothesis (a missing body field) was tested with four body shapes against the same bad id and all four returned 400, refuting it. That refutation is what pointed at the only remaining difference: the probe named the service explicitly and the tool inferred it.

2. Space-separated flags are a SOAP convention

The documentation says flag fields are space-separated. That is true of SOAP. The REST surface parses .NET enums and needs commas — and the error, when you get one, points at Path: $.Field, a System.Text.Json path, which is the clue that you are in a JSON deserializer rather than a SOAP one.

Four fields are affected. The symptom is the worst possible kind: not an error, but a connect that returns zero accounts. Nothing is obviously broken; there is simply nothing there.

The general rule this earns: when an API's REST surface is a transcoding of an older contract, the documentation's conventions may describe the ancestor. The deserializer's error path tells you which one you are actually talking to.

3–4. Two defaults that fail on an ordinary account

  • Error 2034, InvalidTimePeriodColumnForSummaryReport. Every default column set begins with TimePeriod, which is invalid for Summary aggregation. So the most obvious request anyone makes — one row per campaign, no time breakdown — is the one that always failed. The fix is to drop the column as a pre-flight and say so, rather than passing the refusal along.
  • Error 5359, InStoreTransactionPilotNotEnabledForCustomer. A default that asks for every conversion-goal type fails the entire query on an account that is not in a particular pilot. An exhaustive default is not a safe default — it fails on the median account rather than the unusual one.

5–6. Two shapes that are not what they look like

  • Responsive search ad headlines are not { Text }. They are AssetLink arrays wrapping a TextAsset. Errors 6206 and 6207 are what the obvious shape earns you, and the error names the field rather than the structure.
  • The negative-keyword write route is not the read route. POST NegativeKeywords returns 404; writes go to EntityNegativeKeywords. There is no hint of this in the 404 — it was settled by probing eight candidate routes until one answered "entities are required", which is what a correct route looks like when the body is empty.
And a seventh for anyone wiring tracking: error 4615 means a tracking template requires a final URL on the SAME object. If the ad has none, set the template at ad-group or campaign level instead.

Two credential traps before you get that far

  • The Entra Secret ID and the Secret VALUE are both GUIDs. Copying the wrong one gives an auth failure that never mentions which field is wrong.
  • The refresh token rotates on every use and expires after 90 days idle. An integration that sits unused through a quiet quarter comes back disconnected — Microsoft's design, not a bug, and worth knowing before you debug it as one.

What this is worth if you are not writing a client

Most people reading this want Bing Ads connected to an agent rather than to implement the API. The reason to publish the traps anyway is that they explain what "supported" has to mean: a platform is not integrated because a client exists, it is integrated when the write chain has actually been run end to end on a real account and the failures have been converted into pre-flight refusals that name the fix.

Four of these six produce errors that point at the wrong thing. That gap — between what the API says and what is actually wrong — is where most of the work in a platform integration lives.

Setting Bing Ads up from Claude or Codex? The Microsoft Advertising MCP server guide has the configuration.

Frequently asked questions

Why does my Bing Ads API connect return zero accounts?
Most often the flags field. Microsoft's documentation describes space-separated values, which is a SOAP convention; the REST surface parses .NET enums and needs commas. The symptom is an empty account list rather than an error, which is why it hides.
What causes Bing Ads error 2034?
A Summary-aggregation report whose column set begins with TimePeriod. Every default column set does, so the most natural one-row-per-campaign request is the one that fails. Drop the time column before requesting a summary.
What causes Bing Ads error 5359?
Asking for a conversion-goal type your account is not piloted for — InStoreTransaction, typically. One unavailable type fails the whole query, so an exhaustive default breaks on ordinary accounts.
Why does POST NegativeKeywords return 404 in Bing Ads v13?
Because that route is read-only. Negative keyword writes go to EntityNegativeKeywords. The 404 gives no hint, which is why it takes probing to find.
What are Bing Ads errors 6206 and 6207?
A responsive search ad's Headlines and Descriptions submitted as bare { Text } objects. They are AssetLink arrays wrapping a TextAsset.
Do I need a developer token for the Bing Ads API?
Yes — three credentials in total: an Entra application, a Microsoft Advertising developer token, and the OAuth grant. The developer token is the step most people stall on.
Run your ad ops with an agent you can trust

Start free — 2,500 credits a month, no credit card. Every write waits for your approval.

Keep reading