Shopify Flow's product updated trigger fires whenever someone saves a change to a product in the admin — price, title, variants, status, tags, the lot. It landed on 28 October, which is roughly the worst possible timing if you wanted a quiet launch and roughly the best possible timing if you sell things. For the first time you can have a workflow sitting behind your merchandising team that catches a dropped digit in a BFCM price before the first order lands on it.
That's the short version. The longer version involves a metafield, a Liquid expression and a Slack channel nobody mutes. Here's how we build it.
What the trigger gives you, and what it doesn't
One run per product save, not one per variant. If a merchandiser bulk-edits twelve variants in the online bulk editor and hits save, you get a single run carrying the product object with all its variants attached. So almost every useful workflow starts with a For each action looping over product.variants.
What you don't get is a before-and-after. The trigger hands you the product as it is now. It does not tell you what the price was ninety seconds ago. Flow has no memory unless you give it one, and that limitation shapes every workflow below.
The other honest caveat: this is reactive. The save has already happened. By the time Flow runs, the ₹349 price is live on your PDP and in your Meta catalogue feed. In our testing the gap is usually a few seconds, occasionally a couple of minutes when the platform is busy. A few seconds of a 90% underpriced hero product during a Diwali sale is survivable. Four hours is not, and four hours is what you get without this.
How to use the product updated trigger in Shopify Flow
Create a workflow, pick Product updated as the trigger, and immediately add a condition. Do not skip that step. Every product save in your store now runs this workflow, including the ones your inventory sync app makes at 3am, and an unfiltered workflow will either hammer your Slack or quietly burn through your run allowance.
The pattern we use on nearly every build:
- Trigger: Product updated.
- Condition: narrow it hard — product status is Active, product type is in scope, or a tag like
price-guardedis present. On a 6,000-SKU catalogue this is the difference between 40 runs a day and 4,000. - For each variant: run the real check.
- Action: alert, tag, unpublish, or write a metafield. Usually two of those.
For anything involving arithmetic — a margin floor, a percentage discount check — Flow's condition builder compares fields but won't multiply them for you. Write the comparison value as a Liquid expression instead. If your condition step refuses the expression, precompute the floor into a variant metafield from a nightly job and compare against that. Clunky, but it holds.
Workflow 1: stop a mispriced product going live
This is the one worth building first. A variant costs you ₹1,180 landed. It sells at ₹3,499. During festive repricing someone types 349 into the bulk editor instead of 3,499, which is a single keystroke away and happens more often than anyone admits.
Set a floor at cost × 1.4, so ₹1,652. The condition: for each variant, if variant.price is less than variant.inventoryItem.unitCost.amount times 1.4, something is wrong. 349 is well under 1,652, so it fires.
Two actions, in this order. First, unpublish the product from the Online Store — Flow can remove a product from a sales channel, and that stops the bleeding. Second, post to Slack with the product title, the variant SKU, the price that triggered it and a direct admin link. Not an email. Email gets read at 11pm.
The arithmetic on why this matters: if that variant does 60 units in the nine minutes before someone notices, you've sold ₹20,940 of product that should have brought ₹209,940. A ₹189,000 hole, from one keystroke. On COD orders you also eat the shipping and RTO on the cancellations you'll issue.
Set the multiplier by category, not globally. Clearance lines legitimately sit at 1.1× cost. A 1.4 floor across a mixed catalogue produces so many false positives that the channel gets muted inside a week, and a muted alert channel is worse than no alert channel.
Workflow 2: the compare-at price that quietly disappeared
Compare-at price is the field that breaks silently. Someone duplicates a product, edits the price, forgets the compare-at. Or a pricing app writes a new price and clears the strike-through. The PDP still works. Nothing errors. You just lose the discount badge on the collection page and the sale price in your Meta and Google feeds, and a week later someone asks why the ROAS on that campaign fell off.
The check is simple. For each variant where the product carries a on-sale tag: if compareAtPrice is blank, or compare-at is less than or equal to price, flag it.
Action: add the tag compare-at-missing and post to Slack. We deliberately don't auto-fix this one by writing a compare-at value back. Guessing what the original price was is how you end up advertising a 60% discount off a number nobody ever charged, which in India is the kind of thing the Legal Metrology rules care about. Flag it, let a human set it.
A useful extension while you're in there: check the discount depth. If compare-at is ₹2,799 and price is ₹2,199, that's 21.4% off. If a bad edit makes it 94% off, the same workflow catches it with a second condition on the ratio.
Workflow 3: re-tag anything that falls under your margin floor
Less dramatic, more useful over a full quarter. Rather than blocking anything, this one maintains a tag that your other systems read.
On every product update, loop the variants and compute margin. In India your displayed price is GST-inclusive, so the price is not your net realisation — build the tax out before you compare. A ₹1,499 price at a 12% rate nets ₹1,338.39. Against a ₹980 cost that's ₹358.39, or 26.8% on net. If your floor is 30%, this product now gets tagged margin-watch.
Then make the tag do work. Exclude margin-watch products from your automatic discount collections. Drop them from the Google Shopping feed. Pull them out of the free-shipping-eligible collection, which matters when a ₹79 shipping subsidy is a quarter of your remaining margin. The workflow doesn't make the decision. It keeps the label accurate so the rules downstream stay honest.
Crucially, remove the tag when margin recovers. A tagging workflow that only ever adds tags produces a catalogue where half the products are flagged and nobody trusts the flag.
Jewellery and anything else priced off a moving input
A margin-floor alert is close to useless on a store where prices legitimately move every day. Gold-rate-linked jewellery is the obvious case: the spot rate shifts, the price shifts, and a workflow watching for price changes fires on the entire catalogue each morning. The fix isn't a smarter Flow condition, it's getting the repricing itself correct at source so the output can be trusted. That's the problem our Gold & Silver Live Rate app was built for — live metal rates driving the price, with making charge, wastage and GST broken out for the customer. Then you point Flow at the exceptions rather than the rule.
Slack alerts for product edits, without 4,000 messages
Connect Slack as a Flow app connection once, then every workflow can post to it. Give the alerts their own channel, not #general.
The failure mode nobody warns you about: a CSV import touching 4,000 products fires 4,000 workflow runs, and if even 300 of them trip your condition you've posted 300 messages in under a minute. Slack will rate-limit you and the real alert will be buried.
Three guards that work:
- Scope the trigger condition to a tag you control, so bulk imports of out-of-scope products never reach the actions.
- For the high-volume checks, write to a metafield and tag the product instead of posting. Then run a separate scheduled workflow that posts a single digest.
- Keep unpublish-and-alert for the genuinely catastrophic case only. If the alert can wait four hours, it belongs in the digest.
Inventory alerts belong on a different trigger
If what you actually want is a notification when stock moves — a hero SKU dropping below 20 units mid-sale, or a warehouse sync zeroing out a bestseller — use Flow's inventory quantity trigger rather than the product update one. It fires on the quantity change itself, carries the delta and the location, and won't make you diff anything.
The product update trigger is for the fields a person edits: price, compare-at, status, title, variant options. Keep the two concerns in separate workflows. A single workflow trying to handle both ends up with conditions nobody can read six months later.
The loop problem, and two other things that bite
Self-triggering. A workflow triggered by a product update that then tags the product has just updated the product. Which triggers the workflow. Shopify stops runaway loops, but you'll still see duplicate runs and duplicate alerts. Guard it: check whether the tag is already present before adding it, and exit if it is. We get this wrong on the first pass maybe a third of the time.
Also:
- Missing cost data. Any margin check depends on cost per item being filled in on the inventory item. On most catalogues we inherit, it's blank on a meaningful slice of SKUs. A blank cost makes the floor zero and the condition never fires, so the workflow looks like it's working when it's doing nothing. Run a report on empty cost fields before you trust a single margin alert.
- Apps that write prices. Subscription apps, B2B catalogues, currency tools and bundle apps all touch products. Your workflow sees their writes as ordinary edits. Either scope the condition tightly or accept the noise.
When the logic outgrows what the condition builder can express — multi-location stock plus channel-specific pricing plus a cost that varies by batch — that's the point to stop stacking Flow steps and write it properly against the Admin API. We cover that path in custom app development, and it's usually a smaller job than people expect.
Quick answers
Can Flow prevent a bad price from going live at all? No. It runs after the save. Unpublishing within seconds is the closest you get. If you need true prevention, you need the edit to happen somewhere other than the Shopify admin — a PIM or an approval layer that pushes to Shopify only after sign-off.
How do I detect that a price changed, rather than just checking its value? Store the price in a variant metafield at the end of each run. On the next run, compare the live price against the metafield before overwriting it. That gives you a one-step history and lets you alert on the change itself, for example any move greater than 15%.
Can I build a workflow for variant-level changes like a new size being added? Yes, with a loop over the variants and a count check against a stored value. Same metafield trick: write the variant count, compare on the next update, alert when it moves. Useful for catching a variant deleted by accident during festive prep.
Should every store build these? If one person edits prices and you have 80 SKUs, probably not. The cost of a mistake is low and you'll spot it. At 500+ SKUs with three people in the admin during a sale month, the first workflow pays for itself the first time it fires.
Build workflow one this week, before the next price push. Scope it to your top 50 revenue SKUs, set the floor generously, run it for a few days and see what it catches. If it catches nothing and the channel stays quiet, tighten the multiplier. If your pricing logic is tangled enough that Flow can't express it, bring in a developer for a day — or send us the store and we'll tell you what we'd automate first in a free audit.


