Developers

DMpop API

Create comment-to-DM campaigns from your own tools. A content pipeline can publish a reel and switch on its DM automation in the same step.

Authentication

Create a key in Settings → API keys. It is shown once, so store it somewhere safe. Send it with every request:

Authorization: Bearer dmp_your_key_here

Base URL: https://app.dmpop.com/api/v1. Requests and responses are JSON. Each key can make 60 requests a minute. A key acts for its whole workspace, so treat it like a password.

Typical pipeline

Either create the campaign before you post, and DMpop attaches it to the next reel within about five minutes of it going live:

curl -X POST https://app.dmpop.com/api/v1/campaigns \
  -H "Authorization: Bearer $DMPOP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Hooks guide reel",
    "nextReel": true,
    "keywords": ["GUIDE"],
    "message": "Hey {username}, here is the guide you asked for.",
    "link": "https://example.com/guide",
    "buttonLabel": "Get the guide",
    "publicReplies": ["Sent you a DM!"]
  }'

Or, if your pipeline publishes first and knows the post ID, attach it directly with "postId": "1789..." instead of nextReel.

Use with Claude, Codex or Cursor (MCP)

DMpop is also an MCP server, so an AI assistant can list your posts and create, pause or delete campaigns when you ask it to. Use the same API key.

Claude Code

claude mcp add --transport http dmpop https://app.dmpop.com/mcp \
  --header "Authorization: Bearer dmp_your_key_here"

Codex (~/.codex/config.toml)

[mcp_servers.dmpop]
url = "https://app.dmpop.com/mcp"
bearer_token_env_var = "DMPOP_API_KEY"

Cursor and other clients (mcp.json)

{
  "mcpServers": {
    "dmpop": {
      "url": "https://app.dmpop.com/mcp",
      "headers": { "Authorization": "Bearer dmp_your_key_here" }
    }
  }
}

Tools: list_instagram_accounts, list_recent_posts, list_campaigns, get_campaign, create_campaign, update_campaign and delete_campaign. Then just ask, for example: “Set up a DMpop campaign on my next reel: when people comment GUIDE, DM them https://example.com/guide.”

Endpoints

  • GET /accounts: connected Instagram accounts.
  • GET /posts?accountId=&limit=12: recent posts and reels with their IDs (up to 25).
  • GET /campaigns: all campaigns with their numbers.
  • POST /campaigns: create a campaign.
  • GET /campaigns/{id}: one campaign with sends, skips, failures, clicks and click rate.
  • PATCH /campaigns/{id}: change any field. Only the fields you send change. Send {"active": false} to pause.
  • DELETE /campaigns/{id}: delete a campaign.

Campaign fields

FieldTypeWhat it does
namestring, requiredA label for the campaign.
messagestring, requiredThe DM text. Use {username} for the person's handle and {link} to place the tracked link in the text.
nextReelbooleanAttach to the next reel you publish. Use this when the campaign is created before posting.
postIdstringAttach to an existing post or reel. Get IDs from GET /posts.
anyPostbooleanRun on every post. Exactly one of nextReel, postId or anyPost is needed.
keywordsstring[]Up to 10 trigger words, e.g. ["GUIDE"]. Needed unless anyWord is true.
anyWordbooleanReply to every comment, whatever it says.
wholeWordbooleanMatch whole words only. Default true.
linkURLThe link to send. It becomes a tracked link so clicks are counted.
buttonLabelstring, max 20Text on the link button, e.g. "Get the guide".
secondLink, secondButtonLabelURL, stringAn optional second link button.
publicRepliesstring[]Public replies posted under the comment. One is picked at random each time.
openingMessage, openingButtonLabelstring, stringSend a short opener with a button first; the link follows when it is tapped.
requireFollow, followPrompt, followButtonLabelboolean, string, stringOnly send the link to people who follow you.
followUpMessage, followUpDelayMinutesstring, 0 to 1440An optional later message.
alsoOnDmsbooleanAlso reply when someone sends the keyword in a DM or Story reply.
accountIdstringWhich connected account to use. Defaults to the most recently connected one.
activebooleanDefault true. Set false to create the campaign paused.

Responses and errors

Successful calls return { "data": ... }. A campaign looks like this:

{
  "data": {
    "id": "cmv...",
    "name": "Hooks guide reel",
    "active": true,
    "trigger": "next_reel",
    "postId": null,
    "keywords": ["GUIDE"],
    "links": [{ "url": "https://example.com/guide", "label": null, "trackedUrl": "https://app.dmpop.com/r/..." }],
    "stats": { "sent": 0, "skipped": 0, "failed": 0, "clicks": 0, "ctr": 0 }
  }
}

Errors return { "error": { "message": "...", "details": ... } } with a status code: 400 for an invalid request, 401 for a missing or revoked key, 404 for something that doesn't exist, 429 when the rate limit is hit. Unknown fields are rejected, so typos don't pass silently.

Questions: hello@dmpop.com. Campaigns made through the API follow the same rules as the dashboard, including Instagram's limits and our Terms.