By Raj
Connect Shopify API to Google Sheets (Production-Ready Guide)
Most Shopify store owners still export CSV files to track orders or inventory in Google Sheets. That approach breaks the moment your store starts scaling. Stock goes out of sync, reports become outdated, and manual effort increases every day.
A better solution is to connect Shopify API to Google Sheets using Google Apps Script. This allows you to automatically sync orders, products, and inventory into a live spreadsheet without manual exports.
This guide goes beyond basic tutorials. You'll learn how to build a reliable Shopify-to-Sheets automation that handles pagination, rate limits, and real-world data scenarios.
What this integration actually solves
Connecting Shopify with Google Sheets is not just about pulling data it's about building a usable system.
Businesses use this setup to: Track real-time sales performance Monitor inventory across channels Build custom dashboards Combine Shopify data with marketing or finance data
Why manual CSV exports fail at scale
If you're manually exporting CSV files from Shopify to Google Sheets, you've likely encountered these issues:
Data freshness problems: By the time you export, analyze, and share reports, the data is already outdated. Sales teams make decisions on stale information.
Error-prone processes: Manual exports invite human error wrong date ranges, missing columns, or accidentally overwriting previous data.
Time sink: Spending 30 minutes daily on exports adds up to 10+ hours per month time better spent on strategy or customer acquisition.
API integration solves these problems by creating a live data pipeline between your Shopify store and Google Sheets.
Architecture overview (how it works)
At a high level, the system works like this:
1. Apps Script calls Shopify REST API using UrlFetchApp2. API returns JSON data (orders, products, etc.) 3. Script processes and formats data 4. Data is written into Google Sheets in bulk 5. Triggers run this process automatically
This architecture mirrors how enterprise systems handle data synchronization, but simplified for small-to-medium Shopify stores.
Step 1: Get your Shopify API credentials
Before writing any code, you need to generate API access credentials from your Shopify admin.
Step-by-step:
1. Go to your Shopify Admin ? Settings ? Apps and sales channels 2. Click "Develop apps" ? "Create an app" 3. Name your app (e.g., "Google Sheets Integration") 4. Configure Admin API scopes: read_orders, read_products, read_inventory5. Install the app and save your Access Token
Important: The Admin API access token appears only once copy it immediately and store it securely.
Step 2: Store API credentials securely
Never store API keys inside your code. Use PropertiesService to keep credentials secure and manageable.
// In Apps Script, go to File ? Project properties ? Script properties
// Add these key-value pairs:
// SHOPIFY_STORE: your-store.myshopify.com
// SHOPIFY_TOKEN: your_access_token_here
function getShopifyConfig() {
const props = PropertiesService.getScriptProperties();
return {
store: props.getProperty("SHOPIFY_STORE"),
token: props.getProperty("SHOPIFY_TOKEN"),
apiVersion: "2024-01"
};
}This approach keeps your credentials separate from your code, making it easier to update tokens without modifying scripts.
Step 3: Fetch Shopify orders
Now let's build the core function to fetch orders from Shopify and write them to Google Sheets.
function fetchShopifyOrders() {
const config = getShopifyConfig();
const shop = config.store;
const token = config.token;
const apiVersion = config.apiVersion;
// Build the API URL with desired fields
const url = "https://" + shop + "/admin/api/" + apiVersion +
"/orders.json?limit=50&fields=id,name,created_at,customer,total_price,financial_status";
const options = {
method: "GET",
headers: {
"X-Shopify-Access-Token": token,
"Content-Type": "application/json"
},
muteHttpExceptions: true
};
try {
const response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() === 200) {
const data = JSON.parse(response.getContentText());
const orders = data.orders;
writeOrdersToSheet(orders);
Logger.log("Successfully synced " + orders.length + " orders");
} else {
Logger.log("Error: " + response.getContentText());
}
} catch (error) {
Logger.log("Fetch error: " + error.message);
}
}This function fetches 50 orders at a time with essential fields. The limit parameter controls how many records Shopify returns per request.
Step 4: Write data to Google Sheets efficiently
Writing data row-by-row is slow and can hit Apps Script execution limits. Use batch writing instead:
function writeOrdersToSheet(orders) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
// Prepare header row
const headers = ["Order #", "Date", "Customer Email", "Total", "Status"];
// Prepare data rows
const data = orders.map(order => [
order.name,
new Date(order.created_at),
order.customer ? order.customer.email : "N/A",
order.total_price,
order.financial_status
]);
// Clear old data (optional - comment out to append)
sheet.clearContents();
// Write header
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
// Write all data in one call (much faster than row-by-row)
if (data.length > 0) {
sheet.getRange(2, 1, data.length, headers.length).setValues(data);
}
}The key optimization here is setValues() it writes the entire array in one API call, making the process 10-100x faster than appending rows individually.
Handling pagination (critical for scaling)
Shopify limits responses to a maximum of 50 records per request by default (max 250). If your store has hundreds or thousands of orders, you must implement pagination using the page_info cursor.
Without pagination, your data will always be incomplete which is one of the most common mistakes in beginner implementations.
function fetchAllOrders() {
const config = getShopifyConfig();
let allOrders = [];
let hasNextPage = true;
let pageInfo = null;
while (hasNextPage) {
// Build URL with pagination cursor
let url = "https://" + config.store + "/admin/api/" + config.apiVersion +
"/orders.json?limit=250&fields=id,name,created_at,customer,total_price";
if (pageInfo) {
url += "&page_info=" + pageInfo;
}
const response = UrlFetchApp.fetch(url, {
method: "GET",
headers: { "X-Shopify-Access-Token": config.token },
muteHttpExceptions: true
});
const data = JSON.parse(response.getContentText());
allOrders = allOrders.concat(data.orders);
// Check for next page in response headers
const linkHeader = response.getHeaders()["Link"];
if (linkHeader && linkHeader.includes('rel="next"')) {
// Extract page_info from Link header
const match = linkHeader.match(/page_info=([^>&]+).*rel="next"/);
pageInfo = match ? match[1] : null;
} else {
hasNextPage = false;
}
// Respect rate limits - add delay between requests
Utilities.sleep(500);
}
writeOrdersToSheet(allOrders);
return allOrders.length;
}This function loops through all pages until no rel="next" link exists in the response headers. The 500ms delay prevents hitting Shopify's rate limits.
Shopify API rate limits explained
Shopify enforces API limits to prevent overload. Understanding these limits is crucial for production systems:
Rate limit tiers:
Basic plans: 2 requests/second Shopify Plus: 4 requests/second Burst limits: Up to 10 requests/second (short durations)
Consequences of exceeding limits:
HTTP 429 response (Too Many Requests) Temporary IP blocking API access suspension in extreme cases
A production-ready system must include:
Retry logic: Automatically retry failed requests after a delayRequest batching: Combine multiple data needs into fewer callsExponential backoff: Increase delay between retries on repeated failures
function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = UrlFetchApp.fetch(url, options);
const responseCode = response.getResponseCode();
if (responseCode === 200) {
return JSON.parse(response.getContentText());
} else if (responseCode === 429) {
// Rate limited - wait and retry with exponential backoff
const waitTime = Math.pow(2, attempt) * 1000;
Logger.log("Rate limited. Waiting " + waitTime + "ms before retry...");
Utilities.sleep(waitTime);
} else {
throw new Error("HTTP " + responseCode + ": " + response.getContentText());
}
} catch (error) {
if (attempt === maxRetries - 1) throw error;
Logger.log("Attempt " + (attempt + 1) + " failed: " + error.message);
Utilities.sleep(Math.pow(2, attempt) * 1000);
}
}
}Performance optimization (Apps Script limits)
Google Apps Script has strict execution limits that affect large data syncs:
Time limit: 6 minutes per execution (consumer accounts)URL fetch size: 50MB per callSpreadsheet operations: ~500 writes per minute
If your data volume is large, you need to:
Process data in chunks: Fetch and write 250 records at a timeUse triggers for continuation: Schedule multiple runs to complete full syncsAvoid row-by-row writes: Always use batch setValues()
Pro tip: For stores with 10,000+ orders, consider syncing only the last 30 days of data initially, then use time-based triggers to keep data current.
Syncing products and inventory
Beyond orders, you can sync products and inventory levels to track stock across your Shopify store:
function fetchShopifyProducts() {
const config = getShopifyConfig();
const url = "https://" + config.store + "/admin/api/" + config.apiVersion +
"/products.json?limit=250&fields=id,title,variants,inventory_quantity";
const response = UrlFetchApp.fetch(url, {
method: "GET",
headers: { "X-Shopify-Access-Token": config.token }
});
const data = JSON.parse(response.getContentText());
const products = data.products;
// Transform products into inventory data
const inventoryData = [];
products.forEach(product => {
product.variants.forEach(variant => {
inventoryData.push([
product.title,
variant.title,
variant.sku,
variant.inventory_quantity || 0,
variant.price
]);
});
});
// Write to inventory sheet
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Inventory");
sheet.getRange(2, 1, inventoryData.length, 5).setValues(inventoryData);
}This gives you a real-time view of all product variants and their current stock levels, enabling better inventory management decisions.
Setting up automatic sync with triggers
Manual syncing defeats the purpose. Set up time-based triggers to run automatically:
To create a trigger:
1. In Apps Script editor, click clock icon (Triggers) 2. Click "+ Add Trigger" 3. Choose: fetchShopifyOrders as function 4. Select: Time-driven, every hour (or every 6 hours) 5. Save and authorize
This keeps your Google Sheets data automatically synchronized with your Shopify store without any manual intervention.
Real-world implementation issues
In real projects, things rarely work perfectly on first attempt.
Common problems include:
Duplicate records: Use order IDs as unique identifiers and check before writingMissing customer data: Some orders have no customer (guest checkout) handle null valuesAPI timeouts: Large data sets can timeout implement chunked processingData mismatch: Shopify and Sheets handle dates differently always parse dates explicitly
This is why production systems require logging, validation, and retry mechanisms.
Apps Script vs Shopify apps (Zapier, Make)
Tools like Zapier or Make can connect Shopify to Google Sheets quickly, but they come with limitations.
Apps Script advantages:
No monthly cost (free for personal use) Full customization control Better scalability for large data volumes Direct API access without markup fees
Third-party tools advantages:
Faster initial setup Visual workflow builder Pre-built integrations Support included
Third-party tools are easier to start with, but Apps Script is more powerful long term especially if you're comfortable with code and need custom business logic.
Common use cases for this integration
Once connected, businesses use this setup for various purposes:
1. Sales performance tracking: Monitor daily revenue, average order value, and conversion trends in real-time.
2. Inventory alerts: Get notified when stock falls below thresholds for popular products.
3. Customer analytics: Analyze purchase patterns, repeat customer rates, and customer lifetime value.
4. Financial reporting: Combine Shopify revenue data with advertising costs for profit margin analysis.
5. Multi-channel reporting: If you sell on multiple platforms, consolidate all data in one Sheets dashboard.
Security best practices
When connecting APIs to your business data, security should be a top priority:
Use script properties: Never hardcode API tokens in your codeLimit API scopes: Only request the minimum permissions neededRotate tokens regularly: Update access tokens every 3-6 monthsMonitor API usage: Check Shopify admin for unusual API activitySeparate read/write access: Use different tokens for different integration needs
Need a reliable Shopify + Google Sheets automation built for your business?
Get it built ?FAQ
How do I connect Shopify API to Google Sheets?
Use Apps Script with UrlFetchApp to fetch Shopify API data and write it into Google Sheets. First, generate API credentials in your Shopify admin, then create an Apps Script project with functions to fetch and write data. Set up time-based triggers for automatic synchronization.
Can Shopify sync automatically with Google Sheets?
Yes, using time-based triggers in Google Apps Script, data can sync automatically at intervals you choose (hourly, daily, etc.). This eliminates manual exports and keeps your data current without any intervention.
Is Apps Script better than Shopify apps?
For custom workflows and cost savings, Apps Script is often better. It offers full customization, no monthly fees, and better control over data transformation. However, it requires coding knowledge. Third-party tools like Zapier are faster to set up but come with ongoing costs.
How much does Shopify API integration cost?
Google Apps Script is free for personal and most business use. Shopify's Admin API is free to use with your store. The only costs are your time to set it up and any Google Workspace fees if using Sheets for team collaboration.
Can I sync inventory levels from Shopify to Google Sheets?
Yes, the same API integration can fetch product and inventory data. Use the /admin/api/version/products.json endpoint to get variant-level inventory quantities. This enables real-time stock monitoring and low-stock alerts.
How often should I sync Shopify data to Google Sheets?
For most stores, syncing every 1-6 hours is sufficient. High-volume stores may benefit from hourly syncs. Consider API rate limits and your actual needs more frequent syncs mean more API calls and potential throttling.
What data can I sync from Shopify to Google Sheets?
You can sync orders, products, inventory, customers, collections, and more. The Admin API provides access to most store data. Focus on the metrics that matter most to your business don't try to sync everything at once.
Why is my Shopify data not syncing to Google Sheets?
Common causes include: expired API tokens (regenerate in Shopify admin), rate limiting (add delays between requests), incorrect API scopes (verify app has required permissions), or script trigger not running (check Apps Script triggers page).