Most Indian D2C brands set up Meta Catalog once, tick the "Dynamic Ads" checkbox, and never look at the feed again. That is the single biggest reason DPA campaigns underperform here compared to how they're supposed to work. The ad format is not the problem — Meta's dynamic retargeting engine is genuinely good. The problem is that the product feed feeding it was built by whoever set up the Shopify or WooCommerce store, usually without any thought for how Meta actually uses each field, and definitely without any India-specific handling for COD availability, GST-inclusive pricing or regional size/variant labels.
We've rebuilt or audited catalog feeds for enough Indian D2C accounts now to see the pattern clearly: brands with clean, India-aware catalogs see Dynamic Product Ads outperform static retargeting by a wide margin on ROAS, while brands running a copy-pasted default feed often see DPA underperform their static creative — which is the opposite of what should happen. This guide covers how to set the catalog up correctly the first time, the fields that matter specifically for Indian stores, and the retargeting structure that gets the most out of it.
What Meta Catalog and Dynamic Product Ads Actually Do
Meta Catalog is a structured feed of every product you sell — SKU, title, price, availability, image, category — that lives in Meta's Commerce Manager. Dynamic Product Ads (DPA) is the ad format that reads from that catalog and automatically assembles ad creative per user, per product, based on what they viewed, added to cart, or purchased on your site (via the Meta Pixel or Conversions API).
The mechanism is simple but powerful: a shopper looks at a kurta set on your site, doesn't buy, and later scrolls Instagram. Meta pulls that exact kurta set — correct image, correct price, correct "in stock" status — from your catalog and shows it to her as an ad, sometimes alongside 2-3 similar items it thinks she'll also like. No creative team touched that ad. It was assembled from your feed at serve time.
This is why catalog quality is the entire game. A static image ad is fixed the moment you upload it. A DPA is regenerated fresh every time it serves — which means every error in your feed (wrong price, out-of-stock item still showing "buy now", missing GST-inclusive pricing) becomes a live ad shown to a real shopper, potentially thousands of times a day, with nobody reviewing it before it goes out.
Building the Catalog: Fields That Matter for Indian Stores
The core Meta Catalog feed spec (CSV, XML/RSS, or Google Sheets) has around 30 possible fields. Most tutorials cover the 10 required ones and stop. For an Indian store, six additional fields make the difference between a catalog that performs and one that quietly loses money.
Required baseline fields
- id — unique SKU identifier, must exactly match what your Pixel/CAPI sends as
content_idsin ViewContent and Purchase events. This is the single most common mismatch we find — Shopify variant IDs in the feed not matching the product IDs the pixel fires, which silently breaks retargeting for that SKU. - title, description, availability, condition, price, link, image_link, brand — standard fields, but price deserves its own note below.
India-specific fields to add
- price with GST clarity. Meta's price field expects the final, tax-inclusive price the customer actually pays — the same number shown at checkout. If your backend stores a pre-GST base price and your storefront displays MRP inclusive of GST, feed the storefront number, not the backend number. Mismatched pricing between the ad and the checkout page is one of the fastest ways to spike your Meta ad account's disapproval rate and tank Quality Ranking.
- custom_label_0 through custom_label_4. Use these to tag COD-eligible vs prepaid-only SKUs, regional size charts (India sizing differs from US/EU on apparel), festival-relevant categories, and margin tier. These labels become the filters you build product sets on — this is not optional metadata, it is the backbone of your retargeting segmentation.
- size and size_type. If you sell apparel, use India-standard sizing labels (S/M/L/XL or numeric like 30/32/34) consistently across the feed and your site. A mismatch here causes "select a size" errors on tap-through, which kills conversion rate even when the ad itself performed well.
- shipping (COD note). Meta's shipping field is really built for prepaid/flat-rate logistics, and it has no native concept of Cash on Delivery. Since COD is still a meaningful share of orders for many Indian D2C categories, put the COD availability signal in a custom label instead and reflect it prominently in your ad copy or overlay — shoppers checking "COD available?" before tapping through is a real, India-specific purchase hesitation you want to pre-empt in the creative, not just on the PDP.
- inventory sync frequency. Indian D2C brands running flash sales or festival drops move inventory fast. If your feed only syncs once every 24 hours (a common default on budget Shopify apps), you will run ads for SKUs that sold out eight hours ago. Push for at least a 4-hour sync, and hourly during festival or sale windows.
- Feed error rate (items rejected by Meta): should be under 2% — above 5% and Meta throttles delivery for the whole catalog, not just the broken items
- Price-mismatch disapprovals: target zero — even a handful trigger manual review delays on new product launches
- Catalog sync interval: 4 hours minimum, hourly during sale/festival windows
- Content ID match rate (feed ID vs pixel content_ids): should be 98%+ — below that, DPA retargeting silently skips the unmatched SKUs
- Image resolution: minimum 500x500px, but 1024x1024px square crops perform noticeably better in Advantage+ catalog ads because Meta upscales smaller images and it shows in the served creative
Connecting the Feed: Shopify, WooCommerce and Manual Options
Shopify
Shopify's native Facebook & Instagram sales channel auto-generates a product feed and keeps it synced in near real-time, which solves the sync-frequency problem out of the box. The gap is the India-specific fields — Shopify's default feed does not populate custom labels for COD or margin tier. You'll need to either use metafields mapped into custom_label_0-4 via the channel's field-mapping settings, or maintain a supplementary feed layer (a Google Sheet feed merged via Catalog's multiple data source option) that overlays these India fields on top of the auto-generated one.
WooCommerce
WooCommerce needs a feed-generation plugin (Meta for WooCommerce, or a dedicated feed plugin like CTX Feed) since there's no native catalog sync. This is actually an advantage for India-specific fields — most WooCommerce feed plugins let you map any custom product attribute directly into Meta's custom_label fields without extra tooling, so COD eligibility and regional variant flags that already live as WooCommerce product attributes flow straight through.
Manual / spreadsheet feed
For smaller catalogs (under 200 SKUs) or brands on a custom-built storefront, a Google Sheet feed refreshed via Commerce Manager's scheduled fetch is genuinely fine — Meta doesn't penalise manual feeds versus auto-generated ones. The discipline required is making sure someone actually updates it when SKUs go out of stock or prices change, which is exactly the kind of manual step that gets forgotten during a sale. If you're managing multiple product feeds across Meta and Google Shopping simultaneously, this is where AdsSarthi's unified campaign dashboard earns its keep — catalog health, sync status and disapproval alerts across both platforms in one place instead of two separate Commerce Manager tabs you have to remember to check.
Structuring Dynamic Product Ad Campaigns
Once the catalog is clean, the campaign structure itself is where most of the ROAS gain actually gets captured. A single "Dynamic Ads — All Products" campaign catching every funnel stage in one ad set is the most common mistake we see after feed quality issues. Split by funnel intent instead:
- Viewed but not added to cart (Broad Retargeting, 14-day window). Widest reach, lowest intent. Use standard product-card creative, no urgency messaging.
- Added to cart but not purchased (Cart Abandonment, 3-7 day window). Highest-intent retargeting audience for most D2C brands. This is where a discount overlay or "still interested?" framing earns its keep — but test it, because in our data a blanket discount on this audience sometimes just trains repeat shoppers to always wait for the retarget ad before buying.
- Purchased — cross-sell (Post-Purchase, 30-90 day window). Use product sets filtered by category to show complementary items, not the same SKU they already bought. This is where custom_label category tagging pays for itself.
- Advantage+ Catalog Ads (broad, prospecting). Meta's automated version that finds new shoppers likely to convert based on catalog-wide performance signals, without you defining an audience manually. Worth testing as a fourth ad set once the retargeting tiers above are stable — it needs catalog-level purchase volume to learn from, so it underperforms on very small or brand-new catalogs.
Each of these should be a separate ad set with its own budget, not one ad set with an "all events" retargeting rule — combining them means Meta's delivery algorithm optimises toward whichever audience converts easiest (usually cart-abandoners), starving the broader prospecting layer of spend even when it's the one you need to scale.
Common Mistakes That Quietly Cost Budget
- Feed price ≠ checkout price. Covered above, but worth repeating because it's the highest-frequency error we find — usually caused by a separate "sale price" logic on the storefront that never gets reflected back into the feed.
- Out-of-stock SKUs still marked "in stock." This directly damages trust — a shopper taps a DPA, lands on a sold-out product page, and that session is not just a lost conversion, it's a shopper less likely to click your next ad. Automate availability sync; don't rely on manual updates during a sale.
- No product set segmentation by category. Running every SKU in one giant "all products" set means your cross-sell logic and your cart-abandonment logic are identical, which wastes the entire point of dynamic creative.
- Ignoring the Catalog Diagnostics tab. Commerce Manager flags item-level issues (missing GTIN, image too small, price format errors) that most teams never check because the campaign still "runs" even with a chunk of the catalog rejected. Check it weekly, not just at setup.
- Building the catalog once and never revisiting custom labels as the product line grows. New categories launched without updated custom_label tagging fall into the generic "all products" bucket by default, missing the segmentation benefit entirely.
Where Vernacular Creative Fits Into Dynamic Ads
Dynamic Product Ads use templated overlays — the frame, badge and CTA text around the product image — and this is a spot Indian brands frequently leave on English defaults even when their static creative is already localised. Meta's Catalog templates support custom text overlays per language, and swapping "Still thinking about it?" for a Hindi, Tamil or Bengali equivalent on the cart-abandonment tier is a small change that compounds across every dynamically-served impression. If you're already generating vernacular ad copy for your static campaigns, extend the same language mapping to your DPA overlay templates rather than treating dynamic ads as an English-only format by default — it's an easy gap to miss precisely because DPA feels "automated" and teams assume it doesn't need the same localisation pass as manually-built creative.
Measuring Whether Your Catalog Setup Is Actually Working
Beyond ROAS at the campaign level, three catalog-specific metrics tell you whether the setup itself is healthy, independent of creative or targeting quality:
- Catalog coverage rate — the percentage of your total SKU count actually eligible to serve (not rejected, not out of stock, has all required fields). Below 90% coverage means a meaningful chunk of your inventory is invisible to DPA regardless of how well the rest performs.
- Content ID match rate between pixel events and catalog IDs, mentioned earlier — this is the single most under-diagnosed reason DPA retargeting "doesn't work" for a SKU that otherwise has plenty of traffic.
- Dynamic ad frequency per user in the cart-abandonment tier — if it climbs past 4-5 impressions a week without a purchase, tighten the exclusion window rather than letting the ad set keep hammering the same shopper, which just burns budget and increases ad fatigue on your pixel-tracked audience for future campaigns too.
None of this requires exotic tooling — Commerce Manager's Diagnostics tab and Events Manager's match-quality view cover the first two, and standard frequency reporting in Ads Manager covers the third. The discipline is in checking them on a schedule rather than only when ROAS visibly drops, by which point you've usually been bleeding budget on a broken feed segment for a week or two already. If catalog health checks are one more dashboard you don't have time to open daily, this is exactly the kind of monitoring we built into AdsSarthi's Meta suite — feed errors, price mismatches and stale sync all surface as a single alert instead of requiring you to dig through Commerce Manager manually. You can see the full account setup, including catalog diagnostics, in a free 60-minute AI audit delivered straight to WhatsApp.
Getting Started
If you're setting up Meta Catalog for the first time, the sequence that avoids the most rework is: build the feed with India-specific custom labels from the start, verify content ID matching against your pixel before launching any campaign, then structure retargeting into the four funnel tiers rather than one blended audience. Brands that skip straight to "turn on Dynamic Ads" without this groundwork usually end up rebuilding the feed structure three months in anyway, after watching ROAS underperform expectations — better to spend the extra half-day on setup than to run a broken catalog for a quarter before noticing. Our Starter and Growth plans both include catalog health monitoring as part of the standard Meta Ads suite, so this isn't a separate tool you need to bolt on.