Integrações e API do WillTub

Conecte o WillTub a outras plataformas de quatro formas: incorporando o player, recebendo o tempo de exibição, recebendo avisos automáticos (webhooks) ou consultando dados pela API REST. As chaves e os endereços são criados em Integrações e API, no menu do painel.

1. Embed do player

Cada vídeo tem uma página pública e uma página de embed para colocar dentro de outros sites com um <iframe>:

<!-- Página de visualização -->
https://willtub.com/v/ID_DO_VIDEO

<!-- Player para incorporar (horizontal 16:9) -->
<iframe
  src="https://willtub.com/embed/ID_DO_VIDEO"
  style="width:100%;aspect-ratio:16/9;border:0"
  allow="autoplay; fullscreen"
></iframe>

<!-- Player vertical (9:16, ideal para celular) -->
<iframe
  src="https://willtub.com/embed/ID_DO_VIDEO"
  style="width:100%;aspect-ratio:9/16;border:0"
  allow="autoplay; fullscreen"
></iframe>

Os links e códigos prontos de cada vídeo ficam na aba Embed da página do vídeo no painel.

2. Tempo de exibição (postMessage)

Enquanto o vídeo toca dentro do iframe, o player envia uma mensagem por segundo para a página que hospeda o embed. Use para sincronizar conteúdo da página com o andamento da VSL:

window.addEventListener("message", (event) => {
  if (event.origin !== "https://willtub.com") return;
  const { tipo, segundos, id } = event.data || {};
  if (tipo === "tempo") {
    console.log("Vídeo", id, "está em", segundos, "segundos");
  }
});

Formato da mensagem: { tipo: "tempo", segundos: 42, id: "ID_DO_VIDEO" }.

Cliques de botões da página

O botão pode ficar fora do vídeo. No clique real que abre o pagamento, envie esta mensagem ao iframe WillTub. O clique entra nas mesmas métricas de botão da VSL, uma vez por sessão, e utiliza os avisos de clique já ativados pelo dono.

// Adicione id="player-willtub" ao iframe da sua VSL.
// Chame esta função no botão que já abre o pagamento.
function registrarCliqueWillTub() {
  const player = document.getElementById("player-willtub");
  if (!(player instanceof HTMLIFrameElement)) return;
  const url = new URL(player.src);
  if (url.origin !== "https://willtub.com") return;
  const id = url.pathname.match(/^\/embed\/([^/]+)$/)?.[1];
  if (!id) return;
  player.contentWindow?.postMessage(
    { tipo: "willtub:clique", id },
    "https://willtub.com"
  );
}

// Exemplo em React: preserve a ação de pagamento existente.
function openCheckout() {
  registrarCliqueWillTub();
  setCheckoutOpen(true);
}

Não é necessária chave de API. O iframe precisa estar carregado e preservar a origem da página: não use referrerPolicy="no-referrer", nem um sandbox que remova a origem. A política padrão ou strict-origin-when-cross-origin permite a conexão.

O player responde com { tipo: "willtub:clique_recebido", id }. Isso confirma apenas o recebimento da mensagem, não uma compra nem o salvamento no servidor. A atualização das métricas depende da conexão. Não dispare no carregamento da página, na exibição do botão ou por temporizador.

Se o botão sair imediatamente da página, aguarde a resposta (validando event.origin, event.source e o ID), mantenha o iframe aberto por um breve intervalo, ou abra o pagamento em outra aba. Sem o código no site que contém o botão, nenhum clique externo é captado automaticamente.

3. Webhooks (avisos automáticos)

O WillTub envia um POST em JSON para o endereço que você cadastrar quando algo importante acontece nos seus vídeos. Eventos disponíveis:

Exemplo do corpo enviado:

{
  "event": "pitch.reached",
  "occurred_at": "2026-11-07T20:00:00.000Z",
  "video": { "id": "...", "title": "Minha VSL" },
  "session": {
    "id": "...",
    "seconds": 320,
    "city": "São Paulo, SP",
    "country": "BR",
    "device": "Celular",
    "source": "instagram.com"
  }
}

Cada sessão gera no máximo uma tentativa por evento e endereço. O destino precisa responder em até 5 segundos, sem redirecionar. Não há reenvio automático se falhar. Use o botão Testar antes de ativar sua automação. Cabeçalhos enviados:

x-willtub-event: pitch.reached
x-willtub-signature: sha256=...

Valide a assinatura com o segredo mostrado ao cadastrar o endereço, calculando o HMAC-SHA256 do corpo bruto da requisição:

import crypto from "node:crypto";

const assinatura = req.headers["x-willtub-signature"];
const esperada = "sha256=" + crypto
  .createHmac("sha256", SEGREDO_DO_WEBHOOK)
  .update(corpoBruto)
  .digest("hex");

const recebida = Buffer.from(assinatura || "");
const calculada = Buffer.from(esperada);
if (recebida.length !== calculada.length ||
    !crypto.timingSafeEqual(recebida, calculada)) {
  // rejeitar: aviso não veio do WillTub
}

4. API REST

Consulte seus vídeos e métricas em ferramentas que permitem pedidos HTTP, como Make, n8n ou um servidor próprio. Crie uma chave em Integrações e APIe configure o pedido na ferramenta escolhida. A chave sozinha não conecta uma ferramenta automaticamente. Nunca publique a chave em páginas ou scripts do navegador. Envie a chave no cabeçalho Authorization:

Authorization: Bearer wtk_sua_chave_aqui

Listar vídeos

GET https://willtub.com/api/public/v1/videos

curl -H "Authorization: Bearer wtk_sua_chave_aqui" \
  https://willtub.com/api/public/v1/videos
{
  "videos": [
    {
      "id": "...",
      "title": "Minha VSL",
      "created_at": "2026-11-01T12:00:00.000Z",
      "duration_seconds": 600,
      "plays": 1532,
      "watch_url": "https://willtub.com/v/...",
      "embed_url": "https://willtub.com/embed/..."
    }
  ]
}

Métricas de um vídeo

GET https://willtub.com/api/public/v1/videos/ID_DO_VIDEO/stats

curl -H "Authorization: Bearer wtk_sua_chave_aqui" \
  https://willtub.com/api/public/v1/videos/ID_DO_VIDEO/stats
{
  "video": { "id": "...", "title": "Minha VSL", "duration_seconds": 600 },
  "stats": {
    "views": 2100,
    "plays": 1532,
    "cta_clicks": 214,
    "live_now": 3,
    "avg_watch_seconds": 187,
    "top_countries": [{ "name": "BR", "count": 1980 }],
    "top_sources": [{ "name": "instagram.com", "count": 860 }]
  }
}

Respostas de erro: 401 (chave inválida ou revogada), 400 (identificador inválido), 500 (falha temporária), 404 (vídeo não encontrado ou de outra conta). A API é somente leitura e mostra apenas os dados da conta dona da chave.