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.

URL basehttps://hub.genialise.com/v1
  1. 1. Conecte o Instagram

    No painel, em Contas, clique em Conectar Instagram.

  2. 2. Copie a chave

    Na conta, abra Avançado e copie a chave gk_live_…

  3. 3. Faça a primeira chamada

    Chame /v1/me e confira a conta e as permissões.

Primeira chamada
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.

Cabeçalho
Authorization: Bearer gk_live_SUA_CHAVE
# ou
X-API-Key: gk_live_SUA_CHAVE

Permissões da chave

Cada chave tem permissões, marcadas no painel. Sem a permissão do endpoint, a resposta é 403.

PermissãoLiberaEndpoints
messages:sendEnviar mensagens no Direct/send
comments:replyResponder comentários (no Direct e em público)/private-reply, /comment-reply
media:publishPublicar e agendar posts, reels, stories e carrosséis/publish
media:readLer publicações e a cota de publicação/media, /publishing-limit
insights:readLer estatísticas/insights

Conta

Conta da chave

GET/v1/mequalquer chave

Retorna 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"
Resposta 200
{
  "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

POST/v1/sendmessages:send

Envia 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ório

ID da pessoa no Instagram (IGSID), recebido no webhook de mensagens.

textstringobrigatório

Texto da mensagem. Até 1.000 caracteres.

button_titlestringopcional

Título do botão (até 20 caracteres). Exige button_url.

button_urlstring (URL)opcional

Link 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"
}'
Resposta 200
{
  "recipient_id": "6812345678901234",
  "message_id": "aWdfZAG1faWQ6MTc4NDE0MDA..."
}

Comentários

Responder comentário no Direct

POST/v1/private-replycomments:reply

Envia 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ório

ID do comentário, recebido no webhook comments.

textstringobrigatório

Texto da mensagem. Até 1.000 caracteres.

button_titlestringopcional

Título do botão (até 20 caracteres). Exige button_url.

button_urlstring (URL)opcional

Link 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"
}'
Resposta 200
{
  "recipient_id": "6812345678901234",
  "message_id": "aWdfZAG1faWQ6MTc4NDE0MDA..."
}

Comentários

Responder comentário publicamente

POST/v1/comment-replycomments:reply

Publica uma resposta visível no próprio comentário.

Corpo (JSON)

comment_idstringobrigatório

ID do comentário.

textstringobrigatório

Texto da resposta. Até 2.200 caracteres.

curl -X POST "https://hub.genialise.com/v1/comment-reply" \
  -H "Authorization: Bearer gk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
  "comment_id": "17890000000000000",
  "text": "Enviamos no seu Direct! 💌"
}'
Resposta 200
{
  "id": "17891111111111111"
}

Publicação

Publicar ou agendar

POST/v1/publishmedia:publish

Publica 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ório

Tipo da publicação.

urlstring (URL)opcional

Atalho para um único arquivo (IMAGE, REELS e STORIES).

itemsarray<{ url, kind? }>opcional

Arquivos do carrossel (2 a 10). kind = image | video; se omitido, .mp4 e .mov viram vídeo.

captionstringopcional

Legenda (até 2.200 caracteres). Ignorada em stories.

scheduled_atstring (ISO 8601)opcional

Data 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"
}'
Resposta 202
{
  "scheduled_post_id": "9a7c2e10-55b1-4d8e-8f0e-1b2c3d4e5f60",
  "status": "pending",
  "scheduled_at": "2026-11-01T21:00:00.000Z"
}

Publicação

Listar publicações

GET/v1/mediamedia:read

Lista 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"
Resposta 200
{
  "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

GET/v1/publishing-limitmedia:read

Mostra 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"
Resposta 200
{
  "data": [
    {
      "quota_usage": 3,
      "config": {
        "quota_total": 50,
        "quota_duration": 86400
      }
    }
  ]
}

Estatísticas

Estatísticas

GET/v1/insightsinsights:read

Mé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 | 30opcional

Perí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"
Resposta 200
{
  "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ório

Tipo do evento: messages, comments, messaging_postbacks…

X-Genial-Deliveryuuidobrigatório

ID da entrega. Use para ignorar repetições.

X-Genial-Signaturet=…,v1=…obrigatório

v1 = 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));
}
Exemplo de evento
{
  "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.

StatusSignificadoO que fazer
400Requisição inválidaJSON inválido ou campo fora do formato. O corpo traz issues com o campo e o motivo.
401Não autenticadoChave ausente ou inválida. Envie Authorization: Bearer gk_live_...
403Sem permissãoA chave não tem a permissão do endpoint, ou a conta do Instagram está desconectada.
404Endpoint inexistenteConfira o caminho na lista de endpoints.
405Método erradoUse o método indicado (GET ou POST).
429Limite atingidoCota de publicação esgotada ou limite da Meta. Tente de novo mais tarde.
4xx/5xx da MetaErro repassado da MetaQuando a Meta recusa, devolvemos o mesmo status e o corpo original dela.
Formato do erro
{
  "error": {
    "message": "This API key does not have the media:publish scope.",
    "type": "GenialApiException",
    "code": 403
  }
}