En bref
L'API Graph d'Instagram permet de gérer par programmation les comptes Instagram Business et Creator. Elle s'appuie sur l'authentification OAuth 2.0 de Facebook Login, expose des endpoints basés sur GraphQL pour la publication de contenu, la récupération de statistiques, la gestion des commentaires et la messagerie, tout en imposant une limite de 200 appels/heure par application. Ce guide va droit à l'essentiel : configuration de l'authentification, publication automatisée, extraction de statistiques, gestion des commentaires et stratégies d'intégration en production.
Essayez Apidog dès aujourd'hui
Introduction
Instagram dépasse les 2 milliards d'utilisateurs actifs mensuels et 200 millions d'entreprises utilisent Instagram Business. Si vous développez des outils de gestion de médias sociaux, des plateformes d'analyse ou des intégrations e-commerce, l'intégration de l'API Graph est incontournable pour automatiser les workflows.
Les gestionnaires de médias sociaux qui gèrent plus de 10 comptes gaspillent 20 à 30 heures/semaine en publications manuelles, réponses aux commentaires et reporting. Une intégration API robuste automatise la publication, la modération, l'analyse de sentiments et les rapports.
Ce guide détaille l’intégration complète de l’API Graph d’Instagram : authentification Facebook Login, publication de contenu, extraction de statistiques, gestion des commentaires, webhooks et checklist pour la production.
💡 Astuce : Apidog simplifie les tests d'intégration API : testez vos endpoints Instagram, validez OAuth, inspectez les réponses et déboguez dans un workspace unique. Importez des specs, simulez des réponses et partagez vos scénarios de test en équipe.
Qu'est-ce que l'API Graph d'Instagram ?
L’API Graph d’Instagram donne un accès par programmation aux comptes Business/Creator via l’API Graph Facebook. Elle permet :
- Publication de contenu (photos, vidéos, Reels, carrousels)
- Statistiques et analyses médias
- Gestion des commentaires et mentions
- Messagerie directe (API Graph Instagram + Plateforme Messenger)
- Suivi des hashtags/mentions
- Gestion des Stories
- Achats et balises produit
Fonctionnalités clés
| Fonctionnalité | Description |
|---|---|
| API basée sur le graphe | Accès aux ressources basé sur les nœuds |
| OAuth 2.0 | Authentification Facebook Login |
| Webhooks | Notifications temps réel (commentaires, mentions) |
| Limitation du débit | 200 appels/heure/app |
| Publication de contenu | Photos, vidéos, Reels, carrousels |
| Statistiques | Engagement, portée, impressions |
| Modération | Gestion commentaires, mentions, messages |
Exigences du compte
| Type de compte | Accès API |
|---|---|
| Business | Accès complet |
| Creator | Accès complet |
| Personnel | Aucun accès (à convertir) |
| Privé | Statistiques limitées |
Aperçu de l'architecture
L’API repose sur la structure suivante :
https://graph.facebook.com/v18.0/
Comparaison des versions
| Version | Statut | Fin de support | Cas d’usage |
|---|---|---|---|
| v18.0 | Actuelle | Mars 2026 | Nouvelles intégrations |
| v17.0 | Dépréciée | Janvier 2026 | Intégrations existantes |
| v16.0 | Retirée | Expirée | À ne pas utiliser |
Recommandation : Utilisez toujours la version stable la plus récente.
Démarrage : Configuration de l'authentification
Étape 1 : Créer un compte développeur Facebook
- Rendez-vous sur le Portail des développeurs Facebook
- Connectez-vous avec votre compte Facebook
- Créez une application Facebook (type : Entreprise)
- Ajoutez le produit "API Graph d'Instagram"
Étape 2 : Lier un compte Instagram Business
- Accédez aux paramètres de la Page Facebook > Instagram
- Cliquez sur Connecter le compte
- Authentifiez-vous sur Instagram et autorisez l’accès
- Vérifiez que le compte Instagram Business est bien lié
Astuce : Convertissez tout compte personnel en Business/Creator dans les paramètres Instagram.
Étape 3 : Obtenir les jetons d’accès
Générez un jeton d’accès utilisateur via OAuth :
const FB_APP_ID = process.env.FB_APP_ID;
const FB_APP_SECRET = process.env.FB_APP_SECRET;
const FB_REDIRECT_URI = process.env.FB_REDIRECT_URI;
const getAuthUrl = (state) => {
const params = new URLSearchParams({
client_id: FB_APP_ID,
redirect_uri: FB_REDIRECT_URI,
scope: 'instagram_basic,instagram_content_publish,instagram_manage_comments,instagram_manage_insights,pages_read_engagement',
state: state
});
return `https://www.facebook.com/v18.0/dialog/oauth?${params.toString()}`;
};
Autorisations requises
| Permission | Description |
|---|---|
instagram_basic |
Infos profil, liste des médias |
instagram_content_publish |
Publier photos/vidéos/carrousels |
instagram_manage_comments |
Lire/écrire des commentaires |
instagram_manage_insights |
Accéder aux analytics |
pages_read_engagement |
Accès page pour publier |
pages_manage_posts |
Publier sur la page liée |
Étape 4 : Échanger le jeton contre un jeton longue durée
Les jetons courts expirent en 1h. Échangez-les pour un jeton 60 jours :
const exchangeForLongLivedToken = async (shortLivedToken) => {
const response = await fetch(
`https://graph.facebook.com/v18.0/oauth/access_token?` +
`grant_type=fb_exchange_token&` +
`client_id=${FB_APP_ID}&` +
`client_secret=${FB_APP_SECRET}&` +
`fb_exchange_token=${shortLivedToken}`
);
const data = await response.json();
return data;
};
const longLivedToken = await exchangeForLongLivedToken(shortLivedToken);
console.log(`Expiration du jeton : ${new Date(longLivedToken.expires_at * 1000)}`);
Étape 5 : Obtenir l’ID du compte Instagram Business
const getInstagramAccountId = async (pageId, accessToken) => {
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}?fields=instagram_business_account&access_token=${accessToken}`
);
const data = await response.json();
return data.instagram_business_account.id;
};
// Exemple d'utilisation
const igAccountId = await getInstagramAccountId('12345678', accessToken);
console.log(`ID Instagram : ${igAccountId}`);
Étape 6 : Effectuer des appels API authentifiés
Centralisez vos appels API :
const IG_BASE_URL = 'https://graph.facebook.com/v18.0';
const instagramRequest = async (endpoint, params = {}) => {
const url = new URL(`${IG_BASE_URL}${endpoint}`);
url.searchParams.append('access_token', process.env.INSTAGRAM_ACCESS_TOKEN);
Object.entries(params).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
const response = await fetch(url.toString());
if (!response.ok) {
const error = await response.json();
throw new Error(`Instagram API Error: ${error.error.message}`);
}
return response.json();
};
// Exemple d'utilisation
const account = await instagramRequest(`/me`);
console.log(`Compte : ${account.username}`);
Publication de contenu
Publication d’une photo
Publiez une photo en deux étapes :
const publishPhoto = async (igAccountId, photoData) => {
// 1. Créer un conteneur média
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
image_url: photoData.imageUrl,
caption: photoData.caption,
location_id: photoData.locationId, // Optionnel
is_carousel_item: 'false'
});
const creationId = containerResponse.id;
// 2. Publier le média
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Exemple
const post = await publishPhoto({
igAccountId: '17841400000000000',
imageUrl: 'https://example.com/image.jpg',
caption: 'Nouveau produit ! 🚀 #lancement',
locationId: '123456789'
});
console.log(`ID média publié : ${post.id}`);
Publication d’une vidéo
const publishVideo = async (igAccountId, videoData) => {
// 1. Créer un conteneur média
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
video_url: videoData.videoUrl,
cover_url: videoData.coverUrl,
caption: videoData.caption,
media_type: 'REELS', // ou 'VIDEO'
share_to_feed: 'true' // Pour Reels
});
const creationId = containerResponse.id;
// Attendre le traitement de la vidéo
await waitForVideoProcessing(creationId);
// 2. Publier le média
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
const waitForVideoProcessing = async (creationId, maxAttempts = 30) => {
for (let i = 0; i < maxAttempts; i++) {
const status = await instagramRequest(`/${creationId}`);
if (status.status_code === 'FINISHED') {
return true;
} else if (status.status_code === 'EXPIRED') {
throw new Error('Le traitement de la vidéo a expiré');
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error('Délai de traitement dépassé');
};
Publication d’un carrousel (plusieurs images/vidéos)
const publishCarousel = async (igAccountId, carouselData) => {
const children = [];
// Créer chaque élément du carrousel
for (const item of carouselData.items) {
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
[item.type === 'video' ? 'video_url' : 'image_url']: item.url,
caption: item.caption || '',
is_carousel_item: 'true'
});
children.push(containerResponse.id);
}
// Créer un conteneur de carrousel
const carouselContainerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
media_type: 'CAROUSEL',
children: children.join(','),
caption: carouselData.caption
});
const creationId = carouselContainerResponse.id;
// Publier le carrousel
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Exemple
const carousel = await publishCarousel('17841400000000000', {
caption: 'Présentation 2026',
items: [
{ type: 'image', url: 'https://example.com/img1.jpg', caption: 'Produit 1' },
{ type: 'image', url: 'https://example.com/img2.jpg', caption: 'Produit 2' },
{ type: 'video', url: 'https://example.com/vid1.mp4', caption: 'Démo' }
]
});
Types de médias
| Type de média | Paramètres | Cas d’utilisation |
|---|---|---|
IMAGE |
image_url, légende | Publications photo |
VIDEO |
video_url, cover_url, légende | Publications vidéo |
REELS |
video_url, cover_url, légende, share_to_feed | Reels |
CAROUSEL |
enfants (array), légende | Plusieurs médias |
Récupération des médias et des statistiques
Récupérer les médias publiés
const getUserMedia = async (igAccountId, limit = 25) => {
const response = await instagramRequest(`/${igAccountId}/media`, {
fields: 'id,caption,media_type,media_url,permalink,timestamp,like_count,comments_count',
limit: limit.toString()
});
return response;
};
// Exemple
const media = await getUserMedia('17841400000000000');
media.data.forEach(item => {
console.log(`${item.media_type}: ${item.caption}`);
console.log(`J'aime : ${item.like_count}, Commentaires : ${item.comments_count}`);
console.log(`URL : ${item.permalink}`);
});
Obtenir les statistiques d’un média
const getMediaInsights = async (mediaId) => {
const response = await instagramRequest(`/${mediaId}/insights`, {
fields: 'impressions,reach,engagement,saved,video_views,profile_visits,follows'
});
return response;
};
// Exemple
const insights = await getMediaInsights('17890000000000000');
insights.data.forEach(metric => {
console.log(`${metric.name}: ${metric.values[0].value}`);
});
Principales métriques disponibles
| Métrique | Description | Types de médias |
|---|---|---|
impressions |
Vues totales | Tous |
reach |
Comptes uniques | Tous |
engagement |
J'aime + commentaires | Tous |
saved |
Nombre d'enregistrements | Tous |
video_views |
Vues vidéo (3s+) | Vidéo, Reels |
plays |
Lectures vidéo totales | Vidéo, Reels |
profile_visits |
Visites profil | Tous |
follows |
Abonnements | Tous |
comments |
Nombre de commentaires | Tous |
like_count |
Nombre de J'aime | Tous |
Statistiques agrégées du compte
const getAccountInsights = async (igAccountId, metricNames, since = null, until = null) => {
const params = {
metric: metricNames.join(','),
period: 'day'
};
if (since) params.since = since;
if (until) params.until = until;
const response = await instagramRequest(`/${igAccountId}/insights`, params);
return response;
};
// Exemple : 30 derniers jours
const accountInsights = await getAccountInsights(
'17841400000000000',
['impressions', 'reach', 'profile_views', 'email_contacts', 'website_clicks'],
'2026-02-23',
'2026-03-25'
);
accountInsights.data.forEach(metric => {
console.log(`${metric.name}:`);
metric.values.forEach(value => {
console.log(` ${value.end_time}: ${value.value}`);
});
});
Métriques au niveau du compte
| Métrique | Description |
|---|---|
impressions |
Vues totales profil + contenu |
reach |
Comptes uniques atteints |
profile_views |
Visites du profil |
website_clicks |
Clics sur le lien bio |
email_contacts |
Clics bouton email |
phone_call_clicks |
Clics bouton téléphone |
text_message_clicks |
Clics bouton SMS |
get_directions_clicks |
Clics sur l'adresse |
follower_count |
Nombre d'abonnés |
audience_city |
Villes abonnés |
audience_country |
Pays abonnés |
audience_gender_age |
Répartition démographique |
Gestion des commentaires
Récupérer les commentaires d’un média
const getMediaComments = async (mediaId, limit = 50) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
fields: 'id,text,timestamp,username,hidden',
limit: limit.toString()
});
return response;
};
// Exemple
const comments = await getMediaComments('17890000000000000');
comments.data.forEach(comment => {
console.log(`@${comment.username}: ${comment.text}`);
console.log(`Masqué : ${comment.hidden}`);
});
Répondre à un commentaire
const replyToComment = async (mediaId, commentId, replyText) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
method: 'POST',
response_to: commentId,
message: replyText
});
return response;
};
// Exemple
const reply = await replyToComment(
'17890000000000000',
'17900000000000000',
'Merci de votre intérêt ! Vérifiez vos MP.'
);
console.log(`Réponse publiée : ${reply.id}`);
Masquer un commentaire
const hideComment = async (commentId) => {
const response = await instagramRequest(`/${commentId}`, {
method: 'POST',
hide: 'true'
});
return response;
};
// Exemple
await hideComment('17900000000000000');
console.log('Commentaire masqué');
Supprimer un commentaire
const deleteComment = async (commentId) => {
await instagramRequest(`/${commentId}`, {
method: 'DELETE'
});
console.log('Commentaire supprimé');
};
Webhooks
Configurer les webhooks
Automatisez la réception des notifications en temps réel :
const subscribeToWebhooks = async (appId, pageId, accessToken) => {
const response = await fetch(
`https://graph.facebook.com/v18.0/${appId}/subscriptions`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
object: 'instagram',
callback_url: 'https://myapp.com/webhooks/instagram',
verify_token: process.env.WEBHOOK_VERIFY_TOKEN,
access_token: accessToken,
fields: ['comments', 'mentions', 'message_reactions']
})
}
);
return response.json();
};
Gérer les événements webhooks
const express = require('express');
const app = express();
// Vérification du webhook
app.get('/webhooks/instagram', (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.WEBHOOK_VERIFY_TOKEN) {
res.status(200).send(challenge);
} else {
res.status(403).send('Vérification échouée');
}
});
// Traitement des événements
app.post('/webhooks/instagram', express.json(), async (req, res) => {
const body = req.body;
if (body.object !== 'instagram') {
return res.status(404).send('Non trouvé');
}
for (const entry of body.entry) {
const igId = entry.id;
const changes = entry.changes;
for (const change of changes) {
switch (change.field) {
case 'comments':
await handleNewComment(change.value);
break;
case 'mentions':
await handleMention(change.value);
break;
case 'message_reactions':
await handleReaction(change.value);
break;
}
}
}
res.status(200).send('OK');
});
async function handleNewComment(data) {
console.log(`Nouveau commentaire sur le média ${data.media_id}`);
console.log(`De : ${data.from_id}`);
console.log(`Texte : ${data.text}`);
// Auto-modération
if (isSpam(data.text)) {
await hideComment(data.id);
}
}
Champs de webhook
| Champ | Déclencheur |
|---|---|
comments |
Nouveau commentaire ou réponse |
mentions |
Mention du compte Instagram |
message_reactions |
Réaction à une story |
story_status |
Réponse/vue de story |
Limitation du débit
Comprendre les limites
- 200 appels/heure/app (partagés sur tous les utilisateurs)
- Découverte business : 200 appels/heure/utilisateur
- Publication : quotas spécifiques selon l’action
Un dépassement déclenche une erreur HTTP 400, code 613.
Bonnes pratiques
- Mettre en cache : ne récupérez pas inutilement des données inchangées
- Regrouper les requêtes : utilisez field expansion
- Webhooks : préférez les notifications temps réel au polling
- Backoff exponentiel sur erreur 429
const makeRateLimitedRequest = async (endpoint, params = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await instagramRequest(endpoint, params);
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Limite atteinte. Nouvelle tentative dans ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Dépannage des problèmes courants
Problème : Jeton OAuth expiré
Symptômes : Erreur « Jeton d’accès OAuth invalide »
Solutions :
- Rafraîchir le jeton avant expiration (60 jours)
- Stocker la date d’expiration et alerter en amont
- Réauthentifier l’utilisateur si le jeton est expiré
Problème : Échec de la publication média
Symptômes : Erreur lors de la publication
Solutions :
- L’URL de l’image doit être publique
- Format image : JPEG/PNG, <8 Mo
- Vidéo : MP4, <1 Go, <90s
- Attendre la fin du traitement vidéo
Problème : Statistiques non disponibles
Symptômes : API Insights retourne des données vides
Solutions :
- Vérifier que le compte est Business/Creator
- Attendre 24 à 48h pour la génération des stats
- Vérifier l’activité suffisante du compte
Checklist pour le déploiement en production
Avant d’aller en prod :
- [ ] Tous les comptes sont Business/Creator
- [ ] OAuth 2.0 avec jetons longue durée implémenté
- [ ] Jetons stockés et chiffrés
- [ ] Rafraîchissement automatique des jetons
- [ ] Webhooks configurés en HTTPS
- [ ] Limitation du débit et file d’attente ajoutées
- [ ] Gestion complète des erreurs
- [ ] Journalisation de tous les appels API
- [ ] Workflows de modération déployés
- [ ] Tests sur plusieurs types de comptes
Cas d’utilisation réels
Outil de planification de médias sociaux
- Défi : Publication manuelle sur 50+ comptes clients
- Solution : Publication programmée via l’API Instagram
- Résultat : 80 % de gain de temps, calendrier cohérent
Implémentation :
- Calendrier de contenu, planification glisser-déposer
- Publication automatisée photos/vidéos/carrousels
- Suggestions de hashtags contextuelles
Automatisation du service client
- Défi : Temps de réponse client trop long
- Solution : Réponse automatique via webhook
- Résultat : Temps de réponse moyen : 5 min, 90 % satisfaction
Implémentation :
- Détection de mots-clés (prix, livraison, stock)
- Réponse automatique avec liens produits
- Escalade aux agents humains pour les cas complexes
Conclusion
L’API Graph d’Instagram apporte un accès complet aux comptes Business et Creator. Points clés :
- Authentification OAuth 2.0 Facebook Login, jetons 60 jours
- Publication de photos, vidéos, Reels, carrousels
- API Insights : engagement, portée, démographie
- Webhooks pour commentaires/mentions temps réel
- Limite de 200 appels/heure/app à gérer rigoureusement
- Apidog facilite les tests d’API et la collaboration
Section FAQ
Comment obtenir l’accès à l’API Instagram ?
Créez un compte développeur Facebook, créez une app Business, ajoutez l’API Instagram Graph et authentifiez-vous via Facebook Login avec les autorisations requises.
Puis-je publier sur Instagram automatiquement ?
Oui, l’API permet de publier photos, vidéos, Reels et carrousels sur les comptes Business/Creator.
Quels types de comptes Instagram prennent en charge l’API ?
Seuls les comptes Business et Creator bénéficient d’un accès complet à l’API. Les comptes personnels n’y ont pas accès.
Comment obtenir les commentaires d’Instagram ?
Utilisez le endpoint /media-id/comments pour chaque média. Les webhooks fournissent des notifications en temps réel.
Quelles sont les limites de débit d’Instagram ?
200 appels/heure/app via l’API Graph Instagram. Certains endpoints ont des quotas par utilisateur.
Puis-je publier des Stories via l’API ?
Oui, les Stories sont publiables via le même flux que les publications du fil.
Comment accéder aux statistiques Instagram ?
Demandez la permission instagram_manage_insights lors de l’OAuth. Utilisez ensuite le endpoint Insights.
Puis-je répondre automatiquement aux commentaires ?
Oui, l’API commentaires permet de publier des réponses. Pratique pour automatiser le service client.
Top comments (0)