Daily
Get a daily email about low Shopify stock
Each morning you get an email listing products that will run out soon at their current pace, plus any that are not selling.
- Runs
- Daily
- Apps
- Gmail, Shopify
- AI
- Optional
- Access
- read_inventory, read_orders; gmail.send
Send this to your assistant
Create a ClickRuntime automation: every morning, email me Shopify products with under 14 days of stock at their 30-day sales rate, and anything in stock that hasn't sold in 30 days.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A solo founder selling kitchen tools does the buying, packing and marketing alone. Checking stock levels is the task that always gets pushed to tomorrow, until a best seller sells out the week before a holiday.
A morning email with just the items that need attention fits into the routine of checking the inbox. Reordering happens on time, and the slow sellers list shows where cash is tied up.
What you get out of it
Stock checks happen every day
The email arrives whether or not you remember to look. Running low never comes as a surprise.
Priorities based on sales speed
Items are ranked by days of stock left, so a fast seller is flagged early even with plenty of units. You order what is actually urgent.
Slow sellers are visible too
Products with stock but no recent sales are listed separately. You can discount them or stop reordering before they take up more space.
A supplier email can be drafted
With AI turned on, the email can include a short reorder request you can copy to your supplier. Ordering takes minutes, not a separate task.
How it works
What happens, step by step
Every morning, ClickRuntime reads stock levels for each product variant in your Shopify store.
It counts how many of each sold in the last 30 days and works out the days of stock left.
Items with less than 14 days left, and items in stock with no sales, are collected into a list.
If you turn on AI, it writes a short reorder message you can send to your supplier.
The list is emailed to you.
Before it runs live
- Connect Google through your own Google app (a one-time, 10-minute setup), so it works with your own Gmail
- Connect Shopify
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Slack
- Combine it with other Gmail and Shopify steps into one automation
Under the hood
The code that runs this automation
from datetime import date, timedelta
from collections import Counter
from clickruntime import on_trigger, credentials, http, notify, ai
STORE = "your-store.myshopify.com"
def gql(query, variables=None):
resp = http.post(f"https://{STORE}/admin/api/2025-07/graphql.json", json={"query": query, "variables": variables or {}},
headers={"X-Shopify-Access-Token": credentials.connection("shopify", "store")})
return resp.raise_for_status() or resp.json()["data"]
@on_trigger
def run(event):
orders = gql('query($q: String!) { orders(first: 250, query: $q) { nodes { lineItems(first: 50) { nodes { quantity variant { id } } } } } }',
{"q": f"created_at:>={date.today() - timedelta(days=30)}"})["orders"]["nodes"]
sold = Counter()
for o in orders:
sold.update({li["variant"]["id"]: li["quantity"] for li in o["lineItems"]["nodes"] if li["variant"]})
low, idle = [], []
for v in gql("{ productVariants(first: 250) { nodes { id displayName inventoryQuantity } } }")["productVariants"]["nodes"]:
if sold[v["id"]]:
days = v["inventoryQuantity"] / (sold[v["id"]] / 30)
if days < 14:
low.append(f"{v['displayName']}: {v['inventoryQuantity']} left, about {days:.0f} days")
elif v["inventoryQuantity"] > 0:
idle.append(f"{v['displayName']}: {v['inventoryQuantity']} in stock, no sales in 30 days")
if not low and not idle:
return {"low": 0}
text = "Running low:\n" + "\n".join(low or ["none"]) + "\n\nNot selling:\n" + "\n".join(idle or ["none"])
try:
if low:
text += "\n\nDraft to supplier:\n" + ai.generate("\n".join(low), system="Write a short, polite reorder request for these items.", max_output_tokens=250).text
except (ai.AINotIncluded, ai.AILimitReached):
pass
notify.email_me(f"Stock check: {len(low)} low, {len(idle)} not selling", text)
return {"low": len(low), "idle": len(idle)}FAQ
Common questions
How does it decide what is low?
Will it email me every day about the same item?
Does it need AI?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Get a daily Shopify order summary by email
Each morning you get yesterday's orders, revenue, average order value and top products in one short email.
See how it worksCatch Shopify pricing and discount mistakes
Each morning you get an email if any price dropped below your floor, changed sharply, or a discount code is larger than your rules allow.
See how it worksGet emailed when Shopify orders stop or run late
You get an email if no orders arrive for longer than usual, or if paid orders pass your dispatch deadline without shipping.
See how it worksKeep exploring
Set up “Get a daily email about low Shopify stock” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.