sent signifie que Meta a accepté le message, pas que le destinataire l’a reçu. Sur Instagram, la livraison est en fin de compte dictée par le paramètre Message requests du destinataire : s’il n’autorise pas les demandes de message de tout le monde, Meta renvoie une réponse de succès et supprime silencieusement le message, ce qui est invisible à chaque couche d’API. Même un DM déclenché par un commentaire et effectivement livré arrive sous forme de demande de message que le destinataire doit accepter (sauf si une conversation existe déjà entre les deux comptes). Voir Automation DM Sent but Not Delivered pour l’explication complète.Fonctionnement
Créer une automatisation
POST /automations avec les déclencheurs et les actions souhaités. L’automatisation est activée immédiatement.Un utilisateur final s'engage
Ayrshare fait la correspondance et lance
Vérifier ce qui a été déclenché
GET /automations/:id/activity retourne le journal d’audit — chaque tentative d’envoi, les résultats par action et toute erreur.Déclencheurs
Vous pouvez attacher jusqu’à 50 déclencheurs à une automatisation. Chaque déclencheur est une union discriminée sur le champtype ; les champs spécifiques au type se trouvent au même niveau. La colonne Plateformes indique où chaque déclencheur est disponible ; consultez Pages Facebook pour ce dont Facebook a besoin.
Règles permanentes avec "all"
Définissez postId (ou storyId) sur la chaîne littérale en minuscules "all" pour déclencher sur chaque publication, reel ou story du compte connecté au lieu d’un contenu spécifique. C’est ce qu’il vous faut pour une règle qui doit continuer à fonctionner à mesure que du nouveau contenu est publié, sans appel d’API par publication :
"all". Une variante telle que "ALL" ou " all" est rejetée avec une erreur de validation plutôt que d’être enregistrée comme un ID de publication qui ne correspondrait jamais.
"all" ne s’étend jamais au-delà du compte connecté — une règle sur un profil ne peut pas se déclencher sur le contenu d’un autre profil. Votre plafond quotidien de DM et les règles d’envoi ancrées à l’engagement s’appliquent exactement comme pour une règle sur une seule publication.
storyId se comporte de la même manière que "all". Préférez "all" — il exprime l’intention explicitement, et l’omission sera retirée dans une version future avec un préavis sur Upcoming API Changes.Pages Facebook
Définissezplatform sur facebook pour exécuter une automatisation sur la Page Facebook liée au profil. Les DM sont envoyés depuis la Page via Messenger.
- Déclencheurs :
dm_keywordetdm_reaction. Les déclencheurs de commentaire et de story sont pour l’instant uniquement Instagram, et une automatisation Facebook qui en utilise un est rejetée avec une erreur de validation. - Messaging : le profil doit avoir Messaging activé pour Facebook, de la même manière que pour envoyer un DM Facebook avec l’API Messages.
- Destinataire :
{{recipient_id}}est l’ID limité à la Page de l’utilisateur (PSID).{{recipient_username}}est vide, car les webhooks Messenger n’incluent pas de nom d’utilisateur.
Actions
Vous pouvez attacher jusqu’à 50 actions à une automatisation. Elles s’exécutent séquentiellement ; chaque résultat est enregistré sur la ligne d’activité.Fenêtre de déduplication par action
Chaque action — quel que soit son type — accepte également un champ optionnel de premier niveaudedupWindowMinutes qui remplace la fenêtre de déduplication par destinataire par défaut de 7 jours pour cette action uniquement.
- Définissez-le à
0pour désactiver entièrement la déduplication pour cette action (typique pourfire_webhook/send_emailoù le destinataire attend chaque événement). - Plafonné à
525600(un an).
Contenu dynamique du message
Par défaut,send_dm envoie le même message à toutes les personnes qui déclenchent la règle. Les placeholders tels que {{recipient_username}} sont la seule partie qui change d’une personne à l’autre. Définissez messageUrl sur l’action et c’est votre propre serveur qui rédige le DM pour chaque personne : chaque fois que la règle correspond, nous demandons à votre point de terminaison quoi dire, puis nous envoyons sa réponse comme DM.
Exemple. Votre règle répond à toute personne qui commente « LINK » sur une publication, et messageUrl pointe vers votre serveur. Lorsque Ava commente « LINK please! » :
- Nous envoyons en
POSTles détails à votremessageUrl: qui a commenté ("recipientUsername": "ava"), ce qu’elle a écrit et sur quelle publication. - Votre serveur rédige une réponse pour Ava, par exemple avec un lien de suivi créé spécialement pour elle, et répond
{ "message": "Hi ava, here's your link: https://example.com/r/12345" }. - Nous envoyons ce texte à Ava comme DM, exactement tel que vous l’avez écrit.
timeoutMs, renvoie une erreur ou renvoie quelque chose que nous ne pouvons pas utiliser, nous envoyons à Ava le message habituel de l’action à la place, afin qu’elle reçoive quand même une réponse.
Ajoutez-le à une action send_dm comme ceci :
messageUrl est l’adresse à laquelle nous demandons le texte. message reste requis et sert de solution de repli : il n’est jamais envoyé à votre serveur, et nous l’envoyons en DM à la place chaque fois que votre serveur ne répond pas à temps, renvoie une erreur ou renvoie quelque chose que nous ne pouvons pas utiliser (voir l’avertissement ci-dessous). timeoutMs est optionnel (3000 par défaut, 5000 maximum).
Ce que nous envoyons à votre point de terminaison. Un POST avec ce corps JSON :
automations, de la même manière : X-Authorization-Content-SHA256 est le HMAC-SHA256 du corps brut, et X-Authorization-Timestamp contient le timeStamp du corps. Le code de vérification que vous utilisez déjà pour nos webhooks fonctionne sans modification. Si un secret est enregistré mais que nous ne pouvons pas le lire à ce moment-là, nous n’envoyons pas le callback non signé ; nous envoyons à la place votre modèle message.
Vers quoi elle peut pointer. messageUrl doit être une adresse HTTPS publique. Une URL qui se résout en adresse privée, de loopback, link-local ou de métadonnées cloud est refusée, et les redirections ne sont pas suivies — une réponse 3xx compte comme un échec. Dans les deux cas, le modèle est envoyé à la place.
Ce que votre point de terminaison renvoie. Renvoyez 200 avec un corps JSON d’au plus 16 Ko, contenant une chaîne message de 1 à 1000 caractères :
{{placeholder}} ne lui est pas appliquée, de sorte qu’un {{ littéral dans votre texte généré parvient au destinataire tel qu’il a été écrit.
timeoutMs vaut 3000 par défaut. Le maximum est 5000 : une valeur supérieure est rejetée avec une erreur de validation lorsque vous créez ou mettez à jour l’automatisation. Il couvre l’ensemble de l’échange, y compris la lecture du corps de votre réponse. Prévoyez-le : le DM est envoyé après la réponse de votre point de terminaison, donc un point de terminaison lent retarde le message.
Vérifiez quel chemin a suivi un déclenchement avec GET /automations/:id/activity. Une entrée send_dm dans actionResults[] contient messageSource dès que le texte du DM a été déterminé, y compris lorsque l’envoi a ensuite échoué. Il est absent lorsque l’action s’est arrêtée avant, par exemple un DM skipped vers votre propre compte ou une action deduplicated :
messageSource indique à partir de quel texte le DM a été construit, et non s’il a été livré. Consultez le status de l’entrée pour cela.
Un repli à lui seul ne fait pas échouer l’action : lorsque le DM du modèle est livré, l’entrée est sent, avec la raison pour laquelle le callback n’a pas été utilisé dans errorDetails. Si le DM du modèle échoue lui aussi, l’entrée est failed et errorDetails donne l’erreur d’envoi suivie de la raison du callback. Surveillez-le : sinon, un callback qui échoue à chaque déclenchement ressemble exactement à un callback qui fonctionne.
Veillez à ce que votre message puisse être envoyé seul. S’il est rendu vide pour un destinataire, par exemple {{recipient_username}} seul sur un déclencheur de DM qui ne fournit pas de nom d’utilisateur, et que le texte de votre callback n’est pas utilisé, aucun DM n’est envoyé et l’action est failed avec la raison dans errorDetails.
Événements webhook
Deux événements sont livrés à l’action webhookautomations que vous enregistrez avec POST /hook/webhook. Les deux portent un champ type — faites votre branchement dessus avant de lire quoi que ce soit d’autre.
automation.completed est désactivé par défaut. Activez-le pour une automatisation en définissant "sendCompletedEvent": true sur son action fire_webhook. Il reste désactivé sinon, de sorte qu’un récepteur conçu pour une charge utile par déclenchement continue d’en recevoir exactement une. automation.triggered n’est pas un enregistrement de chaque correspondance : il n’est envoyé que lorsque fire_webhook lui-même s’exécute, si bien qu’une correspondance qui se termine rate_limited ou deduplicated produit automation.completed seul. Aucun des deux événements n’est envoyé pour une automatisation qui a été désactivée ou supprimée avant que l’envoi ne s’exécute.automation.triggered
activityId est la ligne que retourne GET /automations/:id/activity, ce qui vous permet de joindre les deux exactement plutôt que de faire correspondre recipientId + triggerId + keyword — ce qui est ambigu lorsque plusieurs personnes commentent le même mot-clé en même temps. actionId est l’action fire_webhook qui a envoyé l’événement, et correspond à actionResults[].actionId ; il permet de distinguer deux actions fire_webhook sur la même règle.
Les champs qu’un déclencheur ne renseigne pas valent null plutôt que d’être omis, la forme est donc stable. recipientUsername vaut null pour dm_keyword, dm_reaction et story_reply, car la charge utile de Meta n’en inclut pas. commentId n’est défini que pour comment_keyword et story_comment, postId uniquement pour comment_keyword, et storyId uniquement pour les déclencheurs de story. story_reply n’a pas de keyword. Pour dm_keyword, commentText est le texte du DM ; pour dm_reaction, commentText et keyword sont tous deux l’emoji de la réaction.
automation.completed
Envoyé uniquement lorsque l’automatisation l’active sur son action fire_webhook :
status et chaque actionResults[].status utilisent les mêmes valeurs que le journal d’activité — sent, failed, rate_limited, deduplicated, skipped, auth_error — si bien que dans le cas normal, vous apprenez comment un envoi s’est terminé sans interroger l’API. La livraison de cet événement se fait toutefois au mieux : si le processus s’arrête entre l’enregistrement du résultat et la mise en file d’attente de l’événement, il n’est pas envoyé. Le journal d’activité est la source de vérité ; si vous avez besoin de chaque résultat, réconciliez avec GET /automations/:id/activity pour tout activityId qui n’en a pas signalé un. Un résultat send_dm contient également messageSource, comme dans le journal d’activité : template, callback ou fallback, ce qui vous permet de repérer un messageUrl qui se replie constamment sans interroger l’API. Faites correspondre les résultats à vos actions configurées par actionId, et non par position — deux actions du même type ne se distinguent que de cette façon. actionResults est vide dans trois cas, chacun avec la raison dans le errorDetails de premier niveau lorsqu’il y en a une : rate_limited (votre plafond quotidien a été atteint), deduplicated (chaque action était à l’intérieur de sa fenêtre de dédup), et failed après que l’envoi a été retenté le nombre maximal de fois sans se terminer. Dans ce dernier cas, certaines actions peuvent déjà s’être exécutées, de sorte qu’un DM a pu partir et qu’automation.triggered a pu déjà être envoyé.
La livraison des webhooks est au moins une fois, de sorte que le même événement peut occasionnellement arriver deux fois, et un envoi qui est retenté peut envoyer automation.triggered à nouveau avec un nouveau hookId. Ne dédupliquez jamais sur hookId. Indexez chaque type d’événement séparément, afin que le traitement de l’un ne supprime jamais l’autre : automation.completed sur activityId (chaque activité a un seul résultat), et automation.triggered sur activityId plus actionId (un par action fire_webhook). Les deux événements sont livrés indépendamment, de sorte qu’automation.completed peut occasionnellement arriver avant automation.triggered.
Si aucun webhook n’est enregistré
fire_webhook poste sur l’action automations enregistrée sur le profil, avec repli sur votre Primary Profile. Il n’y a aucun repli vers une autre action telle que messages. Si aucune des deux inscriptions n’existe, automation.triggered n’est pas silencieusement abandonné : l’action est enregistrée sur la ligne d’activité comme failed, avec la raison dans actionResults[].errorDetails. (automation.completed n’a nulle part où aller non plus, et n’est pas enregistré.) Le statut global de l’envoi suit ensuite la précédence habituelle : auth_error si une action a rencontré une erreur d’auth, sinon sent si une action a été acceptée, sinon failed. Le webhook manquant ne compte donc dans les statistiques d’échec de l’automatisation que lorsque rien d’autre sur la règle n’a été envoyé ; lorsqu’une autre action a bien envoyé (et qu’aucune n’a rencontré d’erreur d’auth), l’envoi se termine sent et le webhook en échec n’apparaît que dans actionResults[].
Un résultat fire_webhook de sent signifie que l’événement a été mis en file d’attente pour livraison à votre URL, pas que votre point de terminaison l’a accepté. La livraison est ensuite retentée selon son propre calendrier.
Variables de modèle
send_dm.message, send_email.subject et send_email.message prennent en charge la substitution {{placeholder}}. Les placeholders inconnus sont rejetés au moment de la création/mise à jour (sous forme d’erreur de validation 473) afin qu’une faute de frappe ne laisse jamais fuiter en silence le littéral {{foo}} dans un message destiné au client.
sender_email / recipient_email. Ceux-ci ne sont délibérément pas exposés — votre e-mail de facturation n’a aucune raison légitime d’apparaître dans un DM à un inconnu, et Meta ne fournit pas l’e-mail du destinataire dans les webhooks IG. Éviter ces placeholders empêche la divulgation accidentelle.Limites de débit et plafonds
POST (création) et de la réactivation PUT (active: false → true), faisant apparaître le code d’erreur 470. Besoin d’une limite par profil plus élevée ? Contactez le support pour qu’elle soit augmentée pour votre compte.
Le plafond quotidien de DM s’applique par compte parent Ayrshare, partagé entre tous vos profils, avec un sous-plafond par profil pour qu’un profil très actif ne draine pas tout le quota du compte. Lorsqu’un plafond de DM est atteint, la ligne d’activité enregistre le statut rate_limited et aucun DM n’est envoyé.
La limite de conversations de messagerie s’applique également. send_dm nécessite le module complémentaire Messaging sur le profil, et chaque DM qu’il envoie est compté dans la limite de conversations mensuelle de ce profil, de la même manière qu’un DM que vous envoyez vous-même. Lorsque la limite est atteinte, un send_dm vers un nouveau destinataire n’est pas envoyé et la ligne d’activité enregistre le statut failed, avec le message de limite dans actionResults[].errorDetails. Les DM déclenchés par un commentaire (comment_keyword et story_comment) font exception : ils sont tout de même envoyés lorsque la limite est atteinte, et tout de même comptés.
Plafonds structurels sur une seule automatisation : 1 à 50 déclencheurs, 1 à 50 actions.
Instagram lui-même plafonne les DM à environ 200/heure par compte. Le moteur régule les envois avec une gigue de 20 à 60 secondes pour rester bien en dessous.
Statuts d’activité
Une ligne dansGET /automations/:id/activity porte un status de premier niveau plus un status par action à l’intérieur d’actionResults[] :
pending et in_flight sont transitoires ; tout le reste est terminal.
Lorsqu’une automatisation comporte plus d’une action, le status de premier niveau est dérivé des résultats par action dans cet ordre : auth_error si une action a rencontré une erreur d’auth, puis sent si une action a été acceptée, puis deduplicated si chaque action a été dédupliquée, puis skipped si chaque action a été délibérément supprimée (skipped ou deduplicated), sinon failed. Consultez actionResults[] pour le détail par action.
sent est un accusé d’acceptation par la plateforme, pas un accusé de livraison. Une action send_dm est marquée sent au moment où Meta accepte le message, qu’il parte de votre compte Instagram ou via Messenger depuis votre Page Facebook. L’automatisation enregistre uniquement cette acceptation ; elle ne suit pas la livraison. Instagram n’expose la livraison des messages à aucune API, et la réception effective par le destinataire dépend de son paramètre Instagram Message requests, qu’Ayrshare ne peut ni lire ni influencer. Voir Automation DM Sent but Not Delivered.Codes d’erreur
L’API renvoie deux formes d’erreur :- Erreurs de règle métier portent un
codenuméroté d’automatisation (p. ex.{ "action": "automation", "code": 469, ... }). - Erreurs de validation — tout corps de requête mal formé (champs manquants ou invalides, variables de modèle inconnues, clés non reconnues) — sont retournées comme une seule réponse
473avec un objetdetailsqui liste les champs fautifs.detailsest la sortie du validateur (formErrorsplusfieldErrors). Faites vos branchements surdetails, et non sur un code par condition. DansfieldErrors, les clés sont les champs de premier niveau de la requête (triggers,actions) : un problème à l’intérieur d’une entrée spécifique, comme un déclencheur auquel il manque sonkeywords, est signalé sous ce champ (p. ex.triggers), tandis queformErrorscontient les problèmes de niveau objet tels que les clés non reconnues.
468 n’est renvoyé qu’aux plans
qui n’incluent pas les automatisations.Ce que Meta N’AUTORISE PAS
Quelques capacités fréquemment demandées ne sont pas prises en charge car Meta ne les autorise pas sur l’API publique d’Instagram :- Auto-DM aux nouveaux abonnés. Instagram ne publie pas de webhook de suivi.
- Premiers DM à des inconnus. Meta exige que le destinataire ait interagi en premier (commentaire, réponse, DM, réaction) avant qu’un compte pro puisse lui envoyer un message. Chaque déclencheur pris en charge est ancré à un tel engagement — mais notez qu’être autorisé à envoyer n’est pas la même chose que le message soit livré : le paramètre Instagram Message requests du destinataire peut toujours conduire Meta à accepter puis supprimer silencieusement le message (voir Automation DM Sent but Not Delivered).
- Campagnes de sortie en masse. Les plafonds horaires de DM et les heuristiques anti-abus s’appliquent au niveau de la plateforme.
Utilisation multi-profil
Les points de terminaison respectent l’en-têteprofileKey. Passez la clé d’un profil enfant et l’automatisation est créée/gérée sous ce profil. Les limites de débit se répartissent entre les profils via un sous-plafond par profil afin qu’un profil bavard ne draine pas le quota du compte parent.
FAQ
Puis-je déclencher sur un nouvel abonné ?
Puis-je déclencher sur un nouvel abonné ?
comment_keyword, story_reply, dm_reaction, dm_keyword) est ancré à un tel engagement, ce qui rend l’envoi permissible.Pourquoi une activité indique-t-elle sent alors que le destinataire n'a jamais reçu le DM ?
Pourquoi une activité indique-t-elle sent alors que le destinataire n'a jamais reçu le DM ?
sent signifie que Meta a accepté le message, pas qu’il a été livré. C’est vrai sur Instagram comme sur Facebook (Messenger depuis votre Page) : l’automatisation enregistre uniquement l’acceptation et ne suit pas la livraison. Sur Instagram, la livraison dépend du paramètre Instagram Message requests du destinataire — s’il n’autorise pas les demandes de message de tout le monde, Meta renvoie une réponse de succès et supprime silencieusement le message, sans erreur, webhook ou autre signal sur aucune surface d’API. Un DM déclenché par un commentaire, même livré avec succès, arrive également sous forme de demande de message que le destinataire doit accepter (sauf si une conversation existe déjà). Il s’agit d’une limitation permanente de la plateforme Instagram. Voir Automation DM Sent but Not Delivered.Que se passe-t-il si mon jeton d'accès est invalide lorsqu'une automatisation se déclenche ?
Que se passe-t-il si mon jeton d'accès est invalide lorsqu'une automatisation se déclenche ?
auth_error et le DM n’est pas retenté. Résoudre l’état du compte (reconnecter, sélectionner une Page, ou activer Messaging) permet au prochain engagement correspondant de se déclencher normalement. Cela s’applique uniquement aux véritables défaillances d’identifiants et d’autorisations : si un DM spécifique n’a pas pu être livré pour une autre raison — par exemple le destinataire n’a pas pu être trouvé, ou l’engagement déclencheur provient du compte qui enverrait le DM — la ligne est enregistrée comme failed ou skipped avec la raison dans actionResults[].errorDetails, et reconnecter le compte ne changera pas le résultat.Pourquoi y a-t-il un délai avant l'envoi du DM ?
Pourquoi y a-t-il un délai avant l'envoi du DM ?
fire_webhook et send_email compris — votre webhook arrive 20 à 60 secondes après le commentaire, pas immédiatement. L’horodatage created de la ligne d’activité est le moment où le déclencheur a correspondu ; completedAt est le moment où l’envoi s’est terminé.Les lignes d'activité sont-elles conservées indéfiniment ?
Les lignes d'activité sont-elles conservées indéfiniment ?
GET /automations/:id/activity renvoie les lignes des 30 derniers jours pour des raisons de performance. (La protection contre la dédup utilise sa propre fenêtre par action — par défaut 7 jours — qui est indépendante de la période de consultation des activités.)La suppression d'une automatisation supprime-t-elle son historique d'activité ?
La suppression d'une automatisation supprime-t-elle son historique d'activité ?
deleted, aucun nouvel envoi ne se produit, mais les lignes d’activité historiques restent consultables via le point de terminaison d’activité.Points de terminaison
POST /automations— créer une nouvelle automatisationGET /automations— lister vos automatisationsGET /automations/:id— récupérer une automatisation avec ses déclencheurs et actionsPUT /automations/:id— mise à jour partielle ; mettre en pause viaactive: falseDELETE /automations/:id— suppression logiqueGET /automations/:id/activity— journal d’audit d’envoi paginé par curseur