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. The action can also be handed to an AI Node as an AI toolkit.
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.
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
Twelve operations, all on Shopify's GraphQL Admin API. The API has hundreds of mutations; these are the ones people actually automate — customers, tags, stock and lookups, the order lifecycle (draft, complete, fulfil, cancel), metafields and new products.
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.
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}}. The id has to be of the kind you picked under What to tag: a customer id with Order picked is refused instead of tagging the customer. Tags can be typed vip, mx or arrive as a list from the payload.
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.
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:ada@example.com, financial_status:paid — and returns one record by default, up to 50 orders or customers, or 25 products. Products come with their variants — the variantId a draft order's line items need and the inventoryItemId inventory needs. Newest first sorts by creation date, and when there is more a nextCursor comes back to pass as Next page.
Get order and List locations
Get order reads one order whole: line items, payment and fulfilment status, customer, shipping address and totals. List locations returns the places the store keeps stock, with the ids Adjust inventory needs.
Draft, complete, fulfil, cancel
Create draft order builds an order the merchant can review or invoice, and charges nobody. Its line items are a JSON list — type it, or point it at {{payload.items}} when the payload already has one. Complete draft order turns it into a real order, Fulfil order marks it shipped and Cancel order cancels it; none of the three is undone by running it again. Set a metafield writes custom data onto an order, customer, product or variant, and Create product puts a product in the catalogue.
PAID — nothing is charged, but it reads as paid in your admin and in every report. Only complete drafts the customer has already paid for.AI toolkit mode
Once the store is connected, the node asks for a Mode. AI toolkit turns it into fifteen tools that an AI Node — or an MCP client, through one of your MCP servers — calls by name.
| Tool | Arguments |
|---|---|
| search_shopify_products | query? · limit? · newest_first? · after? |
| search_shopify_orders | query? · limit? · newest_first? · after? |
| search_shopify_customers | query? · limit? · newest_first? · after? |
| get_shopify_order | order_id |
| list_shopify_locations | — |
| upsert_shopify_customer | email · first_name? · last_name? · phone? · tags? · note? |
| add_shopify_tags | resource_id · tags |
| remove_shopify_tags | resource_id · tags |
| adjust_shopify_inventory | inventory_item_id · location_id · delta · reason? · quantity_name? · reference_document_uri? |
| create_shopify_draft_order | line_items · email? · customer_id? · note? · tags? · shipping_address? |
| complete_shopify_draft_order | draft_order_id · source_name? |
| fulfill_shopify_order | order_id · tracking_number? · tracking_company? · tracking_url? |
| cancel_shopify_order | order_id · reason · staff_note? |
| set_shopify_metafield | owner_id · namespace? · key · type · value |
| create_shopify_product | title · description_html? · vendor? · product_type? · tags? · handle? |
A search without query lists without a filter. Products come with their variants, so the model can go from a search to a draft order or an inventory move without asking you for ids.
What you control
- Blocked from the start.
cancel_shopify_order,complete_shopify_draft_orderandfulfill_shopify_ordermove money, stock or a shipment and can't be undone, so they start blocked. Unblock them under Block these tool calls if the agent should. - Emails to customers. Whether fulfilling or cancelling emails the customer is yours: off by default, and no tool has an argument for it.
- Restocking. Whether a cancellation puts the stock back is yours too, off by default.
- New products. Born as Draft, hidden from shoppers, unless you pick Active.
- Marketing consent. The model never changes a customer's email marketing consent, and it never picks a payment gateway — which means a draft it completes is marked as paid. That is why
complete_shopify_draft_orderstarts blocked. - Characters per call sent to the model. 20,000 by default, anything from 1,000 to 200,000.
What goes back to the model
The same response as the operation. Lists that don't fit the characters limit are cut whole items at a time, with a notes field saying how many were left out. Arguments are used as written: a {{payload.x}} the model writes is not resolved against the flow.
Testing a tool
operation in their payload that names another tool is refused.{ "operation": "search_shopify_products", "query": "title:snowboard*", "limit": 5 }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.
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.
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 Test push button reads the most recent orders, products, customers and stock levels of your store and shows them the way a delivery will arrive, without running the flow. It is rebuilt from the store's current data, so a live delivery can carry more fields and its dates come in the store's time zone. To see a real one, activate the trigger and do the thing in your store — placing a test order is the quickest.
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
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.