DEV Community

Cover image for Como Usar a API Graph do Instagram em 2026
Lucas
Lucas

Posted on • Originally published at apidog.com

Como Usar a API Graph do Instagram em 2026

TL;DR

A API de Gráficos do Instagram permite que desenvolvedores gerenciem contas de Negócios e Criadores do Instagram programaticamente. Ela utiliza OAuth 2.0 via Facebook Login, endpoints GraphQL para publicação de conteúdo, insights, comentários e mensagens, com limite de taxa de 200 chamadas/hora por aplicativo. Este guia mostra desde a configuração de autenticação, publicação, insights, comentários e estratégias de integração em produção.

Experimente o Apidog hoje mesmo


Introdução

O Instagram ultrapassa 2 bilhões de usuários ativos mensais, com mais de 200 milhões de empresas usando contas comerciais. Se você desenvolve ferramentas de gestão de mídias sociais, plataformas de analytics ou integrações de e-commerce, integrar a API de Gráficos do Instagram é fundamental para automatizar operações e escalar o alcance.

Na prática: gerentes de mídias sociais que administram mais de 10 contas perdem de 20 a 30 horas por semana em tarefas manuais (postagens, respostas, relatórios). Uma integração robusta com a API do Instagram automatiza publicação, moderação, análise de sentimento e relatórios.

Este guia cobre a integração da API de Gráficos do Instagram: autenticação, publicação, insights, comentários, webhooks e checklist de produção. Ao final, você terá uma integração pronta para produção.

💡 Dica: Apidog simplifica o teste de integração de API. Teste endpoints do Instagram, valide OAuth, inspecione respostas e depure publicações no mesmo workspace. Importe specs, simule respostas e compartilhe testes com sua equipe.


O Que É a API de Gráficos do Instagram?

A API de Gráficos do Instagram oferece acesso programático a contas de Negócios e Criadores via API de Gráficos do Facebook. Permite:

  • Publicação de conteúdo (fotos, vídeos, Reels, carrosséis)
  • Insights e analytics
  • Gerenciamento de comentários e menções
  • Mensagens diretas (via API + Messenger)
  • Rastreamento de hashtags/menções
  • Gestão de Stories
  • Tags de compras e produtos

Principais Recursos

Recurso Descrição
API baseada em Gráficos Acesso via nós e conexões
OAuth 2.0 Autenticação via Facebook Login
Webhooks Notificações em tempo real
Limite de Taxa 200 chamadas/hora por app
Publicação de Conteúdo Fotos, vídeos, Reels, carrosséis
Insights Engajamento, alcance, impressões
Moderação Gerenciamento de comentários, menções, mensagens

Requisitos da Conta

Tipo de Conta Acesso à API
Comercial Acesso total
Criador de Conteúdo Acesso total
Pessoal Sem acesso (precisa converter)
Privada Insights limitados

Visão Geral da Arquitetura da API

A base da API:

https://graph.facebook.com/v18.0/
Enter fullscreen mode Exit fullscreen mode

Versões da API Comparadas

Versão Status Data Final Uso recomendado
v18.0 Atual Mar 2026 Novas integrações
v17.0 Descontinuado Jan 2026 Integrações existentes
v16.0 Aposentado Expirado Não usar

Sempre use a versão estável mais recente.


Primeiros Passos: Configuração de Autenticação

Passo 1: Criar Conta de Desenvolvedor do Facebook

  1. Acesse o Portal de Desenvolvedores do Facebook
  2. Faça login
  3. Crie um App (tipo: Negócios)
  4. Adicione o produto Instagram Graph API

Passo 2: Vincular Conta Comercial do Instagram

  1. Vá em Configurações da Página do Facebook → Instagram
  2. Clique em Conectar Conta
  3. Faça login no Instagram e autorize
  4. Confirme a vinculação

Contas pessoais não usam a API; converta para Comercial ou Criador nas configurações do Instagram.

Passo 3: Obter Tokens de Acesso

Gere a URL de autorização 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()}`;
};
Enter fullscreen mode Exit fullscreen mode

Permissões Necessárias

Permissão Descrição
instagram_basic Perfil e mídias
instagram_content_publish Publicar mídias
instagram_manage_comments Ler/escrever comentários
instagram_manage_insights Analytics
pages_read_engagement Publicação
pages_manage_posts Publicar na Página

Passo 4: Trocar Token por Longa Duração

Troque token curto (1h) por longo (60 dias):

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(`Token expira: ${new Date(longLivedToken.expires_at * 1000)}`);
Enter fullscreen mode Exit fullscreen mode

Passo 5: Obter ID da Conta Comercial do Instagram

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;
};

const igAccountId = await getInstagramAccountId('12345678', accessToken);
console.log(`ID da Conta do Instagram: ${igAccountId}`);
Enter fullscreen mode Exit fullscreen mode

Passo 6: Fazer Chamadas Autenticadas da API

Use um cliente reutilizável:

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(`Erro da API do Instagram: ${error.error.message}`);
  }
  return response.json();
};

// Exemplo de uso
const account = await instagramRequest(`/me`);
console.log(`Conta do Instagram: ${account.username}`);
Enter fullscreen mode Exit fullscreen mode

Publicação de Conteúdo

Publicando uma Foto

const publishPhoto = async (igAccountId, photoData) => {
  // 1. Criar contêiner de mídia
  const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
    method: 'POST',
    image_url: photoData.imageUrl,
    caption: photoData.caption,
    location_id: photoData.locationId, // Opcional
    is_carousel_item: 'false'
  });
  const creationId = containerResponse.id;

  // 2. Publicar a mídia
  const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
    method: 'POST',
    creation_id: creationId
  });
  return publishResponse;
};

// Exemplo de uso
const post = await publishPhoto({
  igAccountId: '17841400000000000',
  imageUrl: 'https://example.com/image.jpg',
  caption: 'Animados para anunciar nosso novo produto! 🚀 #lançamento #inovação',
  locationId: '123456789'
});
console.log(`ID da mídia publicada: ${post.id}`);
Enter fullscreen mode Exit fullscreen mode

Publicando um Vídeo

const publishVideo = async (igAccountId, videoData) => {
  // 1. Criar contêiner de mídia
  const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
    method: 'POST',
    video_url: videoData.videoUrl,
    cover_url: videoData.coverUrl, // Miniatura opcional
    caption: videoData.caption,
    media_type: 'REELS', // ou 'VIDEO' para o feed
    share_to_feed: 'true'
  });
  const creationId = containerResponse.id;

  // Aguarda o processamento do vídeo
  await waitForVideoProcessing(creationId);

  // 2. Publicar a 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('Processamento de vídeo expirou');
    }
    await new Promise(resolve => setTimeout(resolve, 2000));
  }
  throw new Error('Tempo limite de processamento de vídeo');
};
Enter fullscreen mode Exit fullscreen mode

Publicando um Carrossel

const publishCarousel = async (igAccountId, carouselData) => {
  const children = [];
  // 1. Criar cada item do carrossel
  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);
  }
  // 2. Criar contêiner de carrossel
  const carouselContainerResponse = await instagramRequest(`/${igAccountId}/media`, {
    method: 'POST',
    media_type: 'CAROUSEL',
    children: children.join(','),
    caption: carouselData.caption
  });
  const creationId = carouselContainerResponse.id;

  // 3. Publicar o carrossel
  const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
    method: 'POST',
    creation_id: creationId
  });
  return publishResponse;
};

// Exemplo de uso
const carousel = await publishCarousel('17841400000000000', {
  caption: 'Vitrine de produtos 2026',
  items: [
    { type: 'image', url: 'https://example.com/img1.jpg', caption: 'Produto 1' },
    { type: 'image', url: 'https://example.com/img2.jpg', caption: 'Produto 2' },
    { type: 'video', url: 'https://example.com/vid1.mp4', caption: 'Demonstração' }
  ]
});
Enter fullscreen mode Exit fullscreen mode

Tipos de Mídia

Tipo Parâmetros Uso
IMAGEM image_url, legenda Post de foto
VÍDEO video_url, cover_url, legenda Post de vídeo
REELS video_url, cover_url, legenda, share_to_feed Reels
CARROSSEL children (array), legenda Múltiplas mídias

Recuperando Mídia e Insights

Obtendo Mídia do Usuário

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;
};

const media = await getUserMedia('17841400000000000');
media.data.forEach(item => {
  console.log(`${item.media_type}: ${item.caption}`);
  console.log(`Curtidas: ${item.like_count}, Comentários: ${item.comments_count}`);
  console.log(`URL: ${item.permalink}`);
});
Enter fullscreen mode Exit fullscreen mode

Obtendo Insights de Mídia

const getMediaInsights = async (mediaId) => {
  const response = await instagramRequest(`/${mediaId}/insights`, {
    fields: 'impressions,reach,engagement,saved,video_views,profile_visits,follows'
  });
  return response;
};

const insights = await getMediaInsights('17890000000000000');
insights.data.forEach(metric => {
  console.log(`${metric.name}: ${metric.values[0].value}`);
});
Enter fullscreen mode Exit fullscreen mode

Métricas de Insights Disponíveis

Métrica Descrição Tipos de Mídia
impressões Visualizações totais Todos
alcance Contas únicas alcançadas Todos
engajamento Curtidas + comentários + salvamentos Todos
salvos Quantas vezes salvo Todos
visualizações_de_vídeo Visualizações vídeo 3+ seg Vídeo, Reels
reproduções Reproduções totais Vídeo, Reels
visitas_ao_perfil Visitas ao perfil Todos
seguidores Seguidores ganhos Todos
comentários Total de comentários Todos
contagem_de_curtidas Total de curtidas Todos

Obtendo Insights da Conta

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;
};

// Exemplo: últimos 30 dias
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}`);
  });
});
Enter fullscreen mode Exit fullscreen mode

Métricas Nível de Conta

Métrica Descrição
impressões Visualizações de perfil + posts
alcance Contas únicas alcançadas
visualizações_de_perfil Visitas ao perfil
cliques_no_site Cliques no link da bio
contatos_por_email Toques no botão de e-mail
cliques_em_chamada_telefônica Toques no botão de telefone
cliques_em_mensagem_de_texto Toques em SMS
cliques_em_obter_direções Cliques no endereço
contagem_de_seguidores Total de seguidores
cidade_da_audiência Cidades dos seguidores
país_da_audiência Países dos seguidores
gênero_idade_da_audiência Demografia

Gerenciamento de Comentários

Obtendo Comentários

const getMediaComments = async (mediaId, limit = 50) => {
  const response = await instagramRequest(`/${mediaId}/comments`, {
    fields: 'id,text,timestamp,username,hidden',
    limit: limit.toString()
  });
  return response;
};

const comments = await getMediaComments('17890000000000000');
comments.data.forEach(comment => {
  console.log(`@${comment.username}: ${comment.text}`);
  console.log(`Oculto: ${comment.hidden}`);
});
Enter fullscreen mode Exit fullscreen mode

Respondendo a Comentários

const replyToComment = async (mediaId, commentId, replyText) => {
  const response = await instagramRequest(`/${mediaId}/comments`, {
    method: 'POST',
    response_to: commentId,
    message: replyText
  });
  return response;
};

const reply = await replyToComment(
  '17890000000000000',
  '17900000000000000',
  'Obrigado pelo seu interesse! Verifique sua DM para mais detalhes.'
);
console.log(`Resposta publicada: ${reply.id}`);
Enter fullscreen mode Exit fullscreen mode

Ocultando Comentários

const hideComment = async (commentId) => {
  const response = await instagramRequest(`/${commentId}`, {
    method: 'POST',
    hide: 'true'
  });
  return response;
};

await hideComment('17900000000000000');
console.log('Comentário oculto');
Enter fullscreen mode Exit fullscreen mode

Excluindo Comentários

const deleteComment = async (commentId) => {
  await instagramRequest(`/${commentId}`, {
    method: 'DELETE'
  });
  console.log('Comentário excluído');
};
Enter fullscreen mode Exit fullscreen mode

Webhooks

Configurando Webhooks

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();
};
Enter fullscreen mode Exit fullscreen mode

Gerenciando Webhooks

const express = require('express');
const app = express();

// Verificar assinatura do 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) {
    console.log('Webhook verificado');
    res.status(200).send(challenge);
  } else {
    res.status(403).send('Verificação falhou');
  }
});

// Lidar com eventos de webhook
app.post('/webhooks/instagram', express.json(), async (req, res) => {
  const body = req.body;

  if (body.object !== 'instagram') {
    return res.status(404).send('Não encontrado');
  }

  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(`Novo comentário na mídia ${data.media_id}`);
  console.log(`De: ${data.from_id}`);
  console.log(`Texto: ${data.text}`);

  // Responder automaticamente ou moderar
  if (isSpam(data.text)) {
    await hideComment(data.id);
  }
}
Enter fullscreen mode Exit fullscreen mode

Campos de Webhook

Campo Gatilho
comentários Novo comentário ou resposta
menções Usuário menciona a conta
reações_a_mensagens Reação a Story
status_do_story Resposta/visualização de Story

Limite de Taxa

Compreendendo os Limites de Taxa

  • 200 chamadas/hora por app (compartilhado entre todos os usuários)
  • Descoberta de Negócios: 200/hora por usuário
  • Publicação de Conteúdo: limites por tipo de ação

Exceder limites: HTTP 400, subcódigo 613.

Melhores Práticas para Limite de Taxa

  1. Cache de respostas – evite buscas repetidas
  2. Agrupe requisições – use expansão de campos
  3. Use webhooks – atualizações em tempo real
  4. Implementação de backoff exponencial – para erros 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 de taxa atingido. Tentando novamente em ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Solução de Problemas Comuns

Problema: Token OAuth Expirado

Sintomas: Erro “token de acesso OAuth inválido”.

Soluções:

  1. Implemente renovação antes dos 60 dias
  2. Armazene a data de expiração e alerte o usuário
  3. Reautentique se expirar

Problema: Falha na Publicação de Mídia

Sintomas: Erro ao publicar.

Soluções:

  1. Verifique se a URL da imagem é pública
  2. Formato correto (JPEG, PNG, <8MB)
  3. Para vídeo: MP4, <1GB, <90s
  4. Aguarde processamento do vídeo

Problema: Insights Não Disponíveis

Sintomas: API retorna dados vazios.

Soluções:

  1. Certifique que a conta é Comercial ou Criador
  2. Aguarde 24-48h para preenchimento dos insights
  3. Verifique se há atividade suficiente

Lista de Verificação para Implantação em Produção

Antes do deploy, certifique-se de:

  • [ ] Contas de teste são Comercial/Criador
  • [ ] OAuth 2.0 com tokens longos implementado
  • [ ] Tokens armazenados de forma segura (criptografia)
  • [ ] Renovação automática de tokens
  • [ ] Webhooks com HTTPS
  • [ ] Gerenciamento de limite de taxa e fila
  • [ ] Tratamento de erros robusto
  • [ ] Logging de todas as chamadas
  • [ ] Fluxos para moderação de conteúdo
  • [ ] Testou com múltiplos tipos de contas

Casos de Uso no Mundo Real

Ferramenta de Agendamento de Mídias Sociais

  • Desafio: Postagem manual em 50+ contas de clientes
  • Solução: Agendamento e publicação automática via API
  • Resultado: 80% economia de tempo, cronograma consistente

Funcionalidades:

  • Calendário de conteúdo drag-and-drop
  • Publicação automática de fotos, vídeos, carrosséis
  • Sugestão de hashtags baseada no conteúdo

Automação de Atendimento ao Cliente

  • Desafio: Resposta lenta a clientes
  • Solução: Resposta automática via webhook
  • Resultado: Tempo médio de resposta: 5min; 90% satisfação

Funcionalidades:

  • Detecção de palavras-chave (preço, envio, disponibilidade)
  • Resposta automática com links
  • Escalonamento para humanos em casos complexos

Conclusão

A API de Gráficos do Instagram fornece acesso completo a recursos de contas de Negócios e Criadores. Pontos-chave para implementar:

  • Autenticação OAuth 2.0 (tokens de 60 dias)
  • Publicação de fotos, vídeos, Reels, carrosséis
  • Insights de engajamento, alcance, demografia
  • Webhooks para comentários/menções em tempo real
  • Limite de taxa exige controle e cache
  • Apidog otimiza teste de API e colaboração

Seção de Perguntas Frequentes (FAQ)

Como obtenho acesso à API do Instagram?

Crie uma conta de Desenvolvedor do Facebook, crie um app de Negócios, adicione Instagram Graph API e autentique via Facebook Login com as permissões certas.

Posso postar no Instagram automaticamente?

Sim. Use a API de publicação para fotos, vídeos, Reels e carrosséis em contas de Negócios e Criadores.

Quais tipos de contas do Instagram suportam a API?

Apenas contas de Negócios e Criadores. Contas pessoais não têm acesso total.

Como obtenho comentários do Instagram?

Use o endpoint de Comentários (/{media-id}/comments). Webhooks notificam em tempo real.

Quais são os limites de taxa do Instagram?

200 chamadas/hora por app. Alguns endpoints têm limites adicionais por usuário.

Posso publicar Stories via API?

Sim, Stories podem ser publicados via o fluxo de publicação como posts do feed.

Como acesso os Insights do Instagram?

Solicite permissão instagram_manage_insights no OAuth. Use o endpoint de Insights para métricas.

Posso responder a comentários automaticamente?

Sim, via API de Comentários. Automação é comum para atendimento ao cliente.


Dúvidas ou sugestões? Deixe seu comentário abaixo!

Top comments (0)