Por que o Instagram recusou o post, se o artigo entrou no ar no WordPress sem erro nenhum? Porque a falha não está no WordPress: está na resposta da Graph API, que devolve dois números e só o segundo explica alguma coisa. O code agrupa famílias inteiras de falha; o error_subcode aponta o caso. Quem lê só o primeiro republica o artigo, vê falhar de novo e conclui que a API caiu.
9004 vem com uma mensagem que não descreve o problema
A resposta chega assim, e o campo que interessa não é o primeiro:
{"error":{"message":"Only photo or video can be accepted as media type.","type":"OAuthException","code":9004,"error_subcode":2207052,"is_transient":false,"error_user_title":"Media download has failed. The URI doesn't meet requirements.","error_user_msg":"The media could not be fetched from this URI: https://seusite.com.br/wp-content/uploads/..."}}
A frase que está em message fala de tipo de mídia aceito e manda todo mundo conferir se o arquivo é JPEG. O campo que descreve o que aconteceu é o error_user_msg: a Meta tentou baixar a imagem do endereço que você mandou e não conseguiu. O tipo de mídia não entrou na conta em momento nenhum.
Daí em diante existem dois casos bem diferentes, e eles se separam por um detalhe de pontuação. Num relato aberto em 13 de março de 2026 no repositório do Mixpost, o campo terminava em from this URI: . Não havia endereço nenhum depois dos dois-pontos. O autor chegou à conclusão certa: o aplicativo enviava o parâmetro image_url vazio, e a Meta respondeu com um erro sobre mídia porque foi o que recebeu. Endereço ausente na mensagem é problema do seu lado da linha.
O segundo caso é o inverso. Em 27 de abril de 2026, um relato no repositório do Postiz trazia o mesmo par 9004 e 2207052, com o endereço completo presente na mensagem. O autor tinha verificado o que dava: curl -sI devolvia HTTP 200 e Content-Type: image/jpeg, e a mesma requisição com o agente facebookexternalhit/1.1 respondia 200 limpo. O arquivo, submetido com os mesmos parâmetros, foi aceito pelo X, pelo Facebook e pelo LinkedIn. Só o Instagram recusou.
Separar os dois leva trinta segundos: leia o texto depois de URI: e veja se existe um endereço ali. Existindo, abra esse endereço com curl -sI e repita a chamada passando o agente facebookexternalhit/1.1, que é com ele que a Meta busca a imagem. Duas respostas 200 com tipo de imagem aceito tiram seu site da lista de suspeitos e jogam o caso para a última seção.
190 e 102 são o mesmo assunto em graus diferentes
Um token do Instagram de curta duração vale 1 hora; o de longa duração, 60 dias. Como 60 dias não coincidem com nada no calendário de ninguém, o vencimento pega a equipe de surpresa, quase sempre num fim de semana, e a esteira fica parada até segunda.
O código 190 diz literalmente que o token expirou. O 102 é mais largo: a documentação da Meta registra que, não vindo subcódigo, o estado de login ou o token expirou, foi revogado ou é inválido de alguma outra forma. A diferença importa porque os dois pedem ações diferentes, e é o subcódigo que decide qual.
Três subcódigos se resolvem refazendo a autorização, porque são credencial vencida ou aplicativo removido: 463, 467 e 458. Os outros três não se resolvem assim, e é aí que as tardes são perdidas. O 460 significa que a pessoa trocou a senha da conta do Facebook. O 459 e o 464 dizem que a conta dela tem pendência a resolver dentro do próprio Facebook. O 492 é o mais traiçoeiro: ela não tem o papel adequado na Página, o que aparece quando alguém mexeu nas permissões e não avisou quem cuida do site.
Leia o error_subcode antes de tentar qualquer reconexão. Com 460 ou 492, refazer o login com a mesma conta devolve exatamente o mesmo erro, porque o que mudou foi a senha ou o papel na Página. Sem subcódigo nenhum junto do 102, trate como token vencido e refaça a autorização.
10 e a faixa de 200 a 299 são mudança de regra, não erro de código
A Meta descreve o código 10 e toda a faixa de 200 a 299 com a mesma frase: a permissão não foi concedida ou foi removida. Ler isso como bug do seu lado é o caminho mais rápido para perder o dia. Quase sempre o que mudou foi a lista de permissões exigida pela plataforma, e ela mudou duas vezes em menos de um ano.
Em 3 de dezembro de 2025 a Meta liberou a exclusão de mídia do Instagram pela API e criou a permissão instagram_manage_contents para isso. Em 22 de abril de 2026 chegou a API de curtidas e comentários, com a permissão instagram_manage_engagement. Nenhuma das duas tem relação com publicar artigo, e é por isso que aparecem no diagnóstico: quem autorizou o aplicativo antes dessas datas não concedeu nada disso, e qualquer recurso que encoste nelas falha com 10 sem que uma linha do seu código tenha mudado.
Compare duas listas: as permissões que a autorização atual concedeu e as que o endereço chamado exige hoje na documentação. Havendo uma permissão nova no meio, a data em que ela apareceu no changelog costuma bater com a semana em que o erro começou. Olhe também qual versão a integração fixou: a v25.0 responde até 29 de julho de 2028, prazo longo o bastante para você esquecer que ela existe enquanto a documentação segue em frente.
O 200 que não é sucesso e o contêiner que falha depois
Publicar uma foto no Instagram pela API são duas chamadas: você cria um contêiner de mídia, depois manda publicar esse contêiner. A primeira devolve um identificador e um 200, e é aí que muita gente marca a tarefa como concluída no log. Baixar e processar a imagem acontece depois, fora da sua requisição.
O contêiner tem um campo de estado com cinco valores documentados. Três são rotina: IN_PROGRESS ainda processando, FINISHED pronto para publicar, PUBLISHED já publicado. Os outros dois são a falha que você procura. ERROR significa que o contêiner não completou o processo de publicação. EXPIRED significa que ele não foi publicado em 24 horas e expirou.
Os dois últimos produzem a queixa mais comum: o artigo saiu no blog, o post nunca apareceu e não há erro em lugar nenhum. Não há porque ninguém foi ler o estado. O EXPIRED tem causa banal: a segunda chamada não aconteceu, porque a fila de tarefas agendadas do WordPress não rodou ou porque o processo morreu.
Consulte o estado entre a criação e a publicação em vez de encadear as duas chamadas às cegas. Com ERROR, a causa raiz costuma ser a da primeira seção. Com EXPIRED, o problema é do seu agendamento e não da Meta, e os formatos que a API aceita nessa etapa estão em o que a API do Instagram deixa e o que não deixa automatizar.
80002 e o teto de publicação são dois limites que não se misturam
Confundir os dois leva a esperar o tempo errado. O primeiro é o limite de chamadas: a resposta do Instagram traz o cabeçalho X-Business-Use-Case-Usage, com quatro medidas dentro. call_count é o percentual de chamadas permitidas já feitas numa janela móvel de uma hora, total_cputime e total_time são percentuais de processamento, e estimated_time_to_regain_access é o tempo em minutos até as chamadas deixarem de ser barradas. Quando uma dessas medidas chega a 100, as chamadas podem passar a ser barradas, e o erro que o Instagram devolve nesse caso é o 80002.
O segundo limite é de outra natureza: uma conta pode publicar 100 posts pela API numa janela móvel de 24 horas, e um carrossel inteiro conta como um post só. Esse teto tem endereço próprio de consulta, GET /<IG_ID>/content_publishing_limit, e nenhuma relação com o cabeçalho de uso. Um blog diário nunca encosta nele. Uma agência que dispara a fila de vinte clientes de uma vez encosta no limite de chamadas muito antes de chegar perto do teto de publicações.
Do lado do Facebook os números são outros: 4 e 17 para excesso de chamadas do aplicativo e do usuário, 341 para limite do aplicativo atingido, 368 para bloqueio temporário por violação de política, que não é limite de volume e não passa com espera.
Leia o cabeçalho da resposta que falhou. Se estimated_time_to_regain_access vier com um número, é limitação de chamadas e esperar resolve. Se as medidas estiverem baixas e o erro persistir, o problema é o conteúdo da requisição, não o volume.
Quando o erro não é seu
Existe um caso em que a checagem inteira dá certo e o post continua sendo recusado. Uma discussão na comunidade de desenvolvedores da Meta, aberta em 2 de abril de 2026 e reativada entre os dias 19 e 27, reuniu relatos idênticos de 9004 com 2207052 vindos de aplicativos sem relação entre si. Um participante resumiu: nenhuma mudança de código ou de infraestrutura do lado deles. Imagens de alguns provedores grandes falhavam enquanto as de outros endereços passavam, e o problema se desfez sozinho por volta de 3 de abril, sem explicação pública.
Repare no is_transient daquele payload: vinha como false, ou seja, a Meta afirmava que o erro não era passageiro, num episódio que passou sozinho. Bom motivo para não tratar esse campo como veredicto.
Três sinais apontam para esse caso: o arquivo passa nas duas checagens da primeira seção, outra rede aceita o mesmo arquivo no mesmo minuto, e nada mudou do seu lado desde a última publicação que funcionou. Confirmados os três, republicar na mão é a pior reação: quando o serviço volta, você descobre que criou dois posts iguais. Registre o payload inteiro, espere e tente de novo mais tarde.
Isso pressupõe que alguém guardou o payload, e é aqui que o trabalho manual custa caro: a mensagem passa pela tela uma vez e some. O Post Ping guarda o erro exato devolvido pela Meta junto ao artigo que falhou, com o que foi publicado, onde e quando, o que transforma o diagnóstico deste artigo em leitura de registro. A renovação automática do acesso tira da mesa a família 190 e 102, a que mais derruba blog que publicou sem sobressalto por dois meses. Os dois estão descritos em recursos do plugin, e a esteira completa do artigo até o post no ar está em publicar do WordPress no Instagram e no Facebook automaticamente.
Para saber que a leitura foi correta, force o erro antes que ele aconteça sozinho. Troque o endereço da imagem por um que não existe e dispare a publicação: o retorno tem que ser 9004 com 2207052, e o endereço quebrado tem que aparecer depois de URI:. Volte o endereço certo e consulte o estado do contêiner antes de publicar: tem que vir FINISHED. Quem viu esses dois retornos uma vez, com calma, reconhece o próximo erro de verdade sem abrir a documentação.
