Shopify Webhook Trigger a workflow from any Shopify event topic. The Shopify Webhook trigger fires your workflow whenever a selected event occurs in your store. Any Shopify webhook topic is supported. The data object For Shopify Webhook triggers, data is the raw Shopify webhook payload passed directly as the top-level object. There is no wrapper — you access order fields, customer fields, etc. directly: export class Workflow { async start(data, headers, api) { // data IS the order (for orders/* topics) console.log('Order ID:', data.id); console.log('Total:', data.totalprice); console.log('Customer email:', data.email); } } Useful headers The headers object includes all Shopify webhook headers: | Header | Description | | x-shopify-shop-domain | Your store's myshopify.com domain | | x-shopify-topic | The webhook topic, e.g. orders/paid | | x-shopify-webhook-id | Unique ID for this delivery | | x-shopify-attempt-number | Which retry attempt this is (1 = first) | export class Workflow { async start(data, headers, api) { const shop = headers['x-shopify-shop-domain']; const topic = headers['x-shopify-topic']; console.log(Received ${topic} from ${shop}); } } Common webhook topics | Category | Topics | | Orders | orders/create, orders/updated, orders/paid, orders/fulfilled, orders/cancelled, orders/partiallyfulfilled | | Customers | customers/create, customers/update, customers/delete | | Products | products/create, products/update, products/delete | | Inventory | inventorylevels/update, inventoryitems/update | | Refunds | refunds/create | | Checkouts | checkouts/create, checkouts/update, checkouts/delete | | Fulfilments | fulfillments/create, fulfillments/update | | Collections | collections/create, collections/update, collections/delete | Calling the Shopify API from within the workflow Use the global fetch() with your store's myshopify.com URL. The platform automatically injects the X-Shopify-Access-Token header — no manual token management needed. Use env.SHOPIFYSTORE and env.SHOPIFYAPIVERSION which are always available: export class Workflow { async start(data, headers, api) { // Token is injected automatically — env.SHOPIFYSTORE is "mystore.myshopify.com" const resp = await fetch( https://${env.SHOPIFYSTORE}/admin/api/${env.SHOPIFYAPI_VERSION}/graphql.json, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: mutation UpdateOrderNote($input: OrderInput!) { orderUpdate(input: $input) { order { id note } userErrors { field message } } }, variables: { input: { id: gid://shopify/Order/${data.id}, note: 'Processed by JsWorkflows' } }, }), } ); const { data: gqlData } = await resp.json(); const { order, userErrors } = gqlData.orderUpdate; if (userErrors.length) { console.log('Errors:', userErrors); return; } console.log('Updated note:', order.note); } } Deduplication Shopify retries undelivered webhooks up to 19 times over 48 hours. JsWorkflows automatically deduplicates deliveries using the x-shopify-webhook-id header — if a webhook ID has already been processed, subsequent retries are silently ignored within a 120-second window. Caution: Only active workflows receive and process incoming webhooks. Inactive workflows ignore all events, even while the toggle is off.