Visão geral

Webhooks

O Docsbook pode notificar seus sistemas sobre eventos que acontecem dentro de um espaço de trabalho — novo conteúdo indexado, traduções necessárias, perguntas feitas no chat, anomalias de tráfego e muito mais. Cada webhook é tipado: você se inscreve em um dos 18 eventos específicos, e o Docsbook só faz POST para sua URL quando esse evento exato ocorre.

Registrar um webhook e receber suas entregas não gera nenhum custo no saldo do projeto. As entregas que você reproduz ou testa manualmente são contabilizadas como egress, porque cada uma é uma chamada de saída que o Docsbook faz em seu nome.

Como funciona#

  1. Você registra um webhook com event_type, url e um secret opcional.
  2. Quando o evento ocorre, o Docsbook enfileira uma entrega (padrão outbox).
  3. O worker (cron da Vercel, a cada minuto) envia o corpo JSON via POST para sua URL.
  4. Nós tentamos novamente até 3 vezes com backoff exponencial (1s, 10s, 60s).

Formato da solicitação#

POST https://your-url.example.com
Content-Type: application/json
User-Agent: Docsbook-Webhooks/1.0
X-Docsbook-Event: content.indexed
X-Docsbook-Signature-256: sha256=<hex hmac of body>
X-Docsbook-Delivery: 12345
X-Docsbook-Attempt: 1
{
  "event": "content.indexed",
  "workspace_id": 42,
  "occurred_at": "2026-05-23T12:34:56.000Z",
  "data": { /* event-specific payload */ }
}

Verificando assinaturas#

import crypto from "node:crypto"
const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex")
if (expected !== req.headers["x-docsbook-signature-256"]) reject()

Uma resposta 2xx = entregue. Qualquer outra resposta aciona novas tentativas até que o orçamento de tentativas se esgote.

Vendo o que seu espaço de trabalho emite#

O painel Feeds no seu administrador mostra todos os eventos produzidos pelo espaço de trabalho, começando pelos mais recentes — incluindo eventos que nenhum alerta estava monitorando e todas as chamadas de ferramentas MCP feitas contra ele. Você não precisa ter um webhook cadastrado para ver o feed se encher, e esse é o objetivo: é assim que você descobre quais eventos seus documentos realmente emitem antes de decidir sobre o que deseja receber notificações. O feed é atualizado ao vivo — ele se atualiza sozinho a cada poucos segundos enquanto você o consulta, portanto não há um intervalo de tempo para selecionar nem nada que você precise lembrar de recarregar.

Escolher um feed#

A seção Feeds é aberta em uma página de cartões — um por feed, cada um com uma linha dizendo o que ele contém, além de um cartão Crie seu próprio feed no final. Abrir um cartão muda para o próprio feed, sem título ou link de retorno acima dele: você chegou aqui escolhendo um cartão, e a linha Feeds da barra lateral é o caminho de volta para eles.

Os mesmos feeds também são linhas sob essa seção da barra lateral, para alternar entre eles sem sair daquele que você está lendo — mas essa lista começa fechada. Passe o cursor sobre a linha Feeds e uma seta substitui o ícone; clique nela para mostrar até cinco feeds, começando pelos abertos mais recentemente, com Mostrar mais N para o restante, e o Docsbook lembrará se você a deixou aberta na próxima vez que voltar. O + que cria uma nova lista a partir de um filtro vazio aparece tanto nessa linha quanto como um cartão na galeria.

Sete feeds vêm integrados, então há algo para abrir na sua primeira visita antes de você salvar qualquer coisa própria: Eventos de leitores (tudo o que as pessoas que leram seus documentos fizeram — páginas lidas, pesquisas realizadas, perguntas feitas à IA, feedback enviado), Traduções (cada idioma gerado, desatualizado ou ainda necessário), Eventos de idioma (para quais idiomas os leitores alternam os documentos), Eventos de chat (perguntas feitas ao assistente de IA, quando ele não encontrou uma resposta, quais respostas receberam uma avaliação negativa), Feedback dos leitores (avaliações negativas e comentários, em uma página ou resposta), Chamadas MCP (todas as chamadas tarifadas feitas por um agente) e Todos os eventos — tudo, sem filtros, por último na lista por ser aquele que você procura quando nenhum dos nomeados se encaixa. Eventos de leitores, Eventos de idioma e Chamadas MCP são feeds para leitura, e não para assinatura, pois nenhum de seus eventos é algo ao qual um alerta possa ser associado; os outros quatro são exatamente aqueles que você indicaria a um notificador. Todos os sete são filtros iniciais, e não listas salvas, portanto não podem ser excluídos e nada pode ser direcionado diretamente a um deles — restrinja um e Salvar como lista o transforma em um feed próprio, que aparece como sua própria linha e é o formato ao qual um alerta pode ser associado.

Lendo o feed#

O feed é dividido em seções diárias, e cada item ocupa uma linha: o avatar do leitor quando um leitor causou o evento (um evento de plano, uso ou MCP não tem ninguém a quem atribuí-lo), um bloco colorido para seu tipo, o nome do evento, o resumo de uma linha e para onde ele foi. O status, o tipo de evento e o destino são exibidos como pequenos glifos, com a palavra disponível a um clique em um popover, para que tudo permaneça em uma linha. Os horários são horas do dia, já que o dia é indicado pelo título da seção acima. Clicar em uma linha a expande no local para mostrar o evento completo — cada tentativa de entrega com sua resposta, a repetição e o payload bruto. Um evento tem um único status, calculado a partir de suas entregas, com o pior resultado prevalecendo:

Status Significado
delivered Todos os destinos o aceitaram.
pending Enfileirado; o worker ainda não tentou processá-lo.
retrying Um destino o recusou e ele ainda está dentro do limite de tentativas.
failed Um destino o recusou e o limite de tentativas foi esgotado.
not sent Isso aconteceu, e nenhum alerta estava inscrito nele.

Chamadas de ferramentas MCP no feed#

O feed também mostra cada chamada de ferramenta MCP feita por um agente neste espaço de trabalho, juntamente com os eventos que seus documentos dispararam. Uma linha por chamada: a ferramenta chamada, se funcionou, quanto tempo levou e quanto custou pelo preço de tabela no cartão de tarifas do MCP. As chamadas com falha indicam isso. As chamadas que não diziam respeito a um projeto específico — descrever o servidor, listar seus projetos, criar um — pertencem à sua conta, e não a um projeto, portanto não aparecem no feed de nenhum projeto.

Elas são exibidas por padrão; não há nada para ativar. No seletor Adicionar evento, elas ficam em uma seção própria de Chamadas MCP, filtradas pela classe de cobrança da chamada — mcp.read, mcp.write, mcp.query, mcp.egress, mcp.generate, mcp.agent — e não pelo nome da ferramenta, que é o eixo que gera custos e que continua funcionando à medida que novas ferramentas são lançadas. O nome da própria ferramenta aparece em cada linha e em cada payload, portanto filtrar por uma ferramenta específica requer apenas uma pesquisa no payload. As chamadas gratuitas (get_info, find_skill, find_widget e o restante da descoberta) nunca são contabilizadas e, portanto, não deixam nenhuma linha.

Uma chamada de ferramenta nunca foi encaminhada para nenhum lugar, portanto aparece como não enviada e, assim como a atividade dos leitores, desaparece no momento em que você filtra por destino ou por status de entrega. Fixar um visitante também a faz desaparecer: um agente portador de um token não é um dos seus leitores, e contar suas chamadas como a navegação de alguém seria incorreto.

Restringir o feed#

Filtre o feed por tipo de evento, status, destino, visitante, uma meta concluída ou texto livre correspondido em qualquer parte do payload — uma única linha de ferramentas acima do feed, sem título acima dela. Cada uma das cinco primeiras facetas é um botão com ícone: passe o mouse sobre ele ou coloque o foco para ver seu nome e, assim que for definida, ela se preenche com o próprio valor; clicar nesse valor permite editá-lo novamente. O texto livre é sua própria caixa de pesquisa sempre visível no final dessa linha, em vez de ser uma faceta que você abre primeiro. Um filtro de visitante fica a um clique de Análises — abra um leitor ali e vá diretamente para tudo o que ele fez — a um clique do próprio avatar de uma linha no feed, ou de um ID colado manualmente. Fixar um leitor amplia o que o feed pesquisa: além dos eventos que seus documentos dispararam, ele busca a atividade do próprio leitor no site — as páginas que ele leu, o que pesquisou, o que perguntou — portanto, um feed fixado é tudo o que esse leitor fez, não apenas as partes que poderiam ter acionado um alerta. Ele também coloca um cartão acima do feed dizendo quem é esse leitor: de onde ele leu, em qual dispositivo, sistema e navegador, o idioma em que leu, a página à qual continua voltando, quanto tempo passou lendo sua documentação no total, as metas que alcançou e quanto vale hoje, além de quanto ainda pode valer. O cartão é apenas para um único leitor fixado, pois um filtro de meta representa uma multidão, e um país e um navegador médios para uma multidão não descrevem ninguém. Salvar um filtro o transforma em uma lista de eventos — portanto, restringir o feed e definir sobre o que você será notificado são o mesmo gesto. Os pings de teste aparecem no feed como qualquer outro evento; uma repetição aparece como outra tentativa sob o evento ao qual pertence. Exportar baixa exatamente o que você está vendo, com os filtros aplicados e sem limite de tempo, como CSV, JSON ou NDJSON — sem limite porque o próprio feed não tem intervalo de tempo: ele é dinâmico, e um arquivo mais restrito que a visualização que copia é pior do que nenhum arquivo. Ele fica no final dessa mesma linha de ferramentas, ao lado de Configurar prompt e Configurar alerta — os três controles que atuam sobre toda a visualização, em vez de sobre um único evento.

Executar um prompt em um feed#

Um alerta encaminha os eventos de um feed para uma pessoa. Configurar prompt, ao lado dele na mesma linha, encaminha-os ao seu assistente: escolha um prompt e ele será executado automaticamente sempre que algo chegar a este feed, sem que ninguém precise acompanhar. O botão exibe uma contagem, para que um feed com algo nele nunca pareça um feed vazio, e cada prompt ativado recebe um chip ao lado dos chips de destino — preenchido enquanto está em execução, vazado enquanto está pausado, com sua última execução na dica de ferramenta.

Clicar em um chip não abre suas configurações. Abre a conversa que o prompt tem mantido: a transcrição do que ele realmente fez na última vez que este feed foi atualizado, no grupo Triggers do assistente. Essa é a única coisa que pode informar que um prompt está funcionando, em vez de apenas estar ativado.

O que monitora um feed monitora um feed salvo, portanto uma visualização que você restringiu, mas ainda não salvou, indica isso e aponta para Salvar como lista. A mesma ativação está disponível do outro lado — o painel Em uma programação ou um evento na própria página de uma ferramenta MCP lista seus feeds acima dos eventos individuais — e excluir um feed desativa o que quer que o monitorasse, em vez de excluir a chamada ativada.

Quanto tudo isso custou#

Cada linha do feed traz um preço, e uma linha de cada vez não é uma coluna que alguém possa somar. Ver uso no cartão de saldo na barra lateral troca o fluxo pela soma: em que o dinheiro deste projeto foi gasto durante um período, começando pelo mais caro, em três seções. Isso não fica na própria barra de ferramentas do feed, porque o valor diz respeito ao projeto inteiro, e não ao feed que você está visualizando.

Seção Uma linha por O que o valor representa
IA & tokens superfície e modelo O preço de cada resposta de IA, tradução ou execução de indexação
Chamadas de ferramentas MCP ferramenta O preço de tabela das chamadas que a ferramenta realmente fez
Eventos registrados tipo de evento Quanto custa registrar esse tráfego, de acordo com a tabela de preços

Os dois primeiros são cobrados: esse dinheiro foi descontado do saldo do projeto. O terceiro não é — os eventos têm preço para que o tráfego não fique invisível, e nada é descontado por eles. Portanto, os dois totais são exibidos como dois valores sob duas palavras diferentes, e cada seção traz um selo charged ou not charged, porque um único número cobrindo os três seria uma cobrança por dinheiro que ninguém recebeu.

Escolha um período de 24 horas, 7 dias ou 30 dias. Não há nada mais longo porque não há nada mais longo para consultar: as análises dos leitores são mantidas por 30 dias e o registro de IA é reduzido para corresponder a isso, então um botão de 90 dias responderia por 30 dias com o rótulo errado.

Exportar aqui oferece o detalhamento em si como um CSV — uma linha por modelo, ferramenta ou tipo de evento, com sua contagem e seu custo como um número simples que você pode somar, além de uma coluna informando se aquela linha foi cobrada — bem como os eventos brutos por trás dele, limitados ao período que você está visualizando.

A mesma tela é aberta por Ver uso no aviso de saldo da barra lateral — o cartão que alerta quando este projeto está ficando sem saldo. A recarga fica no bloco Saldo do menu da conta: um responde quanto resta, este responde no que foi gasto.

Notificadores: para onde vão os eventos#

Um notificador é um destino — um canal, sua URL e suas credenciais — e existe separadamente dos eventos que transporta. Você o cria uma vez — Configurar alerta na linha de título ou Novo notificador na parte inferior de Adicionar notificador — e depois o seleciona nas listas de eventos que ele deve atender. Um canal do Slack alimentado por três listas é um único notificador, com um único segredo de assinatura, pausado ou excluído em um só lugar.

Os notificadores que já estão ativos na lista que você está visualizando ficam ao lado dos chips de filtro, como chips identificados próprios — cada um com a marca real de seu canal, seu nome e paused quando está desativado. Clicar em um deles abre esse notificador, para que você veja para onde uma lista envia os eventos e possa alterá-lo sem sair do feed. Um notificador que está ativo em alguma outra lista — ou em nenhuma ainda, que é como todo novo notificador começa — pode ser acessado no menu Adicionar notificador, onde cada linha tem um controle de edição ao lado da caixa de seleção.

Desmarque uma lista e o notificador deixará de ser ativado nela; desmarque a última e o destino permanecerá, sem estar associado a nada e sem entregar nada, até que você o aponte para algum lugar novamente. Excluir uma lista de eventos tem o mesmo efeito sobre tudo o que era ativado por ela — uma assinatura nunca é ampliada pela perda de sua lista.

Apenas listas salvas podem ser atendidas: os feeds integrados, incluindo Todos os eventos, são filtros em vez de listas, portanto salve primeiro aquela que deseja como um feed próprio.

Catálogo de eventos#

Um espaço de trabalho do Docsbook emite 18 eventos tipados. Cada linha abaixo nomeia o evento exatamente como ele aparece no cabeçalho X-Docsbook-Event e no campo event do corpo, com os campos carregados pelo seu objeto data.

Evento Campos da carga útil
content.indexed pages_count, relations_count, indexed_at
content.outdated (obsoleto — não é mais disparado automaticamente) last_indexed_at, repo_head_sha
translation.needed source_path, language
translation.completed source_path, language, origin
translation.outdated source_path, language, source_hash_changed
chat.question_asked question, answered, chat_id
chat.no_answer question, chat_id
chat.negative_feedback chat_id, question, answer
search.no_results query
search.popular query, count_24h
traffic.spike (evento avançado) path, views, baseline
traffic.drop (evento avançado) path, views, baseline
feedback.received path, rating, comment
plan.upgraded from, to
plan.downgraded from, to
usage.limit_approaching metric (ai|translation), used, limit
usage.overage_limit_reached workspace_id, overage_spent_cents, overage_limit_cents
mcp.tool_called (evento avançado) tool_name, args

Três dos dezoito são marcados como avançadostraffic.spike, traffic.drop e mcp.tool_called. Cada um é derivado de uma linha de base ou de uma atividade medida, em vez de ser disparado diretamente por uma ação.

Registrando um webhook#

Via REST#

curl -X POST https://docsbook.io/api/webhooks \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": 42, "event_type": "content.indexed", "url": "https://you.example.com/hook"}'

A resposta inclui secret exatamente uma vez — armazene-o.

event_type aceita qualquer uma das grafias de um nome de evento: a forma com pontos usada em toda esta página (content.indexed) ou a forma com sublinhados (content_indexed). Ambas registram a mesma assinatura.

Cabeçalho de autorização opcional#

Alguns receptores (por exemplo, uma URL de acionamento de rotina do Claude Code) exigem seu próprio token bearer em cada solicitação, separado da verificação da assinatura HMAC. Passe auth_header ao criar o webhook, e o Docsbook o enviará literalmente como o cabeçalho Authorization em cada entrega:

curl -X POST https://docsbook.io/api/webhooks \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": 42, "event_type": "content.indexed", "url": "https://you.example.com/hook", "auth_header": "Bearer sk-..."}'

Se o valor não tiver espaço, ele será enviado como Bearer <value>; se já contiver um esquema (por exemplo, Bearer sk-...), será enviado sem alterações.

Via MCP#

Cada evento tem uma ferramenta MCP dedicada, portanto um agente de IA pode se inscrever em um fluxo de notificações específico sem precisar escolher strings:

register_webhook_content_indexed(workspace_id: 42, url: "https://YOUR_ENDPOINT")
register_webhook_translation_needed(repo: "owner/repo", url: "https://YOUR_ENDPOINT")
register_webhook_traffic_spike(workspace_id: 42, url: "https://YOUR_ENDPOINT")

Outras ferramentas MCP, com a classe de cobrança na qual cada chamada é contabilizada:

Ferramenta Cobrança O que faz
list_webhooks(workspace_id) Leitura Lista os webhooks registrados no workspace
unregister_webhook(webhook_id) Escrita Remove uma inscrição
test_webhook(webhook_id) Saída Enfileira um ping sintético para a URL registrada
list_webhook_deliveries(webhook_id) Análises Histórico de entregas com status, número de tentativas e payload
replay_webhook_delivery(delivery_id) Saída Reenvia uma entrega anterior

endpoints REST#

  • GET /api/webhooks?workspace_id=X — listar
  • POST /api/webhooks — criar
  • PATCH /api/webhooks/:id — renomear, pausar/retomar ou redirecionar para outra lista de eventos
  • POST /api/webhooks/:id/attach{ "list_id": N }, servir mais uma lista a partir do mesmo destino (mesma URL, mesmo segredo)
  • DELETE /api/webhooks/:id — excluir
  • POST /api/webhooks/:id/test — testar ping
  • GET /api/webhooks/:id/deliveries — entregas recentes
  • POST /api/webhook-deliveries/:id/replay — reenfileirar uma entrega existente

Semântica de novas tentativas e falhas#

  • O worker é executado a cada minuto por meio do cron da Vercel.
  • Uma entrega é tentada até 3 vezes.
  • O intervalo de espera é aplicado a partir de created_at da linha: 1s, 10s, 60s.
  • Após a 3ª falha → status = "failed". Use replay_webhook_delivery para tentar novamente.
  • O código de resposta e o corpo (truncado) são armazenados em cada linha de entrega.

Updated

Esta página foi útil?