FDBKDocumentação

Documentação para desenvolvedores

Webhooks, Slack e DiscordA partir do Pro

Saiba de posts novos, mudanças de status e comentários.

Em Developers, adicione um endpoint e escolha os eventos. Enviamos um POST com JSON para o seu servidor, ou uma mensagem curta para um canal do Slack ou do Discord.

  • post.created Um post é criado
  • post.status_changed Um post muda de status (inclusive quando é unido a outro)
  • comment.created Alguém comenta, ou o time responde

Slack e Discord

Escolha Slack ou Discord e cole a URL do incoming webhook do canal. No Slack, crie um incoming webhook para o canal; no Discord, configurações do canal → Integrações → Webhooks → Novo webhook → Copiar URL. As mensagens levam ao post no seu painel.

Seu servidor

Exemplo
POST /your/endpoint
Content-Type: application/json
FDBK-Event: post.status_changed
FDBK-Delivery: 6592c4b9-7980-4879-94e7-535c15ba782a
FDBK-Signature: t=1791046922,v1=7cb9a0f9…

{
  "id": "6592c4b9-7980-4879-94e7-535c15ba782a",
  "type": "post.status_changed",
  "created_at": "2026-10-03T17:02:00.781Z",
  "data": {
    "post": { "id": 22, "status": "in_progress", … },
    "previous_status": "planned"
  }
}

comment.created também traz data.comment. Responda com qualquer 2xx em até 10 segundos. Qualquer outra resposta é reenviada depois de 1 minuto, 5 minutos, 30 minutos, 2 horas e 8 horas, e então descartada. Redirecionamentos não são seguidos. Um endpoint que falha 20 vezes seguidas é desligado até você ligá-lo de novo. As entregas podem chegar fora de ordem e, raramente, duas vezes: use o id da entrega para ignorar repetidas. O Pro inclui 5 endpoints e 20.000 entregas por mês, contando as novas tentativas.

Verificando assinaturas

Cada endpoint tem um segredo de assinatura (whsec_…). A assinatura é um HMAC-SHA256 do timestamp, um ponto e o corpo bruto. Compare em tempo constante e rejeite timestamps antigos.

Exemplo
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((kv) => kv.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return v1.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Usamos o Google Analytics para entender como as pessoas chegam e usam o FDBK. Sem anúncios, e nunca nos seus boards.