Shopify Flow Triggers: Why Multiple Events, Manual Runs, and Webhooks Don't Work the Way the Docs Imply

By Milan Dhameliya · · 9 min read

Shopify Flow allows exactly one trigger per workflow — there's no setting that lets a single workflow start from two different events. A manual trigger already exists inside the admin, and you can fire a workflow from an outside webhook without paying for a connector app. Here's how each piece actually works, since the reference docs bury the one-trigger rule and every existing webhook-trigger guide is a paid app's marketing page.

Shopify Flow allows exactly one trigger per workflow. There's no setting, no "add another event" button, and no workaround inside a single workflow that changes this — but "multiple triggers" is still solvable, a manual trigger already exists inside the admin under a name that doesn't say "manual," and you can fire a workflow from a webhook on an entirely different platform without paying for a connector app. Here's how each of those three things actually works.

The reason this needs writing down is that Shopify's own triggers reference states the one-trigger rule so quietly that most third-party guides never repeat it, and every article that ranks for "webhook trigger" right now is a connector app's product page explaining its own paid feature rather than the free mechanism underneath it.

Why "multiple triggers on one workflow" isn't a checkbox you're missing

Every workflow in Flow has exactly one trigger — it's the event that starts the run, full stop. If you need a workflow's logic to fire off two different events (say, a wholesale-tag check that should run on both Order created and Order paid, because some B2B orders skip straight to paid without a separate creation event in your setup), you don't add a second trigger to the same workflow. You build two small workflows — one per trigger — and have each one call a shared workflow that holds the actual logic, using the built-in Run another workflow action.

Concretely: workflow A triggers on Order created, workflow B triggers on Order paid, and both do nothing except pass the order along to workflow C, which contains the tag check, the condition, and the real action. Edit the logic once, in C, and both entry points stay in sync. This also solves a separate trap merchants hit by accident: if you build two independent workflows that both listen for the same trigger, they run in parallel with each other on every matching event, with no defined order between them — which is exactly how two "automatically apply a discount" workflows end up fighting over the same order. Consolidating shared triggers into one workflow, or funneling multiple triggers into one shared workflow via Run another workflow, is the documented way to avoid both problems at once.

The manual trigger Flow already has — it just isn't called that

Flow does let you start a workflow by hand, but it's not a distinct trigger type you pick when building the workflow. It's a bulk action available from the object's list view in the Shopify admin. Go to Orders, Draft orders, Customers, or Products, select one record or several with the checkboxes, open the bulk actions menu, and choose Run workflow. Flow then lists every active workflow whose trigger matches that object type — a workflow built on Order created, Order paid, or Order deleted shows up when you're on the Orders page; one built on Customer created shows up on the Customers page, and so on.

Two things trip people up here. First, the workflow has to be turned on — an inactive workflow doesn't appear in the list even if its trigger matches. Second, this only works for triggers Shopify has made eligible for manual/bulk runs, which in practice means the common object-lifecycle triggers on orders, draft orders, customers, and products. A workflow built on an inventory-level trigger or a fulfillment-status trigger has no admin list view to run it from by hand, and there's no separate "run this specific workflow now" button that bypasses that requirement.

This is also a different thing from testing a workflow. Test mode uses real store data — Shopify's Sidekick can even generate simulated passing and failing events from an existing order — but reads Liquid variables and evaluates conditions without taking any real action. Running a workflow manually from a list view does take the real action. If you're checking whether a workflow's logic is correct, test it. If you're rerunning a workflow against orders that existed before the workflow did, run it manually.

Firing a workflow from an external webhook, without buying a connector app

This is the part every top-ranking "Shopify Flow webhook trigger" result skips, because the top results are Flow Plus, MESA, and Webhook Triggers for Flow — apps that sell you a working version of a mechanism Shopify already documents for free at shopify.dev: a custom Flow trigger extension, fired by the Admin GraphQL flowTriggerReceive mutation.

The shape of it, once you've generated an extension with shopify app generate extension and chosen the Flow trigger type:

  1. Define the trigger in shopify.extension.toml — a handle, a display name, and the fields your workflow will need as inputs:
    [[extensions]]
    name = "Auction Bid Placed"
    type = "flow_trigger"
    handle = "auction-bid-placed"
    description = "Fires when an external auction platform records a new bid."
    
    [settings]
      [[settings.fields]]
      type = "customer_reference"
    
      [[settings.fields]]
      type = "number_decimal"
      key = "Amount"
  2. Deploy it with shopify app deploy, which also publishes it — the trigger then appears by its name in the trigger picker for any workflow on the store, exactly like a built-in "Order created" trigger. During development it shows a "draft" badge and only fires in your own dev store.
  3. Point the actual external webhook — from Stripe, a 3PL, a review platform, whatever system owns the event — at a small backend endpoint your app hosts. That endpoint receives the webhook and, in response, calls flowTriggerReceive against the Admin API:
    mutation {
      flowTriggerReceive(
        handle: "auction-bid-placed"
        payload: { "Amount": "30", "customer_id": 12345 }
      ) {
        userErrors { field message }
      }
    }
    That mutation call is what actually starts the workflow. The handle has to match the TOML exactly, and the combined payload — keys included — has to stay under 50 KB, or the mutation returns a validation error instead of firing anything.

Budget real time for the deploy step, not just the code. A Shopify Community thread documents merchants getting stuck unable to activate a custom trigger for testing — draft-badge extensions and dev-store scoping catch people who expect the trigger to be live the moment the code compiles.

When paying for a connector app is still the right call

Building your own trigger extension is worth it when you have one store (or an agency building the same pattern across several client stores) and a developer who can own a small, rarely-touched piece of infrastructure. It's a fixed cost once it's deployed, not a recurring one, and there's no third-party app tier capping how many events you can send through it. The same build-once-versus-subscribe tradeoff shows up in our purchase order API build-or-buy breakdown — the deciding factor is the same in both cases: do you have engineering time you'd rather spend once, or ongoing budget you'd rather spend instead.

Buying a connector app makes more sense when you need this across many merchants you don't control, when you have no engineering time to maintain a deploy pipeline, or when you need triggers for a wide range of one-off external events and a pre-built catalog of a hundred-plus pre-mapped triggers gets you there faster than writing extensions one at a time. Neither answer is wrong — the mistake is not knowing the free option exists before deciding.

The short version

If you're weighing whether to build this yourself or wire it through Flow, Shopify's inventory API, and a paid app all at once — that's exactly the kind of integration audit we do as part of Shopify automation and API work. It's also worth a look next to our breakdown of the inventorySetQuantities idempotency requirement, since inventory syncs built on Flow are one of the most common places this exact multiple-trigger confusion shows up. Get in touch if you want a second opinion before you build.

Sources reviewed