Resumo
O Sonarview Hub publica os artigos no seu blog chamando um endereço (webhook) que o seu site expõe. Não hospedamos o seu blog e não guardamos o artigo publicado: quando o post é publicado, enviamos os dados dele para o seu site, e o seu site decide como salvar e exibir.
Este artigo tem duas partes. A primeira é para quem usa o Hub. A segunda é a especificação técnica, para o desenvolvedor do site.
Antes de tudo: nós não hospedamos o seu blog
Esta é a primeira dúvida de quase todo desenvolvedor, e ela muda o desenho inteiro da integração, então vem antes de qualquer detalhe técnico.
O blog continua sendo o site de vocês, no domínio de vocês, na infraestrutura de vocês. Não servimos páginas, não há proxy reverso, não há CNAME apontando para nós, não há subdomínio nosso, não há whitelabel de hospedagem.
O que fazemos é entregar o conteúdo: o Hub planeja, escreve com inteligência artificial, aprova e agenda o artigo; na hora da publicação, ele envia os dados do post para um endereço que o seu site expõe. A partir daí o artigo é do seu site: a URL, o visual, o cache, o sitemap e o SEO são construídos por vocês.
Consequência prática, e é uma boa notícia: vocês mantêm o domínio, o layout e a autoridade de SEO do próprio site. O artigo nasce no seu domínio, não em um domínio nosso que precisaria redirecionar depois.
Parte 1: como conectar (para quem usa o Hub)
-
Peça ao desenvolvedor do seu site o endereço do webhook e a chave de segurança. A segunda parte deste artigo é exatamente o que ele precisa para criar os dois.
-
No Hub, vá em Configurações › Redes sociais › Conexão das redes.
-
No cartão Blog, clique em Conectar.
-
Cole o endereço do webhook e a chave. A chave fica guardada criptografada e nunca volta a aparecer na tela.
-
Clique em Conectar Blog.
Pronto. A partir daí, todo post de blog que você publicar ou agendar vai para o seu site.
Até setembro de 2026 essa tela ficava em Postar › Canais. Ela passou para Configurações, junto com os outros ajustes da plataforma. O que ela faz é o mesmo.
Se o blog não estiver conectado, o post não é publicado e o Hub avisa: Blog não conectado. Configure o webhook do blog em Configurações › Redes sociais › Conexão das redes. Nunca publicamos em outro lugar por engano.
Parte 2: especificação para o desenvolvedor
1. O modelo é push. Não existe API nossa para você consultar.
Nós chamamos o endpoint de vocês quando um post é publicado. Não há REST nem GraphQL de leitura no lado do Hub, não há endpoint público de posts e não há API reference para consumo. Consequência prática: não existe reconciliação periódica, e a fonte da verdade do que está no ar é o banco de vocês.
2. Autenticação: chave estática no cabeçalho
x-api-key: a chave que você definiu e o cliente colou no Hub
Não é OAuth e não é HMAC. É uma chave estática, escolhida por vocês, colada pelo cliente na tela de conexão das redes. Ela é guardada criptografada no nosso banco e enviada em cada requisição.
Recomendações para o endpoint de vocês: responder 401 quando a chave não casar, comparar em tempo constante e aceitar somente HTTPS. Se a chave vazar, o cliente troca na tela e o próximo envio já usa a nova.
O campo da chave é opcional no Hub. Se o seu endpoint não exigir autenticação, o cabeçalho vai vazio. Não recomendamos: um endpoint aberto aceita post de qualquer um.
3. O que chega quando um post é publicado
POST https://seublog.com.br/api/posts/incoming Content-Type: application/json x-api-key: a chave que você definiu
{ "title": "Como organizar a produção sem parar a fábrica", "slug": "como-organizar-a-producao-sem-parar-a-fabrica", "content": "## Subtítulo\n\nParágrafo em **Markdown**.\n\n<div class=\"aspect-video\"><iframe src=\"https://www.youtube.com/embed/XXXXXXXXXXX?rel=0\"></iframe></div>\n\nOutro parágrafo.", "excerpt": "Resumo de até 160 caracteres, texto puro.", "faq": [ { "question": "Quanto tempo leva?", "answer": "Entre duas e quatro semanas." } ], "coverImage": "data:image/png;base64,iVBORw0KGgo...", "category": "Conteúdo", "authorName": "Sonar Labs", "authorRole": "Equipe Sonar Labs", "authorImage": "/icon.png", "publishDate": "2026-07-30T14:00:00.000Z" }
4. Campo por campo
| Campo | Tipo | O que esperar |
|---|---|---|
title | string | Título do post. |
slug | string | Sugestão gerada por nós a partir do título: minúsculas, acentos removidos, o que não é letra ou número vira hífen. Veja o item 7. |
content | string | Markdown com HTML embutido. Parágrafos separados por linha em branco real, subtítulos com ##. Quando o post nasce de um vídeo do YouTube, injetamos uma div com um iframe do player dentro do texto. O renderizador precisa aceitar HTML inline no Markdown. |
excerpt | string | Resumo derivado do corpo, texto puro, no máximo 160 caracteres. |
faq | array ou null | Perguntas e respostas geradas pela inteligência artificial, no formato [{question, answer}]. Pode vir null ou ausente. Serve para montar o bloco de perguntas frequentes e o dado estruturado FAQPage. |
coverImage | string ou null | Pode ser uma URL http(s) ou um data URI em base64. Imagem que mora no armazenamento do Hub é convertida em base64 para poder renderizar no domínio de vocês; imagem de CDN externo vai como URL. Pode vir null. Se vocês guardarem em banco, atenção ao tamanho do base64: prefiram gravar o arquivo e guardar o caminho. |
category | string | Hoje é sempre Conteúdo. Ainda não é escolhida pelo cliente. |
authorName, authorRole, authorImage | string ou null | Veja o item 12: hoje o valor depende de como o post foi publicado. Recomendamos não confiar nesses campos e usar o autor padrão do site de vocês. |
publishDate | string ISO 8601 | O instante real da publicação, em UTC. No caminho agendado enviamos o momento do envio, e não o horário que o cliente agendou. Isso é de propósito: uma data no futuro faria o blog tratar o post como agendado e ele não apareceria. |
5. O que o seu endpoint deve responder
-
HTTP 2xx significa publicado. Se o corpo trouxer um identificador no campo
id, nós guardamos e usamos na remoção. -
Qualquer resposta que não seja 2xx é tratada como falha. Lemos
{"error": "mensagem"}do corpo e mostramos essa mensagem ao cliente na tela, além de criar uma notificação. Escreva uma mensagem útil e sem jargão: quem vai ler é a pessoa que publicou, não um desenvolvedor. -
Não há retentativa automática. Uma falha marca o agendamento como falho e notifica o cliente, que republica quando quiser.
-
Responda rápido. Se o seu endpoint precisa de processamento longo (gerar imagens, invalidar cache), aceite com 2xx e faça o resto em fila.
6. Quando um post é removido
O mesmo endereço recebe o DELETE. Enviamos um dos dois: o id que vocês devolveram na criação, se o tivermos guardado, ou o slug. Aceitem os dois.
DELETE https://seublog.com.br/api/posts/incoming Content-Type: application/json x-api-key: a chave que você definiu
{ "id": "o-id-que-voce-devolveu" } // preferido { "slug": "como-organizar-a-producao" } // quando não temos o id
7. Slug e URL: quem decide é o site de vocês
Enviamos um slug sugerido. A URL final é decisão de vocês, inclusive o padrão do caminho. Podem ignorar o nosso slug e gerar o próprio. Se fizerem isso, devolvam o id na criação, porque a remoção por slug deixaria de casar.
Uma ressalva honesta: o nosso slug vem do título e não tem garantia de unicidade. Dois posts com o mesmo título geram o mesmo slug. Tratem a colisão no lado de vocês, com sufixo em umérico por exemplo.
Também não existe versionamento de URL: se o cliente editar o título no Hub, não recalculamos nem avisamos vocês. Veja o item 10.
8. Volume e limites
Não há limite a se preocupar. Vocês recebem uma requisição por post publicado, no momento em que ele é publicado. O caminho agendado é verificado a cada minuto e publica os posts vencidos um a um, em série. Um cliente que agende cinquenta posts para o mesmo minuto gera cinquenta requisições sequenciais, não simultâneas.
9. SEO, Open Graph e dados estruturados
Não enviamos metaTitle, metaDescription, tags Open Graph nem JSON-LD. O que vocês têm para montar isso é title, excerpt, coverImage, faq e publishDate. O caminho recomendado:
-
titlevira o<title>e oog:title. -
excerptvira ameta descriptione oog:description. -
coverImagevira oog:image. Se vier em base64, salvem o arquivo e usem a URL pública dele: base64 não serve comoog:image. -
faq, quando vier, alimenta o dado estruturado FAQPage. -
O
BlogPostingdo schema.org é montado por vocês, compublishDatecomodatePublished.
Uma observação sobre o corpo: o texto que a inteligência artificial gera não deve conter rótulos de metadado (por exemplo Meta Description:) dentro do content. Se vocês virem um rótulo desses no texto, abram um chamado com um exemplo: o Hub remove esses rótulos antes de publicar, e queremos saber quando um escapa.
10. Sitemap, edição e cache
-
Não geramos sitemap.xml para o site de vocês. O post vive no site de vocês, então o sitemap é de vocês. O gancho natural é gerar ou revalidar o sitemap ao receber um
POSTou umDELETE. -
Não existe webhook de edição. Editar o texto de um post já publicado no Hub não avisa vocês. Se o cliente precisa corrigir um artigo no ar, hoje o caminho é remover e publicar de novo.
-
Não existe webhook de despublicar. Só criação e remoção.
-
Não há invalidação de cache orquestrada. Como não há webhook de edição, invalidem o cache no recebimento do
POSTe doDELETE, que são os dois momentos em que sabemos que algo mudou.
11. Ambiente de teste
Não existe sandbox. O Hub não distingue produção de teste: ele chama a URL configurada. O que dá para fazer, e funciona bem:
-
Aponte o webhook para uma URL de homologação de vocês, ou para um túnel local.
-
Publique um post de teste pelo Hub.
-
Confira o que chegou e ajuste.
-
Quando estiver certo, troque a URL para a de produção em Configurações › Redes sociais › Conexão das redes.
Trocar a URL não republica nada: vale para os próximos envios.
12. O autor do post: não confie no campo
Hoje o autor que chega depende de como o post foi publicado. No caminho agendado vem o nome da plataforma; no botão de publicar agora vem o nome do usuário que clicou. O authorImage pode vir como um caminho relativo, que no domínio de vocês aponta para um arquivo que não existe.
Recomendação: ignorem esses três campos e usem o autor padrão do site do cliente. Estamos tratando isso como um ajuste a fazer.
13. Custo: precisa de plano específico?
Não há cobrança específica pela integração com site externo e não existe pacote de blog a comprar. O blog conta como um canal conectado, na mesma cota dos outros canais (Instagram, LinkedIn, Facebook, Google Meu Negócio, Buffer).
Na prática: se o plano do cliente ainda tem canal disponível, conectar o blog não custa nada além do plano. Se a cota já estiver cheia, a tela recusa a conexão com a mensagem “Limite de canais sociais do seu plano atingido” e o caminho é mudar de plano na conta. Não há custo por post publicado nem por chamada ao webhook de vocês.
14. Checklist do endpoint
-
POSTeDELETEna mesma URL. -
Conferir o cabeçalho
x-api-keye responder 401 quando não casar. -
Aceitar
contentcomo Markdown com HTML inline. -
Aceitar
coverImagecomo URL, como data URI base64, e como null. -
Aceitar
faqausente ou null. -
Devolver 2xx com um
idna criação. -
Em erro, devolver
{"error": "mensagem para humano"}com status diferente de 2xx. -
Aceitar o
DELETEporide porslug. -
Tratar colisão de slug.
-
Invalidar cache e revalidar o sitemap no
POSTe noDELETE.
Resumo do que ainda não existe
Para o desenvolvedor não projetar em cima de algo que não temos: não há API de leitura, webhook de edição, webhook de despublicar, sandbox, retentativa automática, sitemap gerado por nós, campos de SEO no payload nem unicidade garantida de slug.