Shopify

Two nodes, one connected store. The action writes into the store — add or update a customer, tag an order, move stock — or reads it back to enrich a payload. The trigger fires a flow when something happens in the store: an order comes in, a product changes, stock moves.

Connect a store

Both nodes use the same credential, and you connect it once. Click Connect Shopify in either node's credential picker, or from Settings → Credentials.

Shopify asks for one thing no other integration here does: the store, before the flow starts. Its approval screen lives on your own domain — your-store.myshopify.com/admin/oauth/authorize —, so without knowing the store there is nowhere to send you. Use the permanent domain from Settings → Domains, not a custom domain you may have pointed at the store. Pasting the whole admin URL works; so does the bare handle.

The store travels with the credential from then on. That is why the trigger has no “which store” step and the action node shows no store field: one credential is one store. To work with a second store, connect it as a second credential.


The action node

Four operations, all on Shopify's GraphQL Admin API. The API has hundreds of mutations; these are the ones people actually automate.

Add or update customer

Looks the customer up by email, then creates them or updates the fields you set. Point the email at your incoming payload — {{payload.email}} — and leave blank anything you do not want to touch: empty fields are left exactly as they were on an existing customer.

Two fields behave differently from the rest. Tags replace the customer's tags rather than adding to them — to add without losing the others, use the tag operation below. And email marketing consent should stay empty unless the person actually opted in: leaving it empty preserves whatever consent they already had, while writing a subscribed state for someone who never agreed is a legal problem, not a technical one.

Add or remove tags

Tags an order, a customer, a product or a draft order. You pass the Shopify global id — gid://shopify/Order/1234 — and a Shopify trigger hands you one directly in {{payload.body.admin_graphql_api_id}}.

Unlike Mailchimp, Shopify cannot add and remove in the same call, so one node does one direction. The Remove these tags checkbox flips it.

Adjust inventory

For the case where the real stock lives in another system. You give it an inventory item, a location, and how much to move.

The amount is a change, not a total. 5 adds five units and -5 removes five. Sending the absolute stock level on every run is the mistake that silently multiplies inventory.

The inventory item is not the product and not the variant — a variant points at one. And the reason you type lands in the store's own inventory history, so someone reading it in Shopify later can tell why the stock moved.

Find orders, customers or products

Reads the store to enrich a payload that came from somewhere else. Takes Shopify search syntax — email:[email protected], financial_status:paid — and returns one record by default.

Asking for many records does not cost more calls; it costs more of your query budget. See Good to know.

The trigger

Pick a store credential, then pick what fires it. Six buckets: orders, fulfilled orders, products, customers, inventory levels and checkouts. Each expands to Shopify's own webhook topics when the trigger is activated.

Shopify registers one subscription per event type, so a trigger watching orders and products is several subscriptions behind the scenes. Deactivating deletes all of them; you never manage them by hand.

There are no per-event filters here on purpose. Everything of the kinds you picked arrives, and a Filter node right after the trigger narrows it down — only paid orders over a certain amount, say.

If the app is removed from the store

Every Shopify trigger also listens for the app being uninstalled, whether you asked for it or not. It is the only signal Shopify gives that the credential has stopped working — without it, an uninstalled store looks exactly like a store where nothing is happening.

That event never runs your flow. It marks the credential as needing a reconnect, so the screen can say so instead of leaving your nodes failing with an error that looks like a network problem.


What the trigger sends downstream

The delivery metadata is flattened, and Shopify's raw body is kept whole under body so nothing is lost — every topic has a different shape and flattening forty of them would be inventing a contract:

{
  "id": "b4f1c2e0-...",
  "topic": "orders/create",
  "shop": "your-store.myshopify.com",
  "eventId": "9f3a...",
  "triggeredAt": "2026-08-25T18:04:11Z",
  "apiVersion": "2026-07",
  "resourceId": "gid://shopify/Order/1234567890",
  "body": { "...": "the raw Shopify body" }
}

Reach anything Shopify sent with {{payload.body.whatever}} — the line items of an order, the variant of a product, the tags already on a customer.

The id is the delivery, not the order. Shopify sends the same order id on orders/create and again on orders/updated, and it groups both under one eventId when a single action caused them — so deduplicating on either would quietly drop the second event. The delivery id is unique per delivery, which is what makes retries safe without losing real events.

Trying it out

The trigger has no test button yet. Activate it and do the thing in your store — placing a test order is the quickest — and the event arrives.

The action node's Run test button is not a rehearsal: three of its four operations write to your real store, and an inventory adjustment is not undone by running it again — it is doubled. Point it at a development store the first time.

Good to know

The rate limit counts cost, not calls

Shopify meters the GraphQL Admin API by how expensive each query is, not by how many you make: 100 points per second on a standard plan, 200 on Advanced, 1000 on Plus. A search asking for fifty records costs more than one asking for one. If the store throttles, HostWebhook backs off and retries once.

A trigger can go quiet without saying so

If Shopify fails to deliver to a subscription eight times in a row, it deletes the subscription and emails the app developer — not you. The trigger keeps showing as active while nothing arrives. If a Shopify trigger stops firing and you cannot see why, deactivate and activate it again: that registers the subscriptions from scratch.

The API version moves quarterly

HostWebhook pins one Admin API version and updates it deliberately. Shopify supports each version for at least twelve months, so nothing breaks under you between updates.

One app per store, for now

The HostWebhook Shopify app uses custom distribution, which means it is installed on a store by link rather than from the Shopify App Store. The upside is real: no review to wait for, and full access to customer data from day one. The limit is that connecting a store is not yet self-service — ask us and we will set it up.