PUT /v1/ads/{adId} with targeting.customLocations returns400:
▎ "Google does not support updating customLocations after creation; editable fields are devices, locations (or the equivalent top-level countries/regions/cities/zips/metros), languages, keywords, and negativeKeywords."
That matches your docs, so it is intended. The problem is the fit with the original request. Our customers arelocal service businesses — a plumber, a painter, a window fitter. Their service area is a town plus a radius, not a list of
cities, so they are created with customLocations. "Region is the single most common thing a local business wants to change" was the reason for the request, andfor exactly those campaigns nothing changed: the only way to correct a service
area is still todelete the campaign and rebuild it, losing its history.
Ask: support replacing customLocations on an existing campaign, with the same full-replacement semantics as the other location kinds.
Shipped and verified live. PUT /v1/ads/{adId} now accepts targeting.customLocations, so a service area can be corrected without rebuilding the campaign.
The important design decision, given your use case: places and radius are two independent sets. Sending customLocations replaces every radius and leaves the cities and countries alone; sending places replaces those and leaves the radius alone. We considered treating all geo as one set, which is the simpler reading of "full replacement", and rejected it precisely because it would mean a city correction silently shrinking a plumber's service area, which is the failure this request is about.
Send customLocations: [] to drop radius targeting entirely. Each entry needs latitude, longitude, radius and distanceUnit (mile or kilometer); a missing or out-of-range value is a 400 naming the field rather than an opaque Google error.
One property worth relying on: a circle you re-send unchanged keeps its criterion id and history instead of being removed and recreated. Google has no constant to key a radius on, so we diff on the circle itself (point, radius, units). Verified against Google: re-sending an identical circle issues no write at all, changing the radius replaces just that circle, and the campaign's city and country criteria survive every radius edit untouched.
Thanks for pushing on this after the earlier location work. You were right that closing that request left the exact shape your customers are created with still unfixed.
Log in to comment and vote
Comments1
Miquel Palet López
Sep 15
Shipped and verified live.
PUT /v1/ads/{adId}now acceptstargeting.customLocations, so a service area can be corrected without rebuilding the campaign.The important design decision, given your use case: places and radius are two independent sets. Sending
customLocationsreplaces every radius and leaves the cities and countries alone; sending places replaces those and leaves the radius alone. We considered treating all geo as one set, which is the simpler reading of "full replacement", and rejected it precisely because it would mean a city correction silently shrinking a plumber's service area, which is the failure this request is about.Send
customLocations: []to drop radius targeting entirely. Each entry needslatitude,longitude,radiusanddistanceUnit(mileorkilometer); a missing or out-of-range value is a 400 naming the field rather than an opaque Google error.One property worth relying on: a circle you re-send unchanged keeps its criterion id and history instead of being removed and recreated. Google has no constant to key a radius on, so we diff on the circle itself (point, radius, units). Verified against Google: re-sending an identical circle issues no write at all, changing the radius replaces just that circle, and the campaign's city and country criteria survive every radius edit untouched.
Thanks for pushing on this after the earlier location work. You were right that closing that request left the exact shape your customers are created with still unfixed.