Marketing6 min read

Merchant API in Google Ads Scripts: Apr 22 Migration

Google Ads Scripts gain Merchant API support April 22, 2026. Content API sunsets August 18. Script-by-script port guide with before/after code diffs.

Digital Applied Team
April 18, 2026
6 min read
Apr 22

Rollout Date

Aug 18

Sunset Date

~4 mo

Migration Window

10+

Sub-APIs

Key Takeaways

Two Dates, Four Months: Merchant API lands in Ads Scripts April 22, 2026. Content API for Shopping sunsets August 18, 2026. That is the full migration window for every Shopping script you own.
Resource Names Replace IDs: The biggest semantic change: products, inventories, and accounts are now referenced by resource-name strings like accounts/123/products/en~US~SKU42 — not numeric IDs.
Prices Are Now Micros: Every price field switches to amountMicros (int64) + currencyCode (string). Any script doing numeric math on legacy price floats will silently produce wrong totals unless migrated.
Migrate Products First: Google's own priority order is Accounts → Products → Data Sources → Reports. Port in that sequence so dependencies line up and you can unblock the highest-volume reporting scripts fastest.
Shadow Mode Is Non-Negotiable: Run the old Content API script and the new Merchant API script in parallel for at least two reporting cycles. Promote only after zero schema drifts across both.

On April 9, 2026 the Google Ads Developer Blog announced that the Merchant API will be available in Google Ads Scripts starting April 22, 2026, shipped as an Advanced API. In the same announcement Google confirmed the hard sunset of the Content API for Shopping on August 18, 2026. That gives every agency running Shopping scripts approximately four months to rewrite every feed, inventory, promotions, and reviews script they own.

This post is the script-by-script port guide. It covers the semantic changes you will hit (resource names, micros, URL format), the sub-API priority order Google itself recommends, before-and-after Apps Script diffs for the four most common script shapes, the shadow-mode validation recipe, and a 90-day rollout calendar calibrated for a typical agency portfolio. If you want the broader strategic context on programmatic Google Ads in 2026, pair this with the Google Ads API v23.1 + April 2026 core update playbook.

Two Dates That Matter

April 22, 2026 — Rollout
Merchant API becomes available in Ads Scripts

Ships as an Advanced API in the Google Ads Scripts editor. Requires linking the script project to a Google Cloud project and registering that project with your Merchant Center account. After enablement, the new service is importable alongside (not instead of) the existing Content API.

August 18, 2026 — Sunset
Content API for Shopping stops working

Hard retirement. Any Ads Script — or any other integration — still calling Content API endpoints after this date will fail. No grace period. Target end-of-July for completed migrations so you have a two-week buffer for silent regressions.

What's Actually Changing

The Merchant API is not a version bump of the Content API. It is a different surface with a different architecture. Three semantic changes matter most:

ChangeContent APIMerchant API
URL formatshoppingcontent/v2.1/{merchantId}/productsmerchantapi.googleapis.com/products/v1beta/accounts/{account}/products
Resource identifierNumeric IDResource name string (accounts/X/products/Y)
Price fieldprice.value (float), price.currencyprice.amountMicros (int64), price.currencyCode
ArchitectureMonolithicModular sub-APIs (Products, Inventories, Promotions, ...)
NotificationsPoll-basedPush via Notifications API

Sub-API Migration Priority

Google explicitly calls out four sub-APIs as the priority migration targets: Accounts, Products, Data Sources, and Reports. The ranking below extends that to the rest of the Merchant API surface, ordered by typical agency script impact.

PrioritySub-APITypical agency script uses
1AccountsMulti-client account listing, sub-account spawning
2ProductsFeed uploads, SKU sync, attribute overrides
3Data SourcesSupplemental feeds, primary feed rotation
4ReportsPerformance pulls for dashboards and alerts
5Inventories (local & regional)Stock level sync, in-store availability
6PromotionsSale and coupon rollouts
7Reviews (product & merchant)Review feed imports
8NotificationsReplace polling with push subscriptions
9Shipping SettingsRegional shipping overrides
10Conversion SourcesConversion tracking wiring

Enabling Merchant API in Ads Scripts

Three-step enablement, done once per script project:

  1. Link the script project to a Google Cloud project. In the Ads Scripts editor: Project Settings → Google Cloud Platform project → set the project ID. The project needs the Merchant API enabled under APIs & Services.
  2. Register the Cloud project with Merchant Center. In Merchant Center: Developer settings → register your Cloud project ID. This is the step that actually grants the script permission to call Merchant API on behalf of the merchant account.
  3. Enable the Merchant API Advanced Service in the Ads Scripts editor. Resources → Advanced Google services → toggle on the Merchant API service(s) you need (Products, Inventories, Promotions, etc.). Each sub-API is a separate toggle.

Product Script: Before and After

The most common Shopping script pattern is a daily product fetch to feed a reporting sheet. Here is the full before/after for a hypothetical low-stock alerter.

Content API (legacy)

function lowStockAlert_contentApi() {
  const merchantId = '123456789';
  const products = ShoppingContent.Products.list(merchantId).resources || [];

  const alerts = [];
  for (const p of products) {
    if (p.availability === 'out_of_stock') {
      alerts.push({
        id: p.id,                             // numeric ID
        title: p.title,
        price: parseFloat(p.price.value),     // price is a float string
        currency: p.price.currency,
      });
    }
  }

  Logger.log(`Found ${alerts.length} out-of-stock items.`);
}

Merchant API (new)

function lowStockAlert_merchantApi() {
  const parent = 'accounts/123456789';
  const res = MerchantApiProducts.Accounts.Products.list(parent);
  const products = res.products || [];

  const alerts = [];
  for (const p of products) {
    if (p.productStatus?.destinationStatuses?.some(
      ds => ds.approvalStatus === 'disapproved' ||
            p.availability === 'OUT_OF_STOCK'
    )) {
      alerts.push({
        name: p.name,                                 // resource name
        title: p.attributes?.title,
        priceDollars: Number(p.price.amountMicros) / 1_000_000,  // micros → dollars
        currency: p.price.currencyCode,
      });
    }
  }

  Logger.log(`Found ${alerts.length} out-of-stock items.`);
}

Five things changed: the service namespace, the identifier format (parent is now a resource name), the product shape (many old top-level fields moved into p.attributes), the price arithmetic (divide micros by 1,000,000), and the status enum casing (OUT_OF_STOCK not out_of_stock).

Inventory and Promotions Diffs

Regional inventory update

Content API: Inventory.set with merchant ID, product ID, and region. Merchant API: LocalInventories sub-resource on a product, keyed by store code.

// Content API → Merchant API
// OLD: ShoppingContent.Inventory.set(resource, merchantId, productId)
// NEW:
const name = `accounts/${account}/products/${productId}/localInventories/${storeCode}`;
MerchantApiInventories.Accounts.Products.LocalInventories.insert(
  {
    storeCode: storeCode,
    availability: 'IN_STOCK',
    price: { amountMicros: 4999000000, currencyCode: 'USD' },
    quantity: 42,
  },
  `accounts/${account}/products/${productId}`
);

Promotion insert

// Content API's promotions are now Merchant API's Promotions sub-API.
MerchantApiPromotions.Accounts.Promotions.insert(
  {
    promotionId: 'SPRING26',
    contentLanguage: 'en',
    targetCountry: 'US',
    redemptionChannel: ['ONLINE'],
    couponValueType: 'PERCENT_OFF',
    percentOff: 20,
    promotionDisplayDates: { ... },
  },
  'accounts/123456789'
);

The Shadow-Mode Validation Pattern

Never cut over cold. The reliable pattern: run the old script and the new script side-by-side against the same account for two full reporting cycles, write both outputs to a shared sheet, and diff. Promote only after zero unexplained drift.

function shadowMode() {
  const legacyRows = lowStockAlert_contentApi_returnRows();
  const newRows    = lowStockAlert_merchantApi_returnRows();

  const sheet = SpreadsheetApp.openById('SHEET_ID').getSheetByName('ShadowDiff');
  sheet.appendRow([
    new Date(),
    legacyRows.length,
    newRows.length,
    legacyRows.length - newRows.length,
  ]);

  // Alert if |diff| > 2 across a full day
  const threshold = 2;
  if (Math.abs(legacyRows.length - newRows.length) > threshold) {
    MailApp.sendEmail('alerts@agency.com', 'Shadow diff exceeded',
      `Legacy: ${legacyRows.length}, New: ${newRows.length}`);
  }
}

The 90-Day Rollout Calendar

WindowWork
Apr 22 – May 6Enable Merchant API in one sandbox Ads Scripts project. Port the lowest-risk Accounts + Products script.
May 7 – Jun 7Run both scripts in shadow mode. Compare daily. Promote after 14 days of zero drift.
Jun 8 – Jul 15Port Data Sources, Reports, Inventories, Promotions in that order. Budget a week per script.
Jul 16 – Jul 31Reviews, Notifications, Shipping, Conversion Sources. Stop all new Content API writes by July 31.
Aug 1 – Aug 17Contingency buffer. Hunt silent regressions. August 18 the Content API is gone.

Common Pitfalls and Fixes

PitfallFix
Prices off by 6 orders of magnitudeApply / 1_000_000 to every amountMicros before formatting or math.
INVALID_ARGUMENT on product nameResource name must be accounts/{account}/products/{product} — plain IDs fail.
Advanced service not callableEnable the sub-API in Resources → Advanced services; also enable it in the GCP console.
PERMISSION_DENIEDRegister the GCP project with Merchant Center Developer settings.
Enum casing mismatch (out_of_stock vs OUT_OF_STOCK)Merchant API uses UPPER_SNAKE_CASE for every enum. Update comparisons.
Attribute lookup failsMost former top-level product fields are now inside p.attributes. Rewrite property access.

Portfolio-Scale Migration Checklist

For agencies with 20+ client accounts on Shopping, these are the moves that keep the migration from spiraling:

  • Inventory all Shopping scripts across the portfolio. Build the list before April 22 — if you find it on August 10 you are too late.
  • Group by script template. Most agencies run 5-10 canonical script shapes copied across clients. Port once, reuse across accounts.
  • Centralize the migration helper. Write one shared Apps Script library with the price-conversion and resource-name helpers; include it in every migrated script.
  • Automate the comparison sheet.One sheet per client, same shadow-mode diff formula, auto-email on delta > 2.
  • Communicate rollout windows to clients so a week of shadow-mode weirdness doesn't generate escalations.

Conclusion

The Merchant API is a better surface than the Content API. Modular sub-APIs, push notifications, resource-name consistency with the rest of Google Ads API — all genuine improvements. But the migration is real work, and silent failures after August 18, 2026 will cost agencies orders of magnitude more than the port itself. The agencies we see doing it well started in late April. The calendar above is the fastest safe path.

Ship the Merchant API Migration on Schedule

We port Shopping scripts across agency portfolios — from the first sandbox enablement to the August 17 cutover — with shadow-mode validation on every script.

Free consultation
Expert guidance
Tailored solutions

Frequently Asked Questions

Related Guides

More on programmatic Google Ads, Merchant Center, and Shopping automation.