Meta description: I built Python scripts to automate abandoned cart emails, customer segmentation, and reporting for a Shopify store — here’s exactly how it works.
Last updated: July 17, 2026
Intro
A Shopify store I consulted for was manually exporting orders every day, tagging customers by hand for email segments, and building a weekly sales report in a spreadsheet that took almost two hours to compile. Shopify marketing automation through their native tools covered maybe 60% of what the business actually needed. The rest — custom segmentation logic and cross-referencing data with their email platform — needed something more flexible, so I built a set of Python scripts using Shopify’s Admin API to fill the gap.
TL;DR
- Shopify’s Admin API (REST and GraphQL) gives you full programmatic access to orders, customers, and products — enough to build custom automation Shopify Flow can’t handle natively.
- I used Python with
pandasand therequestslibrary to build customer segments and sync them to Klaviyo, avoiding manual CSV exports entirely. - The biggest gotcha: Shopify’s API rate limits (2 requests/second on REST) will silently throttle bulk operations if you don’t handle backoff correctly.
Why This Matters for E-commerce Teams
Shopify Flow and built-in automations cover common cases — abandoned cart emails, basic tagging — but they hit a wall fast when you need custom logic, like segmenting customers by lifetime value bands or triggering different follow-ups based on product category combinations. For a lean e-commerce team without a dedicated developer, that gap either means expensive third-party apps or hours of manual work every week.
Building this with Python automation on top of Shopify’s Admin API gave the team full control without paying for another subscription app, and it’s flexible enough to adapt as the business’s segmentation logic changes.
[INTERNAL LINK: related article]
Prerequisites
Before starting, you’ll need:
- A Shopify store with Admin API access (create a custom app under Settings → Apps → Develop apps)
- Python 3.11+ with
requests,pandas, andpython-dotenvinstalled - An email platform with its own API (I used Klaviyo in this example)
- Read access scopes for
read_orders,read_customers, andread_products
pip install requests pandas python-dotenv
Security Note: Store your Shopify Admin API access token in a
.envfile, never in the script itself — this token has broad access to store and customer data.
Step-by-Step Implementation
Step 1: Authenticate with Shopify’s Admin API
import requests
import os
from dotenv import load_dotenv
load_dotenv()
SHOP_URL = os.getenv("SHOPIFY_STORE_URL") # e.g. "your-store.myshopify.com"
ACCESS_TOKEN = os.getenv("SHOPIFY_ACCESS_TOKEN")
headers = {
"X-Shopify-Access-Token": ACCESS_TOKEN,
"Content-Type": "application/json"
}
response = requests.get(
f"https://{SHOP_URL}/admin/api/2024-10/orders.json?status=any&limit=250",
headers=headers
)
orders = response.json()["orders"]
Step 2: Pull and Structure Order Data
import pandas as pd
df = pd.DataFrame([{
"customer_email": o["email"],
"total_price": float(o["total_price"]),
"created_at": o["created_at"],
"line_items": [item["title"] for item in o["line_items"]]
} for o in orders])
Step 3: Build Custom Customer Segments
I segmented customers into value bands based on total lifetime spend, something Shopify’s native segmentation didn’t handle at the granularity we needed.
customer_totals = df.groupby("customer_email")["total_price"].sum().reset_index()
def segment(spend):
if spend >= 500:
return "vip"
elif spend >= 150:
return "repeat_buyer"
else:
return "new_customer"
customer_totals["segment"] = customer_totals["total_price"].apply(segment)
Step 4: Sync Segments to Klaviyo
KLAVIYO_API_KEY = os.getenv("KLAVIYO_API_KEY")
def sync_to_klaviyo(email, segment):
payload = {
"data": {
"type": "profile",
"attributes": {
"email": email,
"properties": {"segment": segment}
}
}
}
resp = requests.post(
"https://a.klaviyo.com/api/profiles/",
json=payload,
headers={
"Authorization": f"Klaviyo-API-Key {KLAVIYO_API_KEY}",
"revision": "2024-10-15"
}
)
return resp.status_code
for _, row in customer_totals.iterrows():
sync_to_klaviyo(row["customer_email"], row["segment"])
Step 5: Handle Rate Limits with Backoff
import time
def safe_get(url, headers, retries=3):
for attempt in range(retries):
resp = requests.get(url, headers=headers)
if resp.status_code == 429:
retry_after = float(resp.headers.get("Retry-After", 2))
time.sleep(retry_after)
continue
return resp
raise Exception("Max retries exceeded on Shopify API call")
Real-World Tips I Use in Production
- I run the segmentation script as a nightly scheduled job rather than in real-time, since customer lifetime value doesn’t need to update minute-by-minute.
- I always log the number of customers moved between segments each run — a sudden spike usually means a data issue, not a real trend.
- I paginate through Shopify’s API using the
page_infocursor rather than assuming all data fits in one request — stores with thousands of orders will silently truncate otherwise.
Common Errors and How I Fixed Them
429 Too Many Requests during bulk customer sync — I was firing requests as fast as Python could loop, ignoring Shopify’s REST limit of roughly 2 requests/second. I fixed it by adding the backoff logic above and respecting the Retry-After header.
Missing orders in the pulled dataset — The default orders.json endpoint only returns open orders unless you explicitly pass status=any. I fixed this by adding that query parameter, which was easy to miss in the docs.
Klaviyo profile updates silently failing — I was using an outdated API revision date, which caused a 400 error with a vague message. I fixed it by pinning the revision header explicitly and checking Klaviyo’s changelog before each script update.
[SOURCE: https://shopify.dev/docs/api/admin-rest] [SOURCE: https://developers.klaviyo.com/en/reference/api-overview]
FAQ
Q: Can I automate Shopify marketing tasks without paying for a third-party app? A: Yes — using Shopify’s Admin API with Python, you can build custom segmentation and reporting automation without an ongoing app subscription, though you’ll need some development time upfront.
Q: What are Shopify’s API rate limits for bulk operations? A: The REST Admin API allows roughly 2 requests per second by default (bucket-based), so bulk operations need backoff handling to avoid 429 errors.
Q: How do I sync Shopify customer segments to an email marketing platform? A: Pull customer and order data via Shopify’s Admin API, compute your segments in Python, then push updated profile properties to your email platform’s API, such as Klaviyo’s profiles endpoint.
Q: Is Python or Shopify Flow better for e-commerce automation? A: Shopify Flow works well for simple built-in triggers, but Python gives you full control over custom logic like lifetime-value-based segmentation that Flow can’t easily replicate.
Q: How often should I run automated customer segmentation for an e-commerce store? A: A nightly scheduled run is usually sufficient since lifetime value and purchase behavior don’t need real-time updates for most marketing use cases.
Conclusion
Shopify’s native automation tools are a great starting point, but once your segmentation logic gets specific, Python and the Admin API give you far more flexibility without adding another monthly subscription. The scripts above took a two-hour weekly manual process down to a scheduled job that runs while the team sleeps.
About the Author
I’ve worked in e-commerce development for 6 years, with a focus on Shopify integrations and marketing automation for the last 3. My current stack is Python, the Shopify Admin API, and Klaviyo for email marketing execution.
