💼 Conta Business obrigatória
A Graph API do Instagram não publica em conta pessoal. Para postar via API você precisa de uma conta Business (ou Creator em casos pontuais, mas o caminho seguro é Business) vinculada a uma Facebook Page. Sem esses dois requisitos, nenhum endpoint de publicação responde — sempre 400 Bad Request.
Conversão é gratuita e leva minutos no app do Instagram. O ponto crítico é o vínculo com a Page: a permissão de publicação flui da Page → Instagram, não direto na conta IG.
# Passo a passo no app do Instagram
# 1. Configurações → Conta → Mudar para conta profissional
# 2. Escolher categoria (ex: "Software", "Mídia")
# 3. Selecionar "Empresa" (NÃO "Criador de conteúdo")
# 4. Vincular Facebook Page existente OU criar uma nova
# Verificar via Graph API que o vínculo existe
curl -G "https://graph.facebook.com/v21.0/me/accounts" \
-d "access_token=USER_TOKEN" \
-d "fields=id,name,instagram_business_account"
# {
# "data": [{
# "id": "1234567890",
# "name": "Minha Page",
# "instagram_business_account": { "id": "17841405822304914" }
# }]
# }
⚠️ Dica prática
Se o campo instagram_business_account vier vazio, o vínculo Page↔IG não foi feito corretamente. Volte no Meta Business Suite (business.facebook.com) e refaça o link em Configurações → Contas → Contas do Instagram. Esse é o erro #1 de quem tenta postar pela primeira vez.
Conceitos-chave
Tipo de conta IG com acesso à Graph API.
Ponte de permissão entre IG e a API.
ID numérico usado em todas as chamadas.
Painel Meta que gerencia o vínculo Page↔IG.
🏢 Meta App + App Review
Toda chamada à Graph API exige um Meta App registrado em developers.facebook.com. Para Instagram + Threads, o tipo correto é Business — não escolha "Consumer", as permissões necessárias nem aparecem lá.
Após criar o app, adicione os produtos: Instagram Graph API, Facebook Login for Business e, se for usar Threads, Threads API. Cada um tem suas próprias permissões e cada permissão sensível passa por App Review antes de funcionar para usuários que não sejam Admin/Dev/Tester do app.
# Roteiro de criação do app
# 1. developers.facebook.com → Meus Apps → Criar App
# 2. Tipo: "Business" (NÃO Consumer, NÃO Gaming)
# 3. Nome do app: ex. "Postiz Self-Hosted"
# 4. E-mail de contato + Business Account
# 5. Adicionar produtos:
# - Instagram Graph API
# - Facebook Login for Business
# - Threads API (se aplicável)
# Os identificadores ficam em Configurações → Básico
# App ID: 1234567890123456
# App Secret: nunca-exponha-isso-no-front
# Modo do app: Development (só Admin/Dev/Tester usa)
# → Live (após App Review aprovado)
📌 Modo Development vs Live
- Development: só funciona para contas adicionadas como Admin, Developer ou Tester no app. Útil para desenvolver e testar sem App Review.
- Live: qualquer usuário pode conectar, mas todas as permissões avançadas precisam estar aprovadas no App Review.
- Transição: só é possível mudar para Live após Business Verification completa.
Conceitos-chave
Container de credenciais e permissões.
Par usado no OAuth — secret só no backend.
APIs específicas que você ativa no app.
Validação da empresa (CNPJ, documentos).
🎫 Permissões essenciais
A Meta separa cada capacidade em uma permission scope distinta. Para um caso de uso típico de agendamento (publicar feed, ler insights, gerenciar a Page), você vai pedir 5 a 7 escopos — e cada um precisa de justificativa própria no App Review.
# Escopos OAuth para Instagram Business
# Mínimo viável para publicar feed:
pages_show_list # listar Pages do usuário
pages_read_engagement # ler dados da Page
pages_manage_posts # publicar na Page
instagram_basic # ler perfil/posts IG
instagram_content_publish # PUBLICAR no IG via API
# Insights / métricas (opcional mas comum):
instagram_manage_insights
# URL de autorização (Facebook Login for Business)
https://www.facebook.com/v21.0/dialog/oauth
?client_id=APP_ID
&redirect_uri=https://seu-host/oauth/callback
&scope=pages_show_list,pages_read_engagement,pages_manage_posts,
instagram_basic,instagram_content_publish
&response_type=code
# Troca code → long-lived token (server-side, usa App Secret)
curl -G "https://graph.facebook.com/v21.0/oauth/access_token" \
-d "client_id=APP_ID" \
-d "client_secret=APP_SECRET" \
-d "redirect_uri=https://seu-host/oauth/callback" \
-d "code=CODE_RECEBIDO"
✓ O que FAZER
- ✓Pedir apenas escopos que você realmente vai usar.
- ✓Trocar o
codepor token no backend, nunca no front. - ✓Converter para long-lived token (60 dias) e renovar antes de expirar.
- ✓Documentar justificativa de cada escopo para o App Review.
✗ O que NÃO fazer
- ✗Pedir
ads_management"só por garantia" — review nega. - ✗Expor o
App Secretem código que vai pro browser. - ✗Confiar em short-lived token (1h) em produção.
- ✗Usar OAuth tradicional — Meta migrou para Login for Business.
Conceitos-chave
Permissão granular pedida no OAuth.
Token de 60 dias, renovável server-side.
Token específico da Page para publicar IG.
Estado pós-review que libera o escopo no Live.
🔄 Fluxo 2-step: container + publish
Diferente de quase todas as outras APIs, o Instagram não publica em uma chamada só. O fluxo é: (1) criar um media container com a mídia + caption → (2) aguardar processamento → (3) chamar media_publish com o ID do container. Pular o passo 2 em vídeos é o erro mais comum.
# STEP 1 — Criar container (imagem)
curl -X POST "https://graph.facebook.com/v21.0/{IG_BUSINESS_ID}/media" \
-d "image_url=https://cdn.exemplo.com/foto.jpg" \
-d "caption=Lançamento de hoje! #produto" \
-d "access_token=PAGE_TOKEN"
# { "id": "17889455560051234" } ← container_id
# STEP 2 — (Para VÍDEO/REEL) checar status até FINISHED
curl -G "https://graph.facebook.com/v21.0/17889455560051234" \
-d "fields=status_code" \
-d "access_token=PAGE_TOKEN"
# { "status_code": "IN_PROGRESS" } ← aguardar
# { "status_code": "FINISHED" } ← pronto para publicar
# { "status_code": "ERROR" } ← falhou (ver status)
# STEP 3 — Publicar
curl -X POST "https://graph.facebook.com/v21.0/{IG_BUSINESS_ID}/media_publish" \
-d "creation_id=17889455560051234" \
-d "access_token=PAGE_TOKEN"
# { "id": "17912345678901234" } ← ID do post publicado
⏳ Dica prática
Para vídeo/Reel, faça polling com backoff: cheque status_code a cada 3-5s, até 60 segundos de espera máxima. Se publicar antes de FINISHED, a API retorna 9007 ("Media not ready") e o post entra em estado fantasma — não aparece no feed mas ocupa cota.
Para carrossel, repita o STEP 1 para cada slide (com is_carousel_item=true), depois crie um container-pai do tipo CAROUSEL referenciando os filhos e só então faça o media_publish.
Conceitos-chave
Rascunho temporário antes da publicação.
ID retornado no STEP 1, consumido no STEP 3.
IN_PROGRESS / FINISHED / ERROR.
25 publicações / 24h por conta IG.
🧵 Threads API (mesmo ecossistema)
Threads herda a infraestrutura do Instagram: mesmo Meta App, mesmo fluxo OAuth, mesmo modelo 2-step. A diferença é o host da API — graph.threads.net — e o conjunto de permissões próprias começando com threads_.
# Escopos Threads
threads_basic # ler perfil
threads_content_publish # publicar threads
threads_manage_replies # responder
threads_read_replies # ler respostas
threads_manage_insights # métricas
# STEP 1 — Criar container Threads
curl -X POST "https://graph.threads.net/v1.0/{THREADS_USER_ID}/threads" \
-d "media_type=TEXT" \
-d "text=Primeira thread via API 🧵" \
-d "access_token=THREADS_TOKEN"
# { "id": "1234567890" }
# STEP 2 — Publicar
curl -X POST "https://graph.threads.net/v1.0/{THREADS_USER_ID}/threads_publish" \
-d "creation_id=1234567890" \
-d "access_token=THREADS_TOKEN"
# { "id": "9876543210" }
# Encadear reply na mesma thread
curl -X POST "https://graph.threads.net/v1.0/{THREADS_USER_ID}/threads" \
-d "media_type=TEXT" \
-d "text=Segunda parte do thread..." \
-d "reply_to_id=9876543210" \
-d "access_token=THREADS_TOKEN"
📊 Particularidades do Threads
- Conta Threads: não exige Business — basta uma conta Threads ativa (vinculada ao Instagram).
- Host diferente:
graph.threads.net(nãograph.facebook.com). - Rate limit: 250 publicações/24h por usuário — mais generoso que IG.
- Tipos de mídia:
TEXT,IMAGE,VIDEOeCAROUSEL.
Conceitos-chave
Endpoint próprio do Threads.
TEXT / IMAGE / VIDEO / CAROUSEL.
Encadeia respostas em thread.
Mesma app cobre IG + Threads.
⚡ Dicas para acelerar o App Review
O App Review da Meta é o gargalo. Em média leva 4 a 6 semanas entre submissão e Advanced Access. Boa parte das rejeições é por screencast ruim ou justificativa genérica — e cada rejeição reseta o relógio.
⏱️ Timeline realista do App Review
Semana 0 — Preparação (2-5 dias)
Criar app, configurar produtos, escrever Privacy Policy e Terms, hospedar em URL pública estável.
Semana 1 — Business Verification (3-10 dias)
Submeter CNPJ + documentos no Business Manager. Sem isso, App Review nem começa.
Semana 2 — Submissão do Review (1-2 dias preparando)
Gravar screencast por permissão, escrever descrição detalhada, submeter no painel.
Semanas 3-4 — Análise da Meta (10-20 dias)
Revisor humano avalia o fluxo. Tempo varia muito com fila e qualidade da submissão.
Semanas 4-5 — Resposta (Aprovado ou Rejeitado)
Se aprovado → Advanced Access habilitado. Se rejeitado → leia o motivo e re-submeta (reseta o ciclo).
Semana 6 — App em Live (imediato após aprovação)
Mudar app de Development para Live no painel — qualquer usuário externo pode conectar.
🎥 Anatomia de um screencast aprovado
# Checklist do screencast (1 vídeo por permissão)
# Duração: 1-3 minutos por permissão
[00:00-00:10] Tela inicial do produto + login do usuário
[00:10-00:30] Clique em "Conectar Instagram" → tela OAuth da Meta
[00:30-00:50] Mostrar EXATAMENTE quais permissões são pedidas
[00:50-01:30] Demonstrar o USO REAL da permissão
(ex: publicar um post de teste se for content_publish)
[01:30-02:00] Mostrar o resultado (post no feed do IG)
[02:00-02:30] Narração explicando POR QUE o usuário se beneficia
# Pontos críticos
- Áudio com narração em INGLÊS (review é global)
- Resolução mínima 720p
- Mostrar a UI do SEU app, não terminal/Postman
- Cada permissão = vídeo separado
✓ O que ACELERA o review
- ✓Screencast em inglês, com narração clara.
- ✓Justificativa específica: "publica posts agendados em nome do usuário, autenticado via OAuth".
- ✓Privacy Policy + Terms em URL pública e estável.
- ✓Business Verification antes da submissão.
- ✓Conta de teste com dados reais já populados.
✗ O que GARANTE rejeição
- ✗Screencast em terminal/Postman sem mostrar UI.
- ✗"Quero a permissão X para futuras features" — sem caso de uso atual.
- ✗App ainda em
localhostou domínio temporário. - ✗Pedir
ads_*ou escopos que você não precisa. - ✗Privacy Policy genérica copiada de template.
Conceitos-chave
Auditoria humana das permissões pedidas.
Vídeo demonstrando uso real de cada escopo.
Pré-review — só Admin/Dev/Tester usa.
Pós-review — qualquer usuário pode conectar.
🎯 Resumo do Módulo
/me/accounts.pages_manage_posts, instagram_content_publish e companhia, sem excessos.graph.threads.net, escopos threads_*, modelo análogo ao IG.Próximo Módulo:
3.6 — Mastodon, Bluesky e Fediverse (o lado simples da força)