Pipedream is a developer-focused automation platform that lets you write real code (Node.js, Python, Go, Bash) alongside no-code steps. It's ideal for developers who want the convenience of a hosted automation platform but need more control than Make.com or Zapier offer.
Connecting InstantDM to Pipedream gives you webhook triggers, built-in auth for 1,000+ APIs, and the ability to write custom logic in any step - all with a generous free tier.
Why Use Pipedream with InstantDM?
- Code when you need it - write Node.js or Python in any step, or use pre-built actions
- Generous free tier - 10,000 invocations/month on the free plan (each webhook event = 1 invocation)
- Built-in auth - connect to APIs like Slack, Google Sheets, HubSpot without managing OAuth tokens
- Real-time processing - no polling; webhooks trigger workflows instantly
- Version control - workflows can be exported and managed via the Pipedream CLI
- Serverless execution - no infrastructure to manage
Common Use Cases
- Process Instagram leads with custom Node.js/Python logic
- Enrich lead data with external APIs before saving to a CRM
- Build conditional routing based on flow responses
- Sync leads to Google Sheets, Airtable, or a database
- Send formatted Slack/Discord/email notifications
- Call the InstantDM API to send DMs based on external triggers
What You'll Need
| Requirement | Details |
|---|---|
| InstantDM account | Trendsetter, Trendsetter Pro, or any Multi plan (API access required) |
| Pipedream account | Free plan works for testing and moderate volume |
| InstantDM API key | Found at Settings → API in your InstantDM dashboard |
Step 1: Generate an API Key in InstantDM
- Log in to app.instantdm.com.
- Navigate to Settings → API in the left sidebar.
- Copy your API Key.
- Keep this page open - you'll paste your Pipedream webhook URL here shortly.
Step 2: Create a Pipedream Workflow with Webhook Trigger
- Log in to pipedream.com and click New Workflow.
- For the trigger, search for HTTP / Webhook and select New Requests.
- Pipedream generates a unique webhook URL (e.g.,
https://eo1234abc.m.pipedream.net). - Copy this URL.
Pipedream webhook URLs are permanent and always active - no need to toggle between test and production modes.
Step 3: Configure Webhook URL in InstantDM
- Go to Settings → API in InstantDM.
- Paste the Pipedream webhook URL into the Webhook URL field.
- Select which events to forward:
| Event | When It Fires |
|---|---|
comment | Someone comments on your post |
dm_received | Someone sends you a DM |
postback | User clicks a button in your DM flow |
question_answered | User answers a question node in a flow |
flow_completed | User reaches the end of a flow |
- Click Save.
Step 4: Test and Inspect the Webhook Data
- In Pipedream, your workflow is already listening (no "Run once" needed).
- In InstantDM, click Send Test Webhook on the Settings → API page.
- Go back to Pipedream - the trigger step shows the received payload.
- Click on the event to inspect the data structure.
Example Payload
{
"event": "flow_completed",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"instagram_user_id": "17841400123456789",
"username": "johndoe",
"flow_name": "Lead Capture Flow",
"response_variables": {
"full_name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890",
"interest": "Premium Plan"
}
}
}
Step 5: Add Processing Steps
Pipedream lets you mix code steps and pre-built actions. Here are common patterns:
Option A: Filter by Event Type (Node.js)
Add a Node.js code step:
export default defineComponent({
async run({ steps }) {
const event = steps.trigger.event.body.event;
if (event !== "flow_completed") {
$.flow.exit("Not a flow_completed event");
}
return steps.trigger.event.body.data;
},
});
Option B: Filter by Event Type (Python)
Add a Python code step:
def handler(pd: "pipedream"):
event = pd.steps["trigger"]["event"]["body"]["event"]
if event != "flow_completed":
pd.flow.exit("Not a flow_completed event")
return pd.steps["trigger"]["event"]["body"]["data"]
Option C: Enrich Lead Data
Add a code step that calls an external API to enrich the lead before saving:
export default defineComponent({
async run({ steps }) {
const data = steps.trigger.event.body.data;
const email = data.response_variables?.email;
if (!email) return data;
// Example: look up the lead in your own database
const response = await fetch(`https://your-api.com/leads?email=${encodeURIComponent(email)}`);
const existing = await response.json();
return {
...data,
is_returning_lead: existing.found || false,
previous_interactions: existing.count || 0,
};
},
});
Step 6: Connect to Destinations
After your processing step, add pre-built actions to send data to other services.
Google Sheets - Add a Row
- Click "+" to add a step.
- Search for Google Sheets → Add Single Row.
- Connect your Google account.
- Select your spreadsheet and sheet.
- Map columns:
| Column | Value |
|---|---|
| Name | {{steps.trigger.event.body.data.response_variables.full_name}} |
{{steps.trigger.event.body.data.response_variables.email}} | |
| Phone | {{steps.trigger.event.body.data.response_variables.phone}} |
{{steps.trigger.event.body.data.username}} | |
| Flow | {{steps.trigger.event.body.data.flow_name}} |
| Date | {{steps.trigger.event.body.timestamp}} |
Slack - Send a Message
- Add Slack → Send Message to Channel.
- Connect your Slack workspace.
- Select the channel.
- Set the message:
🎯 New Instagram Lead!
Name: {{steps.trigger.event.body.data.response_variables.full_name}}
Email: {{steps.trigger.event.body.data.response_variables.email}}
Instagram: @{{steps.trigger.event.body.data.username}}
Flow: {{steps.trigger.event.body.data.flow_name}}
HubSpot - Create Contact
- Add HubSpot → Create or Update Contact.
- Connect your HubSpot account.
- Map properties:
| HubSpot Property | Value |
|---|---|
{{steps.trigger.event.body.data.response_variables.email}} | |
| First Name | {{steps.trigger.event.body.data.response_variables.full_name}} |
| Phone | {{steps.trigger.event.body.data.response_variables.phone}} |
Step 7: Send DMs Back via the InstantDM API
Use an HTTP request step to send DMs through InstantDM.
- Add a Node.js code step (or use the HTTP Request action):
export default defineComponent({
async run({ steps }) {
const recipientId = steps.trigger.event.body.data.instagram_user_id;
const response = await fetch("https://api.instantdm.com/api-webhook", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "send_message",
type: "text",
recipient_id: recipientId,
message: "Thanks for your interest! We'll follow up shortly.",
}),
});
return await response.json();
},
});
Tip: Store your API key in Pipedream's Environment Variables (Settings → Environment Variables) and reference it as
process.env.INSTANTDM_API_KEYinstead of hardcoding it.
Example Workflow: Comment Alert with Conditional DM Reply
This workflow sends a Slack alert for every comment and auto-replies via DM if the comment contains "pricing".
Workflow flow: Webhook → Filter (event = comment) → Slack Alert → IF (contains "pricing") → Send DM via API
Node.js Step: Check for Pricing Keyword
export default defineComponent({
async run({ steps }) {
const data = steps.trigger.event.body;
if (data.event !== "comment") {
$.flow.exit("Not a comment event");
}
const commentText = data.data.comment_text.toLowerCase();
return {
...data.data,
wants_pricing: commentText.includes("pricing") || commentText.includes("price"),
};
},
});
Conditional DM Reply Step
export default defineComponent({
async run({ steps }) {
if (!steps.check_keyword.$return_value.wants_pricing) {
$.flow.exit("No pricing keyword found");
}
const recipientId = steps.check_keyword.$return_value.instagram_user_id;
const response = 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: "buttons",
recipient_id: recipientId,
message: "Hey! Here's our pricing info 👇",
buttons: [
{ "title": "View Pricing", "url": "https://yoursite.com/pricing" },
{ "title": "Book a Call", "url": "https://calendly.com/yourname" },
],
}),
});
return await response.json();
},
});
Testing Your Workflow
- Deploy the workflow by clicking the green Deploy button.
- Trigger a test event - comment on your Instagram post or click Send Test Webhook in InstantDM.
- Check the execution log - click on the workflow run to see each step's input/output.
- Verify destinations - check Slack, Google Sheets, or your CRM for the data.
Debugging Tips
- Click any step to see its input and output data.
- Use
console.log()in Node.js steps - output appears in the step's logs. - Use
print()in Python steps for the same purpose. - Check the Errors tab in your Pipedream dashboard for failed executions.
Troubleshooting
| Issue | Solution |
|---|---|
| Webhook not receiving data | Verify the webhook URL is saved in InstantDM. Pipedream URLs are always active - no need to toggle anything. |
$.flow.exit not stopping the workflow | Make sure you're using $.flow.exit() (not return) to stop execution in a code step. |
| Data fields undefined | Check the path. Pipedream wraps the body in steps.trigger.event.body. Use steps.trigger.event.body.data.username, not steps.trigger.data.username. |
| API key exposed in code | Move it to Pipedream Environment Variables and reference as process.env.INSTANTDM_API_KEY. |
| HTTP request returning 401 | Verify the API key and ensure the Authorization header uses Bearer prefix (with a space). |
| Workflow not running after deploy | Check that the workflow is active (green toggle in the top-right). |
| Hitting free tier limits | The free plan allows 10,000 invocations/month. Upgrade or add early exit conditions to reduce unnecessary invocations. |
Frequently Asked Questions
How does Pipedream's free tier work with InstantDM?
Each webhook event from InstantDM counts as one invocation. The free plan gives you 10,000 invocations/month. If your workflow has 5 steps, it still counts as 1 invocation (not 5). This is different from Make.com where each module counts as a separate operation.
Can I use Python instead of Node.js?
Yes. Every code step in Pipedream can be Node.js, Python, Go, or Bash. You can even mix languages within the same workflow.
How does Pipedream compare to Make.com for InstantDM?
Pipedream is better for developers who want to write custom logic. Make.com is better for visual, no-code workflows. Pipedream's free tier is more generous (10K invocations vs 1K operations), and code steps give you unlimited flexibility. Make.com has a larger library of pre-built app integrations with visual configuration.
Can I version control my Pipedream workflows?
Yes. The Pipedream CLI (pd) lets you push and pull workflows, making it possible to store them in Git. This is useful for teams that want code review on automation changes.
What's Next
- Set up n8n if you want a fully self-hosted alternative.
- Connect to Salesforce CRM for enterprise lead management.
- Read the Zapier guide if you prefer a no-code approach.
- Build a Custom AI Agent to auto-respond to DMs with AI.
- Explore the full API docs at instantdm.com/instagram-api-docs.