InstantDM has a built-in Shopify integration for basic product carousels in DMs. This guide covers the extended API integration - connecting InstantDM webhooks to Shopify's API for advanced use cases like order tracking, abandoned cart recovery, customer tagging, and custom product recommendations.
Why Extend the Shopify Integration?
The built-in Shopify integration handles product carousels. The extended API integration lets you:
- Sync Instagram leads to Shopify customers - create customer records from DM flow data
- Track orders - send order status updates via Instagram DM
- Recover abandoned carts - DM customers who left items in their cart
- Tag customers - segment Shopify customers by Instagram campaign
- Custom product logic - recommend products based on DM flow answers
- Discount codes - generate unique discount codes per Instagram lead
Common Use Cases
- Create a Shopify customer when someone completes a DM lead capture flow
- Send a unique discount code via DM after someone comments on a product post
- DM customers when their order ships
- Recover abandoned carts by sending a DM with the cart link
- Recommend products based on quiz answers in a DM flow
What You'll Need
| Requirement | Details |
|---|---|
| InstantDM account | Trendsetter, Trendsetter Pro, or any Multi plan |
| Shopify store | Any plan with API access |
| InstantDM API key | Found at Settings → API in your InstantDM dashboard |
| Shopify API credentials | Admin API access token from a custom app |
Step 1: Create a Shopify Custom App
- In Shopify Admin, go to Settings → Apps and sales channels → Develop apps.
- Click Create an app.
- Name it InstantDM Integration.
- Under Configuration → Admin API integration, select scopes:
read_customers,write_customersread_ordersread_productsread_price_rules,write_price_rules(for discount codes)
- Click Install app and copy the Admin API access token.
Sync Instagram Leads to Shopify Customers
Webhook Receiver
const express = require('express');
const app = express();
app.use(express.json());
const SHOPIFY_STORE = 'your-store.myshopify.com';
const SHOPIFY_TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
async function shopifyFetch(endpoint, method = 'GET', body = null) {
const response = await fetch(
`https://${SHOPIFY_STORE}/admin/api/2024-10/${endpoint}`,
{
method,
headers: {
'X-Shopify-Access-Token': SHOPIFY_TOKEN,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : null,
}
);
return response.json();
}
app.post('/instantdm-webhook', async (req, res) => {
const { event, data } = req.body;
if (event !== 'flow_completed') {
return res.status(200).json({ status: 'skipped' });
}
const email = data.response_variables?.email;
if (!email) return res.status(200).json({ status: 'skipped' });
try {
// Check if customer exists
const search = await shopifyFetch(`customers/search.json?query=email:${encodeURIComponent(email)}`);
if (search.customers?.length > 0) {
// Update existing customer
const customerId = search.customers[0].id;
await shopifyFetch(`customers/${customerId}.json`, 'PUT', {
customer: {
id: customerId,
tags: addTag(search.customers[0].tags, 'instagram-lead'),
note: `Instagram: @${data.username}. Flow: ${data.flow_name}. Interest: ${data.response_variables?.interest || 'N/A'}`,
},
});
res.status(200).json({ status: 'updated', customerId });
} else {
// Create new customer
const result = await shopifyFetch('customers.json', 'POST', {
customer: {
first_name: data.response_variables?.full_name || data.username,
email: email,
phone: data.response_variables?.phone || '',
tags: 'instagram-lead',
note: `Instagram: @${data.username}. Flow: ${data.flow_name}. Interest: ${data.response_variables?.interest || 'N/A'}`,
accepts_marketing: true,
},
});
res.status(200).json({ status: 'created', customerId: result.customer?.id });
}
} catch (error) {
res.status(500).json({ status: 'error', message: error.message });
}
});
function addTag(existingTags, newTag) {
const tags = existingTags ? existingTags.split(', ') : [];
if (!tags.includes(newTag)) tags.push(newTag);
return tags.join(', ');
}
app.listen(3000);
Generate Unique Discount Codes
Create a unique discount code for each Instagram lead:
async function createDiscountCode(customerEmail, discountPercent = 15) {
const code = `INSTA-${Date.now().toString(36).toUpperCase()}`;
// Create a price rule
const priceRule = await shopifyFetch('price_rules.json', 'POST', {
price_rule: {
title: code,
target_type: 'line_item',
target_selection: 'all',
allocation_method: 'across',
value_type: 'percentage',
value: `-${discountPercent}`,
customer_selection: 'all',
usage_limit: 1,
starts_at: new Date().toISOString(),
ends_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), // 7 days
},
});
// Create the discount code
await shopifyFetch(
`price_rules/${priceRule.price_rule.id}/discount_codes.json`,
'POST',
{ discount_code: { code } }
);
return code;
}
Then send the code via InstantDM API:
const discountCode = await createDiscountCode(email);
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.INSTANTDM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'send_message',
type: 'text',
recipient_id: data.instagram_user_id,
message: `🎉 Here's your exclusive 15% off code: ${discountCode}\n\nUse it at checkout within 7 days. Shop now: https://${SHOPIFY_STORE.replace('.myshopify.com', '.com')}`,
}),
});
Product Recommendations Based on DM Flow
If your DM flow asks about preferences, recommend matching products:
async function getProductsByTag(tag) {
const result = await shopifyFetch(
`products.json?tag=${encodeURIComponent(tag)}&limit=3&status=active`
);
return result.products || [];
}
app.post('/instantdm-webhook', async (req, res) => {
const { event, data } = req.body;
if (event !== 'flow_completed') return res.status(200).json({ status: 'skipped' });
const interest = data.response_variables?.interest?.toLowerCase();
if (!interest) return res.status(200).json({ status: 'skipped' });
const products = await getProductsByTag(interest);
if (products.length > 0) {
const productList = products.map(p =>
`• ${p.title} - $${p.variants[0].price}\n ${p.handle ? `https://yourstore.com/products/${p.handle}` : ''}`
).join('\n\n');
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.INSTANTDM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'send_message',
type: 'text',
recipient_id: data.instagram_user_id,
message: `Based on your interest in "${interest}", here are our top picks:\n\n${productList}`,
}),
});
}
res.status(200).json({ status: 'sent', products: products.length });
});
Via Make.com
- Set up the webhook per the Make.com guide.
- Add Shopify → Create a Customer module.
- Map fields from the webhook data.
- Optionally add Shopify → Create a Discount Code module.
- Add HTTP Request module to send the discount code via InstantDM API.
Troubleshooting
| Issue | Solution |
|---|---|
| Shopify API returning 401 | Verify the Admin API access token. Ensure the custom app is installed. |
| "Customer already exists" | Search for the customer first and update instead of creating. |
| Discount code not working | Check the price rule dates (starts_at and ends_at). Ensure usage_limit hasn't been reached. |
| Products not found | Verify the product tag matches. Tags are case-sensitive in the API. |
| Rate limited (429) | Shopify allows 2 requests/second for standard plans. Add delays between API calls. |
Frequently Asked Questions
How is this different from InstantDM's built-in Shopify integration?
The built-in integration lets you send product carousels in DM flows. This extended integration syncs customer data, generates discount codes, tracks orders, and enables custom product logic - things that require direct Shopify API access.
Can I send order updates via Instagram DM?
Yes. Set up a Shopify webhook for order fulfillment events, receive it in your server, and call the InstantDM API to send a DM with tracking info. The customer needs to have an existing Instagram conversation with your account.
Do I need Shopify Plus for API access?
No. All Shopify plans include API access. Shopify Plus offers higher rate limits and additional APIs, but the standard API is sufficient for InstantDM integration.
What's Next
- Set up WooCommerce if you use WordPress.
- Connect to Stripe for payment links in DMs.
- Read the Klaviyo guide for e-commerce email marketing.
- Build a Custom AI Agent for product recommendations.
- Explore the full API docs at instantdm.com/instagram-api-docs.