Pular para o conteúdo
LinkProfit

Webhooks

Entregas de eventos assinadas: eventos disponíveis, verificação do X-LinkProfit-Signature em JavaScript e Python, novas tentativas e o estado de falha.

Atualizado em 13 de agosto de 2026

Os webhooks enviam eventos ao seu endpoint como requisições POST em JSON — sem polling. Registre endpoints no painel (Configurações → Webhooks) ou por POST /v1/webhooks; o segredo de assinatura aparece uma única vez, na criação.

Eventos

| Evento | Dispara quando | Disponível para | |---|---|---| | link.created / link.updated / link.deleted | Um link muda — pelo painel, pela API ou por importação em lote | endpoints de espaço de trabalho e de parceiro | | domain.pending_ssl | O DNS foi verificado e o certificado está sendo emitido | espaço de trabalho e parceiro | | domain.activated | O domínio já atende tráfego | espaço de trabalho e parceiro | | domain.error | O provisionamento falhou; os detalhes vêm no payload | espaço de trabalho e parceiro | | click.threshold | Chega a 80% / 100% do limite mensal de cliques medidos | espaço de trabalho e parceiro | | conversion.created | Uma conversão foi registrada: um pedido, um cadastro ou uma meta personalizada atribuída a um clique | espaço de trabalho e parceiro | | workspace.subscribed | Um cliente paga a primeira fatura de uma assinatura | somente parceiro | | workspace.past_due | O pagamento de um cliente falha | somente parceiro | | workspace.suspended | Um cliente é suspenso (por inadimplência ou manualmente) | somente parceiro | | payment.succeeded | O pagamento de um cliente é liquidado, com o detalhamento das taxas | somente parceiro | | payment.refunded | Um pagamento é reembolsado | somente parceiro |

A entrega

POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-LinkProfit-Event: link.created
X-LinkProfit-Delivery: dlv_8Yq2…
X-LinkProfit-Signature: t=1755081600,v1=5f8a2c…
{
  "id": "dlv_8Yq2…",
  "type": "link.created",
  "created_at": "2026-08-13T10:00:00.000Z",
  "data": { "id": "lnk_…", "domain": "go.your-brand.com", "slug": "x7f2q1z", "url": "https://example.com" }
}

Responda com qualquer 2xx em até 10 segundos. Qualquer outra coisa — inclusive um tempo limite esgotado — conta como falha e agenda uma nova tentativa. As entregas podem chegar fora de ordem e, raramente, duas vezes: faça deduplicação por id.

Verificação da assinatura

A assinatura é um HMAC-SHA256 sobre `${t}.${rawBody}` com o segredo do seu endpoint, codificado em hexadecimal. Verifique sempre contra o corpo bruto da requisição, antes de qualquer parsing de JSON, e rejeite marcas de tempo com mais de 5 minutos.

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

function verifySignature(secret, rawBody, header, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    header.split(",").map((piece) => piece.split("=", 2)),
  );
  if (!parts.t || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) return false;

  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && timingSafeEqual(a, b);
}
import hashlib
import hmac
import time


def verify_signature(secret: str, raw_body: bytes, header: str, tolerance: int = 300) -> bool:
    parts = dict(piece.split("=", 1) for piece in header.split(",") if "=" in piece)
    timestamp, signature = parts.get("t"), parts.get("v1")
    if not timestamp or not signature:
        return False
    if abs(time.time() - int(timestamp)) > tolerance:
        return False

    expected = hmac.new(
        secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Novas tentativas e o estado de falha

A primeira tentativa é imediata. As falhas são repetidas em um cronograma fixo: 1 min → 5 min → 30 min → 2 h → 12 h. Depois da quinta nova tentativa, o endpoint é marcado como failing, para de receber eventos novos e o dono recebe um e-mail.

Corrija o endpoint e reative-o no painel ou com PATCH /v1/webhooks/{id} e {"status": "active"}. Os eventos perdidos não são reenviados automaticamente — o registro de entregas (GET /v1/webhooks/{id}/deliveries ou o painel) mostra cada payload para que você faça a reconciliação.

Uma entrega bem-sucedida zera a sequência de falhas.

Testes

O botão Enviar teste (ou POST /v1/webhooks/{id}/test) entrega um evento real e assinado com "data": { "test": true } pelo mesmo pipeline dos eventos de produção — o registro de entregas mostra a resposta do seu endpoint.