API v1 · Instagram oficial (Meta)
API do Genio Hub
Conecte seu CRM, ERP ou chatbot ao Instagram sem implementar login, tokens e webhooks da Meta. Envie Direct, responda comentários, publique e leia estatísticas com uma chave por conta.
https://hub.genialise.com/v11. Conecte o Instagram
No painel, em Contas, clique em Conectar Instagram.
2. Copie a chave
Na conta, abra Avançado e copie a chave gk_live_…
3. Faça a primeira chamada
Chame /v1/me e confira a conta e as permissões.
curl https://hub.genialise.com/v1/me \
-H "Authorization: Bearer gk_live_SUA_CHAVE"Autenticação
Cada conta do Instagram conectada tem uma chave própria, que começa com gk_live_. Envie-a em todas as requisições no cabeçalho Authorization. A chave só acessa a própria conta e o token da Meta nunca sai da plataforma.
Guarde a chave no servidor, nunca no navegador ou no app. Se ela vazar, gere uma nova no painel: a antiga para de funcionar na hora.
Authorization: Bearer gk_live_SUA_CHAVE
# ou
X-API-Key: gk_live_SUA_CHAVEPermissões da chave
Cada chave tem permissões, marcadas no painel. Sem a permissão do endpoint, a resposta é 403.
| Permissão | Libera | Endpoints |
|---|---|---|
| messages:send | Enviar mensagens no Direct | /send |
| comments:reply | Responder comentários (no Direct e em público) | /private-reply, /comment-reply |
| media:publish | Publicar e agendar posts, reels, stories e carrosséis | /publish |
| media:read | Ler publicações e a cota de publicação | /media, /publishing-limit |
| insights:read | Ler estatísticas | /insights |
Conta
Conta da chave
/v1/mequalquer chaveRetorna a conta do Instagram ligada à chave, o modo de atendimento e as permissões da chave. Útil para testar a integração.
curl "https://hub.genialise.com/v1/me" \
-H "Authorization: Bearer gk_live_SUA_CHAVE"{
"instance_id": "4b0b6f0e-2c1f-4a51-9a0e-6c2a7d1e9f10",
"ig_user_id": "17841400000000000",
"username": "sualoja",
"account_type": "BUSINESS",
"mode": "hybrid",
"scopes": [
"messages:send",
"comments:reply",
"media:publish",
"media:read",
"insights:read"
]
}Direct
Enviar Direct
/v1/sendmessages:sendEnvia uma mensagem de texto no Direct para quem falou com a conta nas últimas 24 horas. Aceita um botão de link opcional.
Corpo (JSON)
recipient_idstringobrigatórioID da pessoa no Instagram (IGSID), recebido no webhook de mensagens.
textstringobrigatórioTexto da mensagem. Até 1.000 caracteres.
button_titlestringopcionalTítulo do botão (até 20 caracteres). Exige button_url.
button_urlstring (URL)opcionalLink aberto pelo botão.
- Fora da janela de 24 horas a Meta recusa o envio com erro 400.
curl -X POST "https://hub.genialise.com/v1/send" \
-H "Authorization: Bearer gk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"recipient_id": "6812345678901234",
"text": "Olá! Segue o nosso catálogo.",
"button_title": "Ver catálogo",
"button_url": "https://sualoja.com/catalogo"
}'{
"recipient_id": "6812345678901234",
"message_id": "aWdfZAG1faWQ6MTc4NDE0MDA..."
}Comentários
Responder comentário no Direct
/v1/private-replycomments:replyEnvia uma mensagem privada no Direct para quem comentou um post ou reel. Uma resposta privada por comentário, em até 7 dias.
Corpo (JSON)
comment_idstringobrigatórioID do comentário, recebido no webhook comments.
textstringobrigatórioTexto da mensagem. Até 1.000 caracteres.
button_titlestringopcionalTítulo do botão (até 20 caracteres). Exige button_url.
button_urlstring (URL)opcionalLink aberto pelo botão.
- A Meta limita as respostas privadas por conta por hora. Picos acima do limite devolvem erro de limite: tente de novo mais tarde.
curl -X POST "https://hub.genialise.com/v1/private-reply" \
-H "Authorization: Bearer gk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"comment_id": "17890000000000000",
"text": "Te mandei o link aqui! 💌",
"button_title": "Abrir link",
"button_url": "https://sualoja.com/oferta"
}'{
"recipient_id": "6812345678901234",
"message_id": "aWdfZAG1faWQ6MTc4NDE0MDA..."
}Publicação
Publicar ou agendar
/v1/publishmedia:publishPublica imagem, reel, story ou carrossel a partir de URLs públicas. Com scheduled_at no futuro, o post é agendado e a resposta é 202.
Corpo (JSON)
typeIMAGE | REELS | STORIES | CAROUSELobrigatórioTipo da publicação.
urlstring (URL)opcionalAtalho para um único arquivo (IMAGE, REELS e STORIES).
itemsarray<{ url, kind? }>opcionalArquivos do carrossel (2 a 10). kind = image | video; se omitido, .mp4 e .mov viram vídeo.
captionstringopcionalLegenda (até 2.200 caracteres). Ignorada em stories.
scheduled_atstring (ISO 8601)opcionalData e hora com fuso, por exemplo 2026-11-01T18:00:00-03:00.
- Sem scheduled_at, a publicação é imediata e a resposta é { id, config_issue }.
- config_issue vem preenchido quando a Meta publica sem aplicar algo, por exemplo CAPTION_NOT_ATTACHED. Confira antes de considerar o post perfeito.
- Antes de publicar, a cota diária da conta é conferida. Sem cota, a resposta é 429.
curl -X POST "https://hub.genialise.com/v1/publish" \
-H "Authorization: Bearer gk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"type": "CAROUSEL",
"items": [
{
"url": "https://cdn.sualoja.com/1.jpg"
},
{
"url": "https://cdn.sualoja.com/2.mp4"
}
],
"caption": "Nova coleção ✨",
"scheduled_at": "2026-11-01T18:00:00-03:00"
}'{
"scheduled_post_id": "9a7c2e10-55b1-4d8e-8f0e-1b2c3d4e5f60",
"status": "pending",
"scheduled_at": "2026-11-01T21:00:00.000Z"
}Publicação
Listar publicações
/v1/mediamedia:readLista as publicações mais recentes da conta, com legenda, tipo e link.
curl "https://hub.genialise.com/v1/media" \
-H "Authorization: Bearer gk_live_SUA_CHAVE"{
"data": [
{
"id": "17900000000000000",
"caption": "Nova coleção ✨",
"media_type": "CAROUSEL_ALBUM",
"media_product_type": "FEED",
"permalink": "https://www.instagram.com/p/XXXX/",
"timestamp": "2026-10-26T15:00:00+0000"
}
]
}Publicação
Cota de publicação
/v1/publishing-limitmedia:readMostra quantas publicações a conta já usou nas últimas 24 horas e o total permitido pela Meta.
curl "https://hub.genialise.com/v1/publishing-limit" \
-H "Authorization: Bearer gk_live_SUA_CHAVE"{
"data": [
{
"quota_usage": 3,
"config": {
"quota_total": 50,
"quota_duration": 86400
}
}
]
}Estatísticas
Estatísticas
/v1/insightsinsights:readMétricas da conta (alcance, visualizações, interações, seguidores), das últimas publicações e números da própria plataforma no período.
Parâmetros de consulta
days7 | 30opcionalPeríodo em dias. Padrão: 7.
- Os dados da Meta ficam em cache por 10 minutos por conta e período.
curl "https://hub.genialise.com/v1/insights?days=7" \
-H "Authorization: Bearer gk_live_SUA_CHAVE"{
"days": 7,
"since": "2026-10-19",
"until": "2026-10-26",
"account": {
"followers": 12840,
"mediaCount": 312,
"metrics": {
"reach": 45210,
"views": 98110,
"total_interactions": 3120,
"accounts_engaged": 2210
}
},
"media": [
{
"id": "17900000000000000",
"type": "REELS",
"caption": "Nova coleção ✨",
"permalink": "https://www.instagram.com/reel/XXXX/",
"thumbnail": null,
"timestamp": "2026-10-25T18:00:00+0000",
"metrics": {
"reach": 8100,
"likes": 640,
"comments": 88,
"saved": 52,
"shares": 31
}
}
],
"platform": {
"directReceived": 420,
"aiReplies": 310,
"commentDms": 690,
"queuePending": 0
},
"cachedAt": "2026-10-26T15:30:00.000Z"
}Webhooks
Nos modos API e Híbrido, cada evento da conta (mensagens, comentários, cliques em botões, leituras e reações) chega ao seu endpoint como POST, no formato original da Meta, com o campo extra genial. Cadastre a URL no painel, em Avançado.
Cabeçalhos enviados
X-Genial-EventstringobrigatórioTipo do evento: messages, comments, messaging_postbacks…
X-Genial-DeliveryuuidobrigatórioID da entrega. Use para ignorar repetições.
X-Genial-Signaturet=…,v1=…obrigatóriov1 = HMAC-SHA256 do texto "{t}.{corpo bruto}" com o segredo do webhook.
- • Responda 2xx em até 10 segundos e processe depois, em segundo plano.
- • Falhas são reenviadas até 6 vezes, com espera crescente (até cerca de 2 horas).
- • Valide a assinatura com o corpo bruto, antes de converter o JSON.
import crypto from "node:crypto";
// rawBody: o corpo exatamente como chegou (string), antes de JSON.parse
export function isValidGenioHubSignature(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}{
"object": "instagram",
"entry": [
{
"id": "17841400000000000",
"time": 1761490000000,
"messaging": [
{
"sender": {
"id": "6812345678901234"
},
"recipient": {
"id": "17841400000000000"
},
"timestamp": 1761490000000,
"message": {
"mid": "aWdfZAG1faWQ6MTc4NDE0MDA...",
"text": "Oi! Qual o preço?"
}
}
]
}
],
"genial": {
"instance_id": "4b0b6f0e-2c1f-4a51-9a0e-6c2a7d1e9f10",
"field": "messages",
"ig_user_id": "17841400000000000",
"username": "sualoja"
}
}Limites e regras da Meta
Janela de 24 horas
O Direct só pode ser enviado até 24 horas depois da última mensagem da pessoa.
Uma resposta privada por comentário
Em até 7 dias após o comentário. Repetições são recusadas pela Meta.
Respostas privadas por hora
A Meta limita por conta (referência: 750 por hora). No painel, o excedente espera na fila.
Cota de publicação
Até 50 publicações em 24 horas por conta (consulte /publishing-limit).
Sem mensagens em massa
Não é possível iniciar conversa com quem não falou com a conta.
Mídia pública
As URLs de publicação precisam ser públicas; vídeos em .mp4 ou .mov.
Erros
Os erros usam os códigos HTTP padrão e um corpo JSON com a mensagem.
| Status | Significado | O que fazer |
|---|---|---|
| 400 | Requisição inválida | JSON inválido ou campo fora do formato. O corpo traz issues com o campo e o motivo. |
| 401 | Não autenticado | Chave ausente ou inválida. Envie Authorization: Bearer gk_live_... |
| 403 | Sem permissão | A chave não tem a permissão do endpoint, ou a conta do Instagram está desconectada. |
| 404 | Endpoint inexistente | Confira o caminho na lista de endpoints. |
| 405 | Método errado | Use o método indicado (GET ou POST). |
| 429 | Limite atingido | Cota de publicação esgotada ou limite da Meta. Tente de novo mais tarde. |
| 4xx/5xx da Meta | Erro repassado da Meta | Quando a Meta recusa, devolvemos o mesmo status e o corpo original dela. |
{
"error": {
"message": "This API key does not have the media:publish scope.",
"type": "GenialApiException",
"code": 403
}
}
Comentários
Responder comentário publicamente
/v1/comment-replycomments:replyPublica uma resposta visível no próprio comentário.
Corpo (JSON)
comment_idstringobrigatórioID do comentário.
textstringobrigatórioTexto da resposta. Até 2.200 caracteres.