EasyDM API
Send Instagram DMs, manage comment automations, read leads and get webhooks with the EasyDM REST API.
Authentication
Create a key in your dashboard under Developer API and send it as a bearer token. Keep it secret — use it from your server only.
curl https://easydm.app/api/public/v1/accounts \
-H "Authorization: Bearer edm_live_xxx"const res = await fetch("https://easydm.app/api/public/v1/dms", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.EASYDM_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ account_id, recipient_igsid, text: "Hello!" }),
});
const { data, error } = await res.json();Endpoints
Base URL: https://easydm.app/api/public/v1
/accounts/connectLet a user connect their Instagram account from your website. Send { redirect_url }, open the returned url; after login they return to redirect_url with ?status=connected&account_id=...&username=... (or status=error&message=...).
{ "url": "https://www.instagram.com/oauth/authorize?..." }/accountsList your connected Instagram accounts.
{ "data": [{ "id": "uuid", "username": "mybrand", "ig_user_id": "1784...", "connected": true }] }/dmsSend a DM. Instagram only allows this within 24h of the person's last message to you.
{ "account_id": "uuid", "recipient_igsid": "1234567890", "text": "Hi! Here's your link", "buttons": [{ "title": "Open", "url": "https://..." }] }{ "data": { "id": "uuid", "message_id": "aWdf...", "status": "sent" } }/automationsList automations.
{ "data": [{ "id": "uuid", "name": "...", "keywords": ["link"], "is_active": true }] }/automationsCreate a comment-to-DM automation.
{ "ig_account_id": "uuid", "keywords": ["link"], "dm_template": "Here you go!", "link_url": "https://...", "reply_comment": true, "media_id": null }{ "data": { "id": "uuid", ... } }/automations/:idUpdate or pause (is_active: false) an automation.
{ "is_active": false }{ "data": { "id": "uuid", "is_active": false } }/automations/:idDelete an automation.
{ "data": { "id": "uuid", "deleted": true } }/leads?since=2026-01-01&limit=50Captured leads, newest first (max 200).
{ "data": [{ "id": "uuid", "username": "jane", "email": "jane@x.com", "phone": null, "created_at": "..." }] }/stats?days=7DMs sent, comments, leads and active automations (1–90 days).
{ "data": { "dms_sent": 120, "comments": 300, "leads": 42, ... } }Webhooks
Add an https URL in the dashboard and pick events: lead.created, comment.received, dm.sent. We POST JSON within about a minute and retry up to 3 times. Verify the X-EasyDM-Signature header (HMAC-SHA256 of the raw body with your webhook secret).
{ "id": "evt_uuid", "event": "lead.created", "created_at": "...", "data": { "username": "jane", "email": "jane@x.com" } }import crypto from "node:crypto";
const expected = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET).update(rawBody).digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-easydm-signature"]));Errors & limits
{ "error": { "code": "rate_limited", "message": "..." } }400 invalid_request— bad input401 invalid_key— missing, wrong or revoked key402 plan_required— no active API plan404 not_found·422 outside_window— Instagram 24h rule429 rate_limited/dm_limit— 5,000 calls/day; DMs also follow Instagram safety limits (190/hour)