TL;DR
La API de Instagram Graph permite a los desarrolladores gestionar cuentas de Instagram Business y Creator de forma programática. Utiliza la autenticación OAuth 2.0 de Facebook Login, puntos finales basados en GraphQL para la publicación de contenido, estadísticas, comentarios y mensajería, con límites de tasa de 200 llamadas por hora por aplicación. Esta guía cubre la configuración de autenticación, la publicación de contenido, la recuperación de estadísticas, la gestión de comentarios y las estrategias de integración en producción.
Introducción
Instagram tiene más de 2 mil millones de usuarios activos mensuales, con más de 200 millones de empresas que utilizan cuentas de Instagram Business. Para los desarrolladores que crean herramientas de gestión de redes sociales, plataformas de análisis o integraciones de comercio electrónico, la integración de la API de Instagram Graph es esencial para llegar a esta audiencia masiva.
Esta es la realidad: los gestores de redes sociales que manejan más de 10 cuentas pierden entre 20 y 30 horas semanales en publicaciones manuales, respuestas a comentarios y compilación de análisis. Una sólida integración con la API de Instagram automatiza la publicación de contenido, la moderación de comentarios, el análisis de sentimientos y la elaboración de informes de rendimiento.
Esta guía le acompañará a través de todo el proceso de integración de la API de Instagram Graph. Aprenderá sobre la autenticación de Facebook Login, la publicación de contenido, las estadísticas de medios, la gestión de comentarios, la integración de webhooks y las estrategias de implementación en producción. Al final, tendrá una integración de Instagram lista para producción.
¿Qué es la API de Instagram Graph?
La API de Instagram Graph proporciona acceso programático a cuentas de Instagram Business y Creator a través de la API de Facebook Graph. La API maneja:
- Publicación de contenido (fotos, videos, reels, carruseles)
- Estadísticas y análisis de medios
- Gestión de comentarios y menciones
- Mensajes directos (a través de la API de Instagram Graph + Messenger Platform)
- Seguimiento de hashtags y menciones
- Gestión de historias
- Compras y etiquetas de productos
Características clave
| Característica | Descripción |
|---|---|
| API basada en grafos | Acceso a recursos basado en nodos |
| OAuth 2.0 | Autenticación con Facebook Login |
| Webhooks | Notificaciones en tiempo real para comentarios, menciones |
| Limitación de tasa | 200 llamadas por hora por aplicación |
| Publicación de contenido | Fotos, videos, reels, carruseles |
| Estadísticas | Métricas de engagement, alcance, impresiones |
| Moderación | Gestión de comentarios, menciones, mensajes |
Requisitos de la cuenta
| Tipo de cuenta | Acceso a la API |
|---|---|
| Cuenta Business | Acceso completo a la API |
| Cuenta Creator | Acceso completo a la API |
| Cuenta Personal | Sin acceso a la API (debe convertir) |
| Cuenta Privada | Estadísticas limitadas |
Visión general de la arquitectura de la API
Instagram utiliza la estructura de la API de Facebook Graph:
https://graph.facebook.com/v18.0/
Comparación de versiones de la API
| Versión | Estado | Fecha de finalización | Caso de uso |
|---|---|---|---|
| v18.0 | Actual | Marzo 2026 | Todas las nuevas integraciones |
| v17.0 | Obsoleta | Enero 2026 | Integraciones existentes |
| v16.0 | Retirada | Expirada | No usar |
Facebook lanza nuevas versiones trimestralmente. Siempre apunte a la última versión estable.
Primeros pasos: Configuración de autenticación
Paso 1: Crear una cuenta de desarrollador de Facebook
Antes de acceder a la API:
- Visite el Portal de desarrolladores de Facebook
- Inicie sesión con su cuenta de Facebook
- Cree una aplicación de Facebook (tipo: Negocio)
- Añada el producto Instagram Graph API
Paso 2: Vincular la cuenta de Instagram Business
Conecte Instagram a su página de Facebook:
- Vaya a Configuración de la página de Facebook > Instagram
- Haga clic en Conectar cuenta
- Inicie sesión en Instagram y autorice
- Confirme que la cuenta de Instagram Business está vinculada
Nota: Las cuentas personales de Instagram no pueden utilizar la API de Graph. Conviértala en cuenta Business o Creator en la Configuración de Instagram.
Paso 3: Obtener tokens de acceso
Genere un token de acceso de usuario:
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;
// Build authorization URL
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()}`;
};
Permisos requeridos
| Permiso | Descripción |
|---|---|
instagram_basic |
Información de perfil básica, lista de medios |
instagram_content_publish |
Publicar fotos, videos, carruseles |
instagram_manage_comments |
Leer/escribir comentarios |
instagram_manage_insights |
Acceder a datos analíticos |
pages_read_engagement |
Acceso a la página para publicación |
pages_manage_posts |
Publicar en la página conectada |
Paso 4: Intercambiar token por un token de larga duración
Los tokens de corta duración expiran en 1 hora. Intercámbielos por un token de larga duración (60 días):
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;
};
// Usage
const longLivedToken = await exchangeForLongLivedToken(shortLivedToken);
console.log(`Token expires: ${new Date(longLivedToken.expires_at * 1000)}`);
Paso 5: Obtener el ID de la cuenta de Instagram Business
Recupere la cuenta de Instagram conectada:
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;
};
// Usage
const igAccountId = await getInstagramAccountId('12345678', accessToken);
console.log(`Instagram Account ID: ${igAccountId}`);
Paso 6: Realizar llamadas a la API autenticadas
Cree un cliente de API reutilizable:
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();
};
// Usage
const account = await instagramRequest(`/me`);
console.log(`Instagram Account: ${account.username}`);
Publicación de contenido
Publicar una foto
Publique una foto en Instagram:
const publishPhoto = async (igAccountId, photoData) => {
// Step 1: Create media container
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
image_url: photoData.imageUrl,
caption: photoData.caption,
location_id: photoData.locationId, // Optional
is_carousel_item: 'false'
});
const creationId = containerResponse.id;
// Step 2: Publish the media
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Usage
const post = await publishPhoto({
igAccountId: '17841400000000000',
imageUrl: 'https://example.com/image.jpg',
caption: 'Excited to announce our new product! 🚀 #launch #innovation',
locationId: '123456789' // Optional
});
console.log(`Published media ID: ${post.id}`);
Publicar un video
Publique un video en Instagram:
const publishVideo = async (igAccountId, videoData) => {
// Step 1: Create media container
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
video_url: videoData.videoUrl,
cover_url: videoData.coverUrl, // Optional thumbnail
caption: videoData.caption,
media_type: 'REELS', // or 'VIDEO' for feed
share_to_feed: 'true' // For reels
});
const creationId = containerResponse.id;
// Wait for video processing (poll until status is EXPIRED or FINISHED)
await waitForVideoProcessing(creationId);
// Step 2: Publish the media
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('Video processing expired');
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error('Video processing timeout');
};
Publicar un carrusel (múltiples imágenes/videos)
Publique múltiples elementos multimedia en una sola publicación:
const publishCarousel = async (igAccountId, carouselData) => {
const children = [];
// Step 1: Create each carousel item
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);
}
// Step 2: Create carousel container with children
const carouselContainerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
media_type: 'CAROUSEL',
children: children.join(','),
caption: carouselData.caption
});
const creationId = carouselContainerResponse.id;
// Step 3: Publish the carousel
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Usage
const carousel = await publishCarousel('17841400000000000', {
caption: 'Product showcase 2026',
items: [
{ type: 'image', url: 'https://example.com/img1.jpg', caption: 'Product 1' },
{ type: 'image', url: 'https://example.com/img2.jpg', caption: 'Product 2' },
{ type: 'video', url: 'https://example.com/vid1.mp4', caption: 'Demo' }
]
});
Tipos de medios
| Tipo de medio | Parámetros | Caso de uso |
|---|---|---|
IMAGE |
image_url, caption | Publicaciones de fotos |
VIDEO |
video_url, cover_url, caption | Publicaciones de video |
REELS |
video_url, cover_url, caption, share_to_feed | Reels |
CAROUSEL |
children (array), caption | Múltiples medios |
Recuperación de medios y estadísticas
Obtener medios del usuario
Recuperar medios publicados:
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;
};
// Usage
const media = await getUserMedia('17841400000000000');
media.data.forEach(item => {
console.log(`${item.media_type}: ${item.caption}`);
console.log(`Likes: ${item.like_count}, Comments: ${item.comments_count}`);
console.log(`URL: ${item.permalink}`);
});
Obtener estadísticas de medios
Recuperar análisis para medios específicos:
const getMediaInsights = async (mediaId) => {
const response = await instagramRequest(`/${mediaId}/insights`, {
fields: 'impressions,reach,engagement,saved,video_views,profile_visits,follows'
});
return response;
};
// Usage
const insights = await getMediaInsights('17890000000000000');
insights.data.forEach(metric => {
console.log(`${metric.name}: ${metric.values[0].value}`);
});
Métricas de estadísticas disponibles
| Métrica | Descripción | Tipos de medios |
|---|---|---|
impressions |
Vistas totales | Todos |
reach |
Cuentas únicas alcanzadas | Todos |
engagement |
Me gusta + comentarios + guardados | Todos |
saved |
Veces guardado | Todos |
video_views |
Vistas de video (3+ segundos) | Video, Reels |
plays |
Reproducciones totales de video | Video, Reels |
profile_visits |
Visitas al perfil desde la publicación | Todos |
follows |
Seguidores desde la publicación | Todos |
comments |
Cantidad de comentarios | Todos |
like_count |
Cantidad de "Me gusta" | Todos |
Obtener estadísticas de la cuenta
Recuperar análisis agregados de la cuenta:
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;
};
// Usage - Get last 30 days of metrics
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étricas a nivel de cuenta
| Métrica | Descripción |
|---|---|
impressions |
Vistas totales de perfil + contenido |
reach |
Cuentas únicas alcanzadas |
profile_views |
Visitas al perfil |
website_clicks |
Clics en el enlace de la biografía |
email_contacts |
Tocados en el botón de correo electrónico |
phone_call_clicks |
Tocados en el botón de teléfono |
text_message_clicks |
Tocados en el botón de SMS |
get_directions_clicks |
Clics en la dirección |
follower_count |
Total de seguidores |
audience_city |
Ciudades de los seguidores |
audience_country |
Países de los seguidores |
audience_gender_age |
Desglose demográfico |
Gestión de comentarios
Obtener comentarios
Recuperar comentarios en medios:
const getMediaComments = async (mediaId, limit = 50) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
fields: 'id,text,timestamp,username,hidden',
limit: limit.toString()
});
return response;
};
// Usage
const comments = await getMediaComments('17890000000000000');
comments.data.forEach(comment => {
console.log(`@${comment.username}: ${comment.text}`);
console.log(`Hidden: ${comment.hidden}`);
});
Responder a comentarios
Publicar una respuesta a un comentario:
const replyToComment = async (mediaId, commentId, replyText) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
method: 'POST',
response_to: commentId,
message: replyText
});
return response;
};
// Usage
const reply = await replyToComment(
'17890000000000000',
'17900000000000000',
'Thank you for your interest! Check your DM for details.'
);
console.log(`Reply posted: ${reply.id}`);
Ocultar comentarios
Ocultar comentarios inapropiados:
const hideComment = async (commentId) => {
const response = await instagramRequest(`/${commentId}`, {
method: 'POST',
hide: 'true'
});
return response;
};
// Usage
await hideComment('17900000000000000');
console.log('Comment hidden');
Eliminar comentarios
Eliminar spam o comentarios inapropiados:
const deleteComment = async (commentId) => {
await instagramRequest(`/${commentId}`, {
method: 'DELETE'
});
console.log('Comment deleted');
};
Webhooks
Configuración de webhooks
Configure webhooks para notificaciones en tiempo real:
const subscribeToWebhooks = async (appId, pageId, accessToken) => {
// Subscribe to Instagram events
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();
};
Manejo de webhooks
const express = require('express');
const app = express();
// Verify webhook subscription
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) {
console.log('Webhook verified');
res.status(200).send(challenge);
} else {
res.status(403).send('Verification failed');
}
});
// Handle webhook events
app.post('/webhooks/instagram', express.json(), async (req, res) => {
const body = req.body;
if (body.object !== 'instagram') {
return res.status(404).send('Not found');
}
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(`New comment on media ${data.media_id}`);
console.log(`From: ${data.from_id}`);
console.log(`Text: ${data.text}`);
// Auto-reply or moderate
if (isSpam(data.text)) {
await hideComment(data.id);
}
}
Campos de webhook
| Campo | Activador |
|---|---|
comments |
Nuevo comentario o respuesta |
mentions |
El usuario menciona la cuenta |
message_reactions |
Reacción a una historia |
story_status |
Respuesta/vista de historia |
Limitación de tasa
Comprendiendo los límites de tasa
La API de Instagram Graph impone:
- 200 llamadas por hora por aplicación (compartidas entre todos los usuarios)
- Business Discovery: 200 llamadas por hora por usuario
- Publicación de contenido: Limitado por tipo de acción
Exceder los límites resulta en un HTTP 400 con el subcódigo de error 613.
Mejores prácticas para la limitación de tasa
- Caché de respuestas - No vuelva a recuperar datos no modificados
- Solicitudes por lotes - Utilice la expansión de campos para reducir las llamadas
- Utilice webhooks - Actualizaciones en tiempo real en lugar de sondeo
- Implementar retroceso - Retroceso exponencial en errores 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(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Solución de problemas comunes
Problema: Token OAuth expirado
Síntomas: Recibir errores de "Invalid OAuth access token".
Soluciones:
- Implementar la actualización del token antes de la expiración de 60 días
- Almacenar la fecha de expiración del token y alertar antes de la misma
- Volver a autenticar al usuario si el token ha expirado
Problema: Falla la publicación de medios
Síntomas: La publicación devuelve un error.
Soluciones:
- Verificar que la URL de la imagen sea de acceso público (no requiere autenticación)
- Comprobar el formato de la imagen (JPEG, PNG) y el tamaño (<8MB)
- Asegurarse de que el video esté en formato MP4, <1GB, <90 segundos
- Esperar a que el video sea procesado antes de publicar
Problema: Estadísticas no disponibles
Síntomas: La API de estadísticas devuelve datos vacíos.
Soluciones:
- Verificar que la cuenta sea Business o Creator (no Personal)
- Esperar 24-48 horas para que las estadísticas se completen
- Comprobar que la cuenta tenga suficiente actividad
Lista de verificación para la implementación en producción
Antes de salir en vivo:
- [ ] Convertir todas las cuentas de prueba a Business/Creator
- [ ] Implementar OAuth 2.0 con tokens de larga duración
- [ ] Almacenar tokens de forma segura con cifrado
- [ ] Implementar la actualización automática de tokens
- [ ] Configurar puntos finales de webhook con HTTPS
- [ ] Añadir limitación de tasa y cola de solicitudes
- [ ] Implementar un manejo de errores completo
- [ ] Añadir registro para todas las llamadas a la API
- [ ] Crear flujos de trabajo de moderación de contenido
- [ ] Probar con múltiples tipos de cuenta
Casos de uso en el mundo real
Herramienta de programación de redes sociales
Una plataforma de marketing automatiza la publicación:
- Desafío: Publicación manual en más de 50 cuentas de clientes
- Solución: Publicación programada a través de la API de Instagram
- Resultado: Ahorro del 80% de tiempo, horario de publicación consistente
Implementación clave:
- Calendario de contenido con programación de arrastrar y soltar
- Publicación automática de fotos, videos, carruseles
- Sugerencias de hashtags basadas en el contenido
Automatización del servicio al cliente
Una marca de comercio electrónico automatiza las respuestas a los comentarios:
- Desafío: Respuesta lenta a las consultas de los clientes
- Solución: Respuesta automática a preguntas comunes a través de webhook
- Resultado: Tiempo de respuesta promedio de 5 minutos, 90% de satisfacción
Implementación clave:
- Detección de palabras clave (precio, disponibilidad, envío)
- Respuesta automática con enlaces de productos
- Escalar consultas complejas a agentes humanos
Conclusión
La API de Instagram Graph proporciona acceso completo a las funciones de las cuentas de Instagram Business y Creator. Puntos clave:
- Autenticación OAuth 2.0 de Facebook Login con tokens de 60 días
- La publicación de contenido admite fotos, videos, reels y carruseles
- La API de Insights proporciona datos de engagement, alcance y demografía
- Los webhooks permiten el monitoreo en tiempo real de comentarios y menciones
- El límite de tasa de 200 llamadas/hora por aplicación requiere una gestión cuidadosa
- Apidog agiliza las pruebas de API y la colaboración en equipo
Sección de Preguntas Frecuentes
¿Cómo obtengo acceso a la API de Instagram?
Cree una cuenta de desarrollador de Facebook, cree una aplicación de negocios, añada el producto Instagram Graph API y autentíquese a través de Facebook Login con los permisos requeridos.
¿Puedo publicar en Instagram automáticamente?
Sí, utilice la API de Publicación de Contenido para publicar fotos, videos, reels y carruseles en cuentas Business y Creator.
¿Qué tipos de cuentas de Instagram son compatibles con la API?
Solo las cuentas Business y Creator tienen acceso completo a la API. Las cuentas personales tienen acceso limitado o nulo a la API.
¿Cómo obtengo comentarios de Instagram?
Utilice el punto final de Comentarios (/{media-id}/comments) para obtener comentarios en medios específicos. Los webhooks proporcionan notificaciones en tiempo real.
¿Cuáles son los límites de tasa de Instagram?
La API de Instagram Graph permite 200 llamadas por hora por aplicación. Algunos puntos finales tienen límites adicionales por usuario.
¿Puedo publicar Stories a través de la API?
Sí, las Stories se pueden publicar utilizando el mismo flujo de publicación de contenido que las publicaciones de feed.
¿Cómo accedo a las estadísticas de Instagram?
Solicite el permiso instagram_manage_insights durante OAuth. Utilice el punto final de Insights para obtener métricas para medios y cuentas.
¿Puedo responder a los comentarios automáticamente?
Sí, use la API de Comentarios para publicar respuestas. Muchas marcas usan esto para respuestas automatizadas de servicio al cliente.
