Instagram auto reply comments with DMs
Automate Instagram comment-to-DM funnels using the Upload-Post API. Auto-reply to Instagram comments with private DMs, build lead capture funnels, and set up...
Like a lobster shell, security has layers — review code before you run it.
License
Runtime requirements
SKILL.md
Comment-to-DM Funnel — Upload-Post API
Turn Instagram comments into conversations. This skill lets you monitor comments on a post, detect trigger keywords (semantically, not just exact match), and send personalized private DMs to each commenter automatically.
This is the same mechanism ManyChat, Inro, and every major DM automation tool uses — the official Instagram Private Replies API. Fully compliant with Meta's terms.
Documentation
- Full API docs: https://docs.upload-post.com
- LLM-friendly reference: https://docs.upload-post.com/llm.txt
Authentication
All requests require an API key:
Authorization: Apikey YOUR_API_KEY
Base URL: https://api.upload-post.com/api
The user parameter is the profile name (not username) from the Upload-Post dashboard.
How the Funnel Works
The typical flow a creator wants:
- They post a Reel saying "Comment GUIDE to get my free PDF"
- People comment "GUIDE", "quiero la guía", "send me the guide", etc.
- Each commenter receives a personalized DM with the link
- If someone replies to the DM, the conversation continues
- The creator gets a summary of how many DMs were sent
Your job as an agent is to orchestrate this. There are two modes:
- One-shot: Scan comments right now and send DMs to everyone who already commented. Good for processing a backlog.
- Persistent monitor: Start a background monitor that checks for new comments every X minutes and auto-sends DMs 24/7. This is the "set it and forget it" mode — like ManyChat.
Choose based on what the user asks. If they say "set up a funnel" or "activate monitoring", use persistent. If they say "check comments" or "send DMs to whoever commented", use one-shot.
Endpoints
Persistent Monitor Endpoints
These start a background process on Upload-Post's servers that monitors comments and sends DMs automatically. No need for the agent to stay running.
Start Monitor
curl -X POST "https://api.upload-post.com/api/uploadposts/autodms/start" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"post_url": "https://www.instagram.com/p/ABC123/",
"reply_message": "Hey! Here is your guide: https://example.com/guide",
"profile_username": "PROFILE",
"monitoring_interval": 15,
"trigger_keywords": ["guide", "link"]
}'
Parameters:
post_url(required): The Instagram post URL to monitorreply_message(required): The DM message to send to matching commentersprofile_username(required): Upload-Post profile name with Instagram connectedmonitoring_interval(optional): Minutes between checks. Default: 15. Minimum: 15 (values below 15 are auto-clamped)trigger_keywords(optional but strongly recommended): Array of keywords to filter comments. Only comments containing at least one keyword receive a DM. Case-insensitive and accent-insensitive ("guía" matches "guia"). If omitted, ALL commenters receive a DM — use with caution.
Returns a monitor_id you'll need for managing the monitor.
Limits:
- Maximum 2 new monitors per profile per day
- No duplicate monitors on the same post URL
- Monitors auto-stop after 15 days
- Daily DM limits apply per plan (free: 10 DMs/day, paid: 500 DMs/day). When the limit is reached, the monitor pauses and resumes the next day.
Important: This monitor sends a fixed reply_message — it does not do semantic filtering or personalization. If trigger_keywords is set, it only replies to comments containing those words (case and accent insensitive). If omitted, it replies to ALL commenters. For smart semantic filtering, use one-shot mode instead.
⚠️ Safety: Persistent monitors run on Upload-Post's servers for up to 15 days, even after the agent session ends. Always confirm with the user before starting a monitor, and prefer setting
trigger_keywordsto avoid mass-replying to every commenter. UsePOST /autodms/stoporPOST /autodms/deleteto cancel.
Check Monitor Status
curl "https://api.upload-post.com/api/uploadposts/autodms/status" \
-H "Authorization: Apikey YOUR_KEY"
Returns all active monitors with their status: running, paused, or stopped.
Get Monitor Logs
curl "https://api.upload-post.com/api/uploadposts/autodms/logs?monitor_id=MONITOR_ID" \
-H "Authorization: Apikey YOUR_KEY"
Returns activity logs: when the monitor started, how many DMs sent, any errors.
Pause / Resume / Stop / Delete Monitor
# Pause (keeps config, stops checking)
curl -X POST "https://api.upload-post.com/api/uploadposts/autodms/pause" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"monitor_id": "MONITOR_ID"}'
# Resume a paused monitor
curl -X POST "https://api.upload-post.com/api/uploadposts/autodms/resume" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"monitor_id": "MONITOR_ID"}'
# Stop (deactivates)
curl -X POST "https://api.upload-post.com/api/uploadposts/autodms/stop" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"monitor_id": "MONITOR_ID"}'
# Delete (permanent)
curl -X POST "https://api.upload-post.com/api/uploadposts/autodms/delete" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"monitor_id": "MONITOR_ID"}'
One-Shot Endpoints
These are for scanning comments on-demand and sending DMs with AI-powered semantic matching and personalization.
1. Get Recent Posts
Find the post to monitor.
curl "https://api.upload-post.com/api/uploadposts/media?platform=instagram&user=PROFILE" \
-H "Authorization: Apikey YOUR_KEY"
Returns an array of recent posts with id, caption, permalink, timestamp, and media_type. Use the id field as post_id in subsequent calls.
2. Read Comments
curl "https://api.upload-post.com/api/uploadposts/comments?platform=instagram&user=PROFILE&post_id=POST_ID" \
-H "Authorization: Apikey YOUR_KEY"
You can also use post_url instead of post_id:
curl "https://api.upload-post.com/api/uploadposts/comments?platform=instagram&user=PROFILE&post_url=https://www.instagram.com/p/ABC123/" \
-H "Authorization: Apikey YOUR_KEY"
Rate limit: Once per 10 minutes per post. Plan your polling accordingly — don't call this in a tight loop.
Each comment includes id, text, username, and timestamp.
3. Send Private Reply (the DM)
This is the core action. It sends a DM to the person who wrote the comment, using Meta's official Private Replies API.
curl -X POST "https://api.upload-post.com/api/uploadposts/comments/reply" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "instagram",
"user": "PROFILE",
"comment_id": "COMMENT_ID",
"message": "Hey! Here is your guide: https://example.com/guide"
}'
Constraints you must respect:
- One reply per comment — if you already replied to a comment, the API will reject a second attempt
- The comment must be less than 7 days old
- The post must belong to the authenticated account
- Daily DM limits apply (varies by plan)
4. List DM Conversations
Check for replies to your DMs.
curl "https://api.upload-post.com/api/uploadposts/dms/conversations?platform=instagram&user=PROFILE" \
-H "Authorization: Apikey YOUR_KEY"
Returns conversation threads with participant_id, messages, and metadata.
5. Send Follow-Up DM
Continue a conversation with someone who replied.
curl -X POST "https://api.upload-post.com/api/uploadposts/dms/send" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "instagram",
"user": "PROFILE",
"recipient_id": "USER_ID",
"message": "Glad you liked it! Let me know if you have questions."
}'
24-hour window: You can only send follow-up DMs within 24 hours of the user's last reply. After that, the window closes and you cannot message them until they message you again.
Building the Funnel — Step by Step
When the user asks you to set up a comment funnel, follow these steps:
Step 1: Gather Requirements
Ask the user (if not already provided):
- API key? (needed for all requests)
- Profile name? (the
userparameter — this is the Upload-Post profile name, not their Instagram username. If they don't know it, callGET /uploadposts/meto validate the key. If they have no profiles or no Instagram connected, direct them to https://app.upload-post.com/manage-users to create a profile and connect their Instagram Business account first) - Which post? (URL or they can say "my latest post")
- What keywords trigger the DM? (e.g., "GUIDE", "INFO", "LINK")
- What message to send? (the DM content)
- Persistent or one-shot? (do they want 24/7 monitoring or a one-time scan?)
Step 2: Find the Post
Call GET /uploadposts/media to list recent posts. Match by URL, caption content, or just pick the latest. Confirm with the user which post to monitor.
Path A: Persistent Monitor (24/7)
Use this when the user wants continuous monitoring ("set up a funnel", "activate it", "keep it running").
- Call
POST /uploadposts/autodms/startwith the post URL, reply message, profile, and interval - Save the returned
monitor_idand tell the user - Confirm it's running with
GET /uploadposts/autodms/status - Tell the user how to check results: "Ask me anytime to check the funnel status or logs"
The backend handles everything from here — checking comments, sending DMs, avoiding duplicates, respecting rate limits. The agent doesn't need to stay running.
To check on it later:
GET /uploadposts/autodms/status→ is it running?GET /uploadposts/autodms/logs?monitor_id=X→ how many DMs sent?
To manage it:
POST /uploadposts/autodms/pause→ pause without losing configPOST /uploadposts/autodms/resume→ resume after pausePOST /uploadposts/autodms/stop→ deactivatePOST /uploadposts/autodms/delete→ remove permanently
Trade-off: The persistent monitor sends the same fixed message — no personalization per commenter. Use trigger_keywords to filter so only relevant comments get a DM. Without keywords, it replies to every new comment.
Path B: One-Shot with AI (Smart Filtering)
Use this when the user wants intelligent processing ("check my comments", "DM the ones who asked for the guide", or when the post gets mixed comments — some requesting, some just engaging).
Scan Comments
Call GET /uploadposts/comments with the post ID.
For each comment, decide if it matches the trigger. Use semantic matching, not just exact string comparison:
| Comment | Trigger: "GUIDE" | Match? |
|---|---|---|
| "GUIDE" | Exact match | Yes |
| "guide please" | Contains keyword | Yes |
| "I want the guide!" | Semantic intent | Yes |
| "can you send me the guide?" | Semantic intent | Yes |
| "guía" | Translation | Yes |
| "great post!" | No intent | No |
| "nice guide on the topic" | Ambiguous — talking about the content, not requesting | No |
The key question: is this person requesting the thing the creator offered? Use judgment, not regex.
Send DMs
For each matching comment that hasn't been replied to yet:
-
Personalize the message. Don't send identical copy-paste to everyone. Use their name or reference their comment:
- Generic: "Here's your guide: [link]"
- Better: "Hey @maria! You asked about the guide — here it is: [link]. Let me know if you have any questions!"
-
Call
POST /uploadposts/comments/replywith the personalized message. -
Track which comment IDs you've already replied to (keep a list in your working memory) to avoid duplicate attempts.
Report Results
After processing, tell the user:
- Total comments scanned
- How many matched the trigger
- How many DMs sent successfully
- Any errors (already replied, window expired, rate limit)
Monitor Replies (Optional)
If the user wants follow-up handling:
- Call
GET /uploadposts/dms/conversationsto check for new replies - For each reply, generate a contextual response using the funnel's purpose
- Call
POST /uploadposts/dms/sendto respond - Only send within the 24-hour messaging window
Combining Both Modes
A smart approach: start a persistent monitor for the baseline (everyone gets the DM), then periodically run one-shot scans to check DM conversations and do personalized follow-ups. Tell the user this option if it fits their use case.
Compliance Rules
These are Meta's rules. Breaking them gets the account restricted, not just rate-limited.
What's allowed (you're doing this):
- Sending a private reply to someone who commented on YOUR post — this is the exact use case Meta built the Private Replies API for
- Using the official Instagram Graph API through Upload-Post
- Personalizing messages per commenter
Hard limits:
- 200 DMs per hour per Instagram account (Meta enforces this — the API returns 429)
- 1 private reply per comment (API rejects duplicates)
- 7-day window on comments (older comments can't receive private replies)
- 24-hour window on follow-up DMs (resets each time the user replies)
What would get the account banned (never do this):
- Sending DMs to people who never interacted with the account
- Ignoring rate limit errors and retrying aggressively
- Sending identical spam messages to hundreds of people
Error Handling
| Code | Meaning | What to Do |
|---|---|---|
| 200 | DM sent | Track as success |
| 400 | Bad request | Check parameters — likely missing comment_id or message |
| 401 | Invalid API key | Ask user to check their key |
| 404 | Comment not found | Comment may have been deleted |
| 429 | Rate limit / DM limit reached | Stop sending. Tell the user how many were sent and that the limit was hit |
| 500 | Server error | Retry once, then report to user |
When you hit a 429, stop the entire batch. Don't keep trying. Report to the user: "Sent X DMs successfully. Hit the rate limit — the remaining Y commenters will need to be processed later."
Example Conversation
User: "In my latest Reel I told people to comment CURSO to get info about my course. Set up the funnel to DM them the enrollment link https://mycourse.com/enroll"
Agent workflow:
GET /uploadposts/media?platform=instagram&user=profilename→ find latest ReelGET /uploadposts/comments?platform=instagram&user=profilename&post_id=12345- Analyze each comment for intent to receive the course info
- For each match:
POST /uploadposts/comments/replywith personalized DM - Report: "Found 47 comments. 31 matched the trigger. Sent 31 DMs. 2 had already been replied to. Here's the breakdown..."
Platform Limitation
This skill works on Instagram only. The comments and DM endpoints in the Upload-Post API currently support Instagram exclusively. This is because Meta's Private Replies API is Instagram-specific, and other platforms (TikTok, LinkedIn, X, etc.) don't offer equivalent APIs for comment-to-DM automation.
This is not a limitation of Upload-Post — it's how the social platform APIs work. Instagram is where 90%+ of comment-to-DM funnels run commercially (ManyChat, Inro, etc. are all Instagram-first for this reason).
Tips for Better Funnels
- Short DMs convert better: 1-3 sentences max. Link + brief context. Nobody reads paragraphs in DMs.
- Personalize: Reference their comment or use their display name. "Hey! Here's what you asked for" beats "Dear valued follower."
- One clear CTA: Don't overload the DM. One link, one action.
- Timing matters: The sooner after commenting they get the DM, the higher the open rate. Process comments as soon as the rate limit allows.
- Track what works: Compare DM response rates across different message styles. Iterate.
Files
3 totalComments
Loading comments…
