Recevez les DMs Instagram sur votre serveur — configuration officielle du webhook Messaging API, identifiant IGID, schémas de payload pour DMs, mentions de stories et réactions, code Node.js
Dans ce guide : Pourquoi uniquement l'API officielle · Prérequis du compte · Permissions requises · L'IGID expliqué · Étapes de configuration du webhook · Schémas de tous les types d'événements · Mentions et réponses de stories · Réactions · Répondre avec la Send API · Format normalisé SocialHook

Pourquoi l'API officielle — et uniquement l'API officielle

La plupart des tutoriels « d'automatisation des DM Instagram » utilisent des méthodes non officielles : automatisation du navigateur, scraping de tokens de session, outils tiers d'automatisation qui contournent l'API d'Instagram. Tous violent les Conditions d'utilisation d'Instagram. Instagram détecte activement et bannit les comptes qui les utilisent — parfois définitivement, souvent sans avertissement ni recours possible.

L'API Instagram Messaging officielle est la seule approche qui soit :

  • Approuvée par Meta et conforme aux ToS d'Instagram
  • Éligible pour un usage professionnel à grande échelle (jusqu'à 1 000 appels API par heure par utilisateur)
  • Couverte par le SLA de Meta et la fiabilité de son infrastructure
  • Sûre pour le compte Instagram de votre entreprise sur le long terme

Ce guide couvre exclusivement l'API Instagram Messaging officielle de Meta Graph API v21.0.

Prérequis du compte : ce qu'il vous faut avant d'écrire du code

L'API Instagram Messaging a des exigences de compte plus strictes que l'API Messenger. Les trois conditions suivantes doivent être réunies :

  1. Compte Instagram Professional : Votre compte Instagram doit être converti en compte Business ou Creator (pas en compte personnel). Faites-le dans l'application Instagram → Paramètres → Compte → Passer à un compte Professional. Les comptes Creator ont des fonctionnalités légèrement différentes des comptes Business — pour l'automatisation des DM, les deux fonctionnent.
  2. Page Facebook liée : Votre compte Instagram Professional doit être connecté à une Page Facebook que vous possédez et administrez. C'est obligatoire — l'API Instagram Messaging s'authentifie via l'infrastructure de Facebook. Connectez-la dans Paramètres Instagram → Compte → Comptes liés → Facebook.
  3. Application Facebook Developer : Une application Facebook avec le produit Instagram ajouté. Votre compte Instagram Business doit être lié dans les paramètres Instagram de l'application. C'est là que vous générez les tokens d'accès et enregistrez votre webhook.
Les comptes Instagram personnels ne peuvent pas utiliser la Messaging API. Si vous travaillez avec un compte personnel, vous devez d'abord le convertir en Professional. C'est gratuit et réversible — passer à Professional ne change pas votre contenu, vos abonnés ni votre workflow de publication. Cela ajoute uniquement des fonctionnalités business, dont l'accès à l'API.

Permissions requises

PermissionRequise ?Ce qu'elle autorise
instagram_manage_messages Requise Recevoir les événements webhook DM, envoyer des messages au nom du compte Instagram. C'est la permission centrale pour tout ce qui figure dans ce guide.
pages_messaging Requise S'abonner aux et recevoir les événements webhook via la Page Facebook liée. Sans elle, les webhooks DM d'Instagram ne se déclenchent pas.
pages_read_engagement Requise Lire les informations du compte Instagram Business nécessaires à l'abonnement webhook et à la validation du token.
instagram_manage_insights Optionnelle Accéder aux statistiques et analyses du compte Instagram. Non nécessaire pour la simple réception/envoi de DM.
instagram_basic Optionnelle Lire les informations de profil basiques du compte Instagram connecté. Utile pour la vérification de la configuration du profil.
App Review obligatoire pour la production. Pendant le développement, les permissions fonctionnent pour les comptes ajoutés en tant que Test Users dans les paramètres de votre application. Pour la production (réception de DM de vrais clients qui n'ont pas été ajoutés comme test users), vous devez soumettre une demande d'App Review. La revue demande une description de votre cas d'usage et prend généralement 5 à 10 jours ouvrables. Préparez une description claire du cas d'usage et un enregistrement d'écran montrant votre bot en action.

Instagram-Scoped ID (IGSID) : comment Instagram identifie les utilisateurs

Lorsqu'un utilisateur Instagram envoie un DM à votre compte business, Instagram l'identifie auprès de votre webhook avec son IGSID (Instagram-Scoped ID) — une chaîne numérique opaque unique, spécifique à votre compte Instagram Business.

Faits clés sur les IGSID :

  • Spécifique au scope. Le même utilisateur a un IGSID différent pour chaque compte Instagram Business avec lequel il échange. L'IGSID de l'utilisateur A sur votre compte est différent de son IGSID sur le compte d'un concurrent — la confidentialité par conception.
  • Différent du PSID. Même si vous exploitez également une Page Facebook connectée au même compte Instagram, le PSID Facebook Messenger de l'utilisateur et son IGSID Instagram sont des identifiants distincts. Ne les mélangez pas dans votre base de données sans une étiquette de type.
  • Stockez en chaîne, pas en entier. Les IGSID sont des chaînes numériques qui peuvent dépasser le Number.MAX_SAFE_INTEGER de JavaScript. Stockez toujours en VARCHAR/TEXT, jamais en INT ou BIGINT. Convertir vers un nombre JavaScript fait perdre la précision sur les derniers chiffres.
  • Apparaît à : entry[0].messaging[0].sender.id dans le payload webhook brut — au même emplacement que les PSID Messenger.
Créez votre application Facebook et connectez Instagram
  1. Rendez-vous sur developers.facebook.com → My Apps → Create App → choisissez le type « Business »
  2. Ajoutez le produit Instagram à votre application depuis le menu Products
  3. Sous Instagram → Settings, ajoutez votre compte Instagram Business
  4. Générez un Page Access Token : Graph API Explorer → sélectionnez votre application → sélectionnez votre Page Facebook → Generate Token → accordez instagram_manage_messages + pages_messaging + pages_read_engagement
  5. Copiez votre Instagram Business Account ID (l'identifiant numérique, pas votre nom d'utilisateur) — trouvez-le dans Graph API Explorer en interrogeant GET /me?fields=id,instagram_business_account
  6. Copiez votre App Secret depuis Settings → Basic
Shell — project setup
mkdir instagram-dm-bot && cd instagram-dm-bot npm init -y npm install express dotenv cat > .env << EOF IG_PAGE_TOKEN=your_page_access_token_here IG_VERIFY_TOKEN=your_custom_verify_secret IG_APP_SECRET=your_app_secret IG_BUSINESS_ID=your_instagram_business_account_id PORT=3000 EOF # Start ngrok for local webhook testing ngrok http 3000
Endpoint de vérification du webhook

Le challenge de vérification est identique à Facebook Messenger — Instagram utilise le même schéma hub.challenge :

Node.js + Express
index.js
require('dotenv').config(); const express = require('express'); const crypto = require('crypto'); const app = express(); // MUST use express.raw() for HMAC verification on webhook route app.use('/webhook', express.raw({ type: 'application/json' })); app.use(express.json()); // GET /webhook — Instagram verification challenge (same as Messenger) app.get('/webhook', (req, res) => { const mode = req.query['hub.mode']; const token = req.query['hub.verify_token']; const challenge = req.query['hub.challenge']; if (mode === 'subscribe' && token === process.env.IG_VERIFY_TOKEN) { console.log('✓ Instagram webhook verified'); return res.status(200).send(challenge); } res.sendStatus(403); }); app.listen(process.env.PORT || 3000);
Python (Flask)
app.py
import os, hmac, hashlib, json from flask import Flask, request, jsonify app = Flask(__name__) @app.route("/webhook", methods=["GET"]) def verify_webhook(): mode = request.args.get("hub.mode") token = request.args.get("hub.verify_token") challenge = request.args.get("hub.challenge") if mode == "subscribe" and token == os.environ["IG_VERIFY_TOKEN"]: return challenge, 200 return "Forbidden", 403

Après avoir lancé votre serveur, enregistrez le webhook dans le Facebook Developer Dashboard : App → Instagram → Webhooks → Add Callback URL. Saisissez votre URL ngrok + /webhook et votre verify token. Abonnez-vous au champ messages — c'est l'abonnement clé pour les DMs Instagram.

Vérification de signature HMAC-SHA256

Instagram utilise le même header X-Hub-Signature-256 et le même schéma HMAC que Facebook Messenger. Le même middleware de vérification fonctionne pour les deux :

Node.js — HMAC middleware (same as Messenger)
verifySignature.js
const crypto = require('crypto'); function verifyInstagramSignature(req, res, next) { const signature = req.headers['x-hub-signature-256']; if (!signature) return res.sendStatus(401); const hash = crypto .createHmac('sha256', process.env.IG_APP_SECRET) .update(req.body) .digest('hex'); const expected = Buffer.from(signature.split('=')[1], 'hex'); const computed = Buffer.from(hash, 'hex'); if (expected.length !== computed.length || !crypto.timingSafeEqual(expected, computed)) { return res.sendStatus(401); } req.body = JSON.parse(req.body.toString('utf8')); next(); } module.exports = { verifyInstagramSignature };
Handler complet d'événement POST webhook
Node.js — full Instagram webhook POST handler
webhook.js
const { verifyInstagramSignature } = require('./verifySignature'); app.post('/webhook', verifyInstagramSignature, async (req, res) => { res.sendStatus(200); // acknowledge immediately const body = req.body; // Instagram DMs arrive with object: "instagram" // (contrast: Messenger uses object: "page") if (body.object !== 'instagram') return; for (const entry of body.entry) { const igBusinessId = entry.id; // your Instagram Business Account ID for (const event of (entry.messaging || [])) { const igsid = event.sender.id; // user's IGSID — store as string if (event.message) { const { text, attachments, mid, reply_to } = event.message; if (reply_to?.story) { // User replied to your story await handleStoryReply(igsid, reply_to.story, text); } else if (attachments) { // Image, video, audio, sticker, or share for (const att of attachments) { await handleAttachment(igsid, att); } } else if (text) { // Standard text DM await handleTextDM(igsid, text, mid); } } else if (event.reaction) { // User reacted to one of your messages const { reaction, action, mid } = event.reaction; await handleReaction(igsid, action, reaction, mid); // action: 'react' | 'unreact' } else if (event.read) { // User read your messages await handleRead(igsid, event.read.mid); } else if (event.referral) { // User arrived via story mention or ad CTA await handleReferral(igsid, event.referral); } } } });
Python (Flask)
app.py
@app.route("/webhook", methods=["POST"]) def receive_webhook(): # Verify HMAC signature sig = request.headers.get("X-Hub-Signature-256", "") expected = hmac.new( os.environ["IG_APP_SECRET"].encode(), request.data, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(sig, f"sha256={expected}"): return "Forbidden", 401 body = request.get_json() if body.get("object") != "instagram": return "OK", 200 for entry in body.get("entry", []): for event in entry.get("messaging", []): igsid = event["sender"]["id"] # IGSID — store as string msg = event.get("message") react = event.get("reaction") if msg: reply_to = msg.get("reply_to", {}) if reply_to.get("story"): handle_story_reply(igsid, reply_to["story"], msg.get("text")) elif msg.get("text"): handle_text_dm(igsid, msg["text"]) elif msg.get("attachments"): handle_attachment(igsid, msg["attachments"]) elif react: handle_reaction(igsid, react["action"], react.get("reaction")) return "OK", 200

Tous les schémas d'événements DM Instagram

DM texte
messages
event.message.text
Message texte standard d'un utilisateur. Le type d'événement le plus courant. Contient le corps du texte et un identifiant de message (mid) que vous pouvez utiliser pour les accusés de lecture et les réactions.
Image / Vidéo / Audio
attachments
event.message.attachments
Média envoyé dans un DM. Chaque pièce jointe a un type (image, video, audio, file) et un payload.url pour le téléchargement. Les URLs sont temporaires — téléchargez immédiatement.
Réponse à une story
reply_to.story
event.message.reply_to.story
L'utilisateur a répondu à l'une de vos Stories Instagram. Contient l'identifiant de la story et l'URL CDN du média de la story. Inclut également le texte de réponse de l'utilisateur dans event.message.text.
Sticker
attachments
event.message.attachments[0].type === 'story_mention'
L'utilisateur a envoyé un sticker ou une réaction cœur/like (sous forme de sticker). Le type de pièce jointe est sticker. Le sticker_id identifie le sticker spécifique utilisé.
Réaction emoji
reaction
event.reaction.action
L'utilisateur a réagi (ou retiré sa réaction) à l'un de vos messages. action vaut « react » ou « unreact ». reaction est le caractère emoji. mid est l'identifiant du message auquel il a réagi.
Mention dans une story
referral
event.referral.source === 'STORY_MENTION'
L'utilisateur a mentionné votre compte dans sa Story et vous a ensuite envoyé un DM. Arrive comme événement referral avec source : « STORY_MENTION ». L'URL de la story de l'utilisateur se trouve dans event.referral.story.url.

Le JSON exact pour les trois types d'événements les plus courants :

Raw webhook payloads — all key event types
// ── Text DM ───────────────────────────────────────────────────────────── { "object": "instagram", // CRITICAL: "instagram" not "page" like Messenger "entry": [{ "id": "987654321098765", // your Instagram Business Account ID "messaging": [{ "sender": { "id": "12345678901234" }, // user's IGSID — store as string "recipient": { "id": "987654321098765" }, // your IG Business Account ID "timestamp": 1747231892, "message": { "mid": "aWdtc2c...", "text": "Hey, do you ship internationally?" } }] }] } // ── Story Reply ───────────────────────────────────────────────────────── { "message": { "mid": "aWdtc2c...", "text": "Wow, this looks amazing!", // the user's reply text "reply_to": { "story": { "id": "17893310459840806", // story ID they replied to "url": "https://lookaside.fbsbx.com/..." // story media URL (CDN) } } } } // ── Emoji Reaction ────────────────────────────────────────────────────── { "reaction": { "action": "react", // 'react' | 'unreact' "reaction": "❤️", // the emoji character "mid": "aWdtc2c..." // which of your messages they reacted to } }

Mentions dans les stories : quand les utilisateurs mettent votre compte en avant

Lorsqu'un utilisateur mentionne votre compte Instagram Business dans sa Story (en vous taguant), Instagram déclenche un événement referral vers votre webhook. C'est un signal à forte valeur — l'utilisateur recommande votre marque à ses abonnés et attend souvent que vous réagissiez (lui envoyer un DM, reposter sa story, etc.).

Story mention event schema
{ "sender": { "id": "USER_IGSID" }, "recipient": { "id": "YOUR_IG_BUSINESS_ID" }, "timestamp": 1747231892, "referral": { // present for story mentions "ref": "STORY_MENTION", // your tracking string (if set) "source": "STORY_MENTION", "type": "OPEN_THREAD", "story": { "id": "17893310459840806", // story ID from the user's account "url": "https://lookaside...", // story media URL (CDN, may expire) "mention": { "page_id": "YOUR_IG_BUSINESS_ID" // confirms it's your account mentioned } } }, "message": { // often empty for pure story mentions "mid": "aWdtc2c..." } } // Subscribe to messaging_referrals webhook field to receive story mentions // WITHOUT this subscription, story mentions never arrive at your webhook

Envoyer des réponses avec la Send API d'Instagram

La Send API d'Instagram utilise la même URL de base que Messenger mais avec un endpoint différent — votre Instagram Business Account ID à la place de /me :

Node.js — Instagram Send API
sendDM.js
const GRAPH = 'https://graph.facebook.com/v21.0'; const IG_BIZ_ID = process.env.IG_BUSINESS_ID; // numeric IG Business Account ID const TOKEN = process.env.IG_PAGE_TOKEN; async function sendInstagramDM(igsid, messageText) { // NOTE: endpoint uses IG_BUSINESS_ID, NOT /me (contrast: Messenger uses /me) const res = await fetch( `${GRAPH}/${IG_BIZ_ID}/messages?access_token=${TOKEN}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ recipient: { id: igsid }, // user's IGSID message: { text: messageText }, }), } ); if (!res.ok) { const err = await res.json(); throw new Error(`Instagram DM send failed: ${err.error?.message}`); } return await res.json(); // { recipient_id: igsid, message_id: "..." } } // Usage await sendInstagramDM('12345678901234', 'Thanks for reaching out! 🙏');
Python — Instagram Send API
send_dm.py
import os, requests GRAPH = "https://graph.facebook.com/v21.0" IG_BIZ_ID = os.environ["IG_BUSINESS_ID"] # numeric IG Business Account ID TOKEN = os.environ["IG_PAGE_TOKEN"] def send_instagram_dm(igsid: str, text: str) -> dict: # NOTE: endpoint uses IG_BIZ_ID not /me res = requests.post( f"{GRAPH}/{IG_BIZ_ID}/messages", params={ "access_token": TOKEN }, json={ "recipient": { "id": igsid }, "message": { "text": text }, } ) res.raise_for_status() return res.json()

SocialHook : des DMs Instagram pré-parsés en format normalisé

Lorsque vous connectez votre compte Instagram à SocialHook, tout le pipeline entrant — vérification HMAC, parsing de object: "instagram", extraction de l'IGSID, détection du type d'événement — est géré avant que l'événement n'atteigne votre serveur. Vous recevez :

Questions fréquentes

Quelles permissions faut-il pour l'API Instagram Messaging ?
Trois sont requises : instagram_manage_messages (recevoir/envoyer des DM), pages_messaging (s'abonner aux webhooks via la Page liée) et pages_read_engagement (lire les informations du compte). Pendant le développement, elles fonctionnent pour les comptes ajoutés en tant que test users dans les paramètres de votre application. Pour la production (vrais DM clients), vous devez soumettre les trois permissions à l'App Review de Meta.
Qu'est-ce qu'un IGSID et en quoi diffère-t-il d'un PSID Facebook ?
Un IGSID (Instagram-Scoped ID) est l'identifiant unique d'un utilisateur Instagram dans le contexte de votre compte Instagram Business spécifique — analogue au PSID pour Messenger. Un PSID identifie un utilisateur sur une Page Facebook ; un IGSID identifie le même utilisateur sur votre compte Instagram. Ce sont des identifiants distincts même si votre compte Instagram et votre Page Facebook sont liés. Stockez toujours les IGSID en chaînes (VARCHAR) — ils peuvent dépasser le Number.MAX_SAFE_INTEGER de JavaScript.
En quoi l'endpoint de la Send API Instagram diffère-t-il de Facebook Messenger ?
Messenger : POST /me/messages (où « me » résout vers votre Page). Instagram : POST /{IG_BUSINESS_ID}/messages (où IG_BUSINESS_ID est l'identifiant numérique de votre compte Instagram Business, pas votre nom d'utilisateur). Les deux utilisent la même URL de base et le même Page Access Token. La structure du corps du message est identique — recipient.id prend l'IGSID, message.text contient votre réponse.
Comment recevoir les mentions de stories dans mon webhook Instagram ?
Vous devez vous abonner au champ webhook messaging_referrals en plus de messages. Quand un utilisateur mentionne votre compte dans sa Story, Instagram déclenche un événement referral avec source: "STORY_MENTION" et une URL de story dans le payload. L'événement vous permet de répondre à l'utilisateur en DM (dans la fenêtre de 24 heures) pour le remercier, demander une autorisation de repost ou offrir une remise.
Puis-je recevoir des DM Instagram de n'importe quel utilisateur ou seulement de mes abonnés ?
Vous pouvez recevoir des DM de tout utilisateur Instagram pouvant envoyer un message à votre compte — pas seulement vos abonnés. Par défaut, les DM des non-abonnés vont dans un dossier « Demandes de message » et ne déclenchent pas de webhooks tant que la demande n'est pas acceptée. Dans vos Paramètres Instagram → Confidentialité → Messages, réglez « Autres personnes sur Instagram » sur « Ne pas demander d'approbation » pour que les DM arrivent immédiatement sur votre webhook. Les comptes business qui activent l'API Message Requests peuvent également traiter les événements de demande de manière programmatique.
En quoi le type d'objet du webhook Instagram diffère-t-il de Facebook Messenger ?
Les webhooks Instagram arrivent avec "object": "instagram" dans l'enveloppe du payload. Les webhooks Messenger arrivent avec "object": "page". C'est le premier champ à vérifier dans votre handler — si vous gérez les deux canaux, branchez sur ce champ. La structure imbriquée du payload (entry[0].messaging[0].sender.id) est la même pour les deux, mais le type d'identifiant utilisateur diffère : IGSID pour Instagram, PSID pour Messenger.

DMs pré-parsés livrés
à votre handler.

Connectez votre compte Instagram Business à SocialHook. Chaque DM, réponse à une story et mention dans une story arrive en JSON normalisé — IGSID extrait, type d'événement étiqueté, HMAC déjà vérifié. Même format que vos événements Messenger et WhatsApp.

Aucune carte bancaire requise · 50 $/mois après l'essai · Instagram + Messenger + WhatsApp