Skip to main content

Workflow Automation

Shopify Flow is a visual automation platform that lets merchants and developers create workflows triggered by store events. When combined with AI, Flow becomes dramatically more powerful -- instead of rigid if/then rules, workflows can make nuanced decisions based on context, patterns, and predictions. This lesson covers the architecture of AI-enhanced Flow automations and walks through five production patterns.

What is Shopify Flow?

Shopify Flow is available on all Shopify plans. It uses a trigger-condition-action model: an event triggers the workflow, conditions filter which events proceed, and actions execute the desired outcome. Developers can extend Flow with custom triggers, conditions, and actions through their apps.

Shopify Flow + AI Integration Patterns

There are three primary patterns for integrating AI into Flow workflows:

Pattern 1: AI as a Condition

Use an AI model to evaluate whether a workflow should proceed. Instead of hard-coded rules, the AI assesses context and returns a decision.

Pattern 2: AI as an Action

The trigger and conditions are standard Flow logic, but the action involves AI-generated content or decisions.

Pattern 3: AI as an Orchestrator

The AI evaluates the entire context and determines which of several possible workflows to execute. This is the most powerful pattern but requires careful error handling.

Building Custom Flow Actions with AI

To add AI-powered actions to Flow, you create a Flow action extension in your Shopify app. Here is the complete setup:

# shopify.extension.toml
[extension]
type = "flow_action"
name = "AI Product Description Generator"
handle = "ai-product-description"

[[extension.settings]]
key = "tone"
type = "single_line_text_field"
name = "Writing Tone"
description = "The tone for generated descriptions (e.g., professional, casual, luxurious)"

[[extension.settings]]
key = "max_length"
type = "number_integer"
name = "Maximum Length"
description = "Maximum character count for the generated description"
// extensions/flow-ai-action/src/index.ts
import { ActionHandler } from '@shopify/flow-extensions';
import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic();

export const handler: ActionHandler = async (payload) => {
const { product_title, product_type, product_vendor, tags, tone, max_length } = payload;

const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: parseInt(max_length) || 500,
messages: [
{
role: 'user',
content: `Write a product description for an e-commerce store.

Product: ${product_title}
Type: ${product_type}
Brand: ${product_vendor}
Tags: ${tags?.join(', ')}
Tone: ${tone || 'professional'}
Max length: ${max_length || 300} characters

Requirements:
- Lead with the primary benefit
- Include relevant keywords naturally for SEO
- End with a subtle call to action
- Do not use generic filler phrases like "high quality" without specifics`,
},
],
});

const description = response.content[0].type === 'text'
? response.content[0].text
: '';

// Return the result to Flow for the next action
return {
generated_description: description,
};
};

Automated Inventory Management

AI-powered inventory management goes beyond simple reorder-point alerts. It predicts demand, identifies slow-moving stock, and recommends actions.

Demand Forecasting Workflow

// src/workflows/inventory-forecasting.ts
interface InventoryForecast {
productId: string;
currentStock: number;
predictedDemand: number; // Units expected to sell in next 14 days
reorderPoint: number;
recommendedOrderQuantity: number;
confidence: number;
reasoning: string;
}

export async function generateInventoryForecasts(
shopId: string
): Promise<InventoryForecast[]> {
// Gather historical data
const salesHistory = await db.orders.aggregate({
shopId,
period: '90d',
groupBy: 'product_variant',
});

const seasonalTrends = await db.analytics.getSeasonalPatterns(shopId);
const currentInventory = await shopifyAdmin.getInventoryLevels(shopId);

// Use AI to generate forecasts with reasoning
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 4000,
messages: [
{
role: 'user',
content: `Analyze this inventory data and generate demand forecasts.

Sales History (last 90 days):
${JSON.stringify(salesHistory, null, 2)}

Seasonal Patterns:
${JSON.stringify(seasonalTrends, null, 2)}

Current Inventory Levels:
${JSON.stringify(currentInventory, null, 2)}

Current Date: ${new Date().toISOString().split('T')[0]}

For each product variant, provide:
1. Predicted demand for the next 14 days
2. Whether current stock is sufficient
3. Recommended reorder quantity (if needed)
4. Confidence level (0-1) and reasoning

Return as a JSON array.`,
},
],
});

return JSON.parse(
response.content[0].type === 'text' ? response.content[0].text : '[]'
);
}
Do Not Blindly Auto-Reorder

AI demand forecasting is powerful but imperfect. For high-value inventory decisions, always include a human review step. Use Flow to send reorder recommendations to the merchant as a Sidekick Pulse notification rather than automatically placing purchase orders.

Customer Segmentation with AI

Traditional segmentation uses rigid rules (spent over $500, ordered 3+ times). AI segmentation identifies nuanced behavioral patterns that merchants would never think to look for.

// src/workflows/customer-segmentation.ts
export async function segmentCustomers(shopId: string) {
const customers = await shopifyAdmin.getCustomers(shopId, {
fields: ['id', 'email', 'orders_count', 'total_spent', 'tags',
'created_at', 'last_order_date', 'average_order_value'],
limit: 1000,
});

const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 3000,
messages: [
{
role: 'user',
content: `Analyze these customers and create meaningful segments for an e-commerce store.

Customer Data:
${JSON.stringify(customers, null, 2)}

Create 5-8 segments. For each segment:
- Name (merchant-friendly, e.g., "Loyal Champions" not "Cluster 3")
- Criteria (what defines this segment)
- Size (number of customers)
- Customer IDs belonging to this segment
- Recommended marketing action

Focus on actionable segments that a merchant can target with specific campaigns.
Return as JSON.`,
},
],
});

const segments = JSON.parse(
response.content[0].type === 'text' ? response.content[0].text : '[]'
);

// Apply segment tags to customers via Admin API
for (const segment of segments) {
for (const customerId of segment.customerIds) {
await shopifyAdmin.addCustomerTag(customerId, `segment:${segment.name}`);
}
}

return segments;
}

Example Segments AI Might Identify

SegmentCriteriaAction
Weekend Warriors80%+ orders placed Sat-Sun, avg spend $75Schedule email campaigns for Friday evenings
Gift GiversMultiple shipping addresses, spikes around holidaysPromote gift wrapping and gift cards
Browse-Heavy Abandoners10+ sessions per order, high cart abandonmentTrigger comparison guides and decision-support content
One-and-Done RiskSingle purchase 30+ days ago, no return visitsSend a targeted win-back offer before they churn
Upsell ReadyConsistent purchasers of mid-tier products with high engagementPresent premium product recommendations

Dynamic Pricing

Pricing Transparency

Dynamic pricing must be implemented responsibly. Many jurisdictions have regulations about price discrimination. Always ensure your pricing logic is transparent, does not discriminate based on protected characteristics, and complies with local laws. Use AI for demand-based pricing, not customer-based pricing.

AI-powered dynamic pricing adjusts product prices based on demand signals, competition, inventory levels, and market conditions.

// src/workflows/dynamic-pricing.ts
interface PricingRecommendation {
variantId: string;
currentPrice: number;
recommendedPrice: number;
reasoning: string;
expectedImpact: string;
}

export async function generatePricingRecommendations(
shopId: string,
productIds: string[]
): Promise<PricingRecommendation[]> {
const products = await shopifyAdmin.getProducts(shopId, productIds);
const salesVelocity = await db.analytics.getSalesVelocity(shopId, productIds);
const inventoryLevels = await shopifyAdmin.getInventoryLevels(shopId);

const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 2000,
messages: [
{
role: 'user',
content: `Recommend pricing adjustments based on this data.

Rules:
- Never increase price more than 15% above the base price
- Never decrease price more than 30% below the base price
- Prioritize clearing slow-moving inventory
- Consider margin floors (never price below cost + 10%)

Products and current data:
${JSON.stringify({ products, salesVelocity, inventoryLevels }, null, 2)}

For each product, recommend a price adjustment with reasoning.
Return as JSON array.`,
},
],
});

return JSON.parse(
response.content[0].type === 'text' ? response.content[0].text : '[]'
);
}

Automated Marketing

Combine Flow triggers with AI to create marketing campaigns that respond to real-time store events.

Post-Purchase Email Sequence

// Flow trigger: Order Created
// This action generates a personalized follow-up email sequence

export async function generatePostPurchaseSequence(order: Order) {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 2000,
messages: [
{
role: 'user',
content: `Create a 3-email post-purchase sequence for this order.

Order details:
- Products: ${order.lineItems.map((i) => i.title).join(', ')}
- Total: ${order.totalPrice}
- Customer name: ${order.customer.firstName}
- Is first order: ${order.customer.ordersCount === 1}

Email 1: Thank you (send immediately)
Email 2: Usage tips for purchased products (send day 3)
Email 3: Complementary product recommendation (send day 7)

For each email, provide: subject line, preview text, and body (HTML).
Keep tone warm and helpful. Do not be pushy about the upsell.`,
},
],
});

return JSON.parse(
response.content[0].type === 'text' ? response.content[0].text : '[]'
);
}

Order Routing Optimization

For merchants with multiple fulfillment locations, AI can optimize which warehouse fulfills each order based on proximity, inventory levels, shipping costs, and delivery speed.

// src/workflows/order-routing.ts
interface RoutingDecision {
orderId: string;
assignedLocationId: string;
locationName: string;
estimatedShippingCost: number;
estimatedDeliveryDays: number;
reasoning: string;
}

export async function routeOrder(order: Order): Promise<RoutingDecision> {
const locations = await shopifyAdmin.getLocations();
const inventoryByLocation = await shopifyAdmin.getInventoryByLocation(
order.lineItems.map((i) => i.variantId)
);
const customerAddress = order.shippingAddress;

const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 500,
messages: [
{
role: 'user',
content: `Select the optimal fulfillment location for this order.

Fulfillment Locations:
${JSON.stringify(locations, null, 2)}

Inventory by Location:
${JSON.stringify(inventoryByLocation, null, 2)}

Ship-to Address: ${customerAddress.city}, ${customerAddress.province}, ${customerAddress.country}

Order Items: ${order.lineItems.map((i) => `${i.title} (qty: ${i.quantity}, variant: ${i.variantId})`).join(', ')}

Optimization priorities:
1. All items must be in stock at the chosen location (no split shipments if possible)
2. Minimize shipping distance to customer
3. Balance load across warehouses (prefer locations with higher stock levels)

Return JSON with: assignedLocationId, locationName, estimatedShippingCost, estimatedDeliveryDays, reasoning.`,
},
],
});

return JSON.parse(
response.content[0].type === 'text' ? response.content[0].text : '{}'
);
}
Split Shipment Handling

When no single location can fulfill the entire order, implement a two-pass routing strategy. First, try to find a single location. If that fails, use AI to determine the optimal split that minimizes total shipping cost while keeping the number of shipments to a minimum (customers prefer fewer packages).

Connecting It All Together in Flow

These AI-powered actions are registered as Flow actions in your app. Merchants then wire them together visually in the Flow editor:

  1. Trigger: Order created
  2. Condition: Order value > $50
  3. Action: AI fraud check (your extension)
  4. Condition: Fraud score < 0.3
  5. Action: AI order routing (your extension)
  6. Action: AI post-purchase email sequence (your extension)
  7. Action: Update customer segment tags (your extension)

Each action operates independently, receives data from Flow's context, and returns results that subsequent actions can use.

Next Steps

You have now covered the four core agentic patterns. In the next module, Building Apps, you will learn how to package these patterns into production Shopify apps with proper architecture, authentication, and deployment.