Guias de integração
Avisos por webhook
Receba um POST assinado quando um destino cair, voltar, expirar ou atingir o limite de cliques.
Cada aviso envia um POST em JSON para um endereço de aviso quando um destino cai, volta, expira ou atinge o limite de cliques. Cadastre o endereço no painel, em Links, Avisos para outros sistemas, e escolha quais avisos ele recebe. O recurso faz parte dos planos Pro e Business.
Avisos disponíveis
| Aviso | Quando acontece | Dados além do link |
|---|---|---|
link.fora_do_ar | O destino do link passa a ser classificado como indisponível. | motivo, codigo_http |
link.voltou_ao_ar | O destino volta a responder depois de ter ficado fora do ar. | fora_desde |
link.limite_atingido | Um clique completa o max_cliques do link. | max_cliques |
link.expirou | Chega a data de expira_em do link. | expira_em |
O botão Testar do painel envia o aviso teste, apenas com a mensagem "Aviso de teste".
Corpo do aviso
{ "id": "ent_1042", "evento": "link.fora_do_ar", "criado_em": "2026-10-12T14:03:21-03:00", "dados": { "link": { "id": 4821, "codigo": "promo-outubro", "url_curta": "https://pqno.app/promo-outubro", "url": "https://exemplo.com.br/campanha", "titulo": "Campanha de outubro" }, "motivo": "a página não existe mais (erro 404)", "codigo_http": 404 } }
O id identifica a entrega e se repete nas novas tentativas do mesmo aviso. Use-o para ignorar um aviso já processado.
Cabeçalhos
| Cabeçalho | Conteúdo |
|---|---|
X-Webhook-Event | Nome do aviso, como link.fora_do_ar. |
X-Webhook-Delivery | O mesmo id do corpo. |
X-Webhook-Signature | t= com o momento do envio em segundos e v1= com a assinatura, como t=1760281401,v1=9f2c.... |
Confira a assinatura
A assinatura é o HMAC SHA-256, em hexadecimal, de momento.corpo, calculado com o segredo do endereço de aviso. O painel mostra o segredo uma vez, ao cadastrar o endereço ou gerar um novo. Calcule o mesmo valor sobre o corpo exatamente como chegou, compare em tempo constante e recuse avisos com momento muito antigo. Este exemplo usa Node.js.
const crypto = require('node:crypto');
function assinaturaValida(corpoBruto, cabecalho, segredo) {
const partes = Object.fromEntries(cabecalho.split(',').map((p) => p.split('=')));
const esperado = crypto.createHmac('sha256', segredo).update(`${partes.t}.${corpoBruto}`).digest('hex');
const a = Buffer.from(esperado);
const b = Buffer.from(partes.v1 || '');
const recente = Math.abs(Date.now() / 1000 - Number(partes.t)) < 300;
return recente && a.length === b.length && crypto.timingSafeEqual(a, b);
}
Resposta e novas tentativas
Responda com qualquer código 2xx em até 8 segundos. Outro código, falha de conexão ou demora fazem o aviso voltar à fila. São até 5 tentativas. A primeira sai em até 1 minuto; as seguintes esperam 1 minuto, 5 minutos, 30 minutos e 2 horas. Após 10 avisos seguidos que esgotam as tentativas, o endereço é desligado e a conta recebe um aviso no painel. Corrija o problema e ligue o endereço de novo.
Regras do endereço
O endereço de aviso precisa usar https, apontar para um site público e usar a porta 443 ou 8443, sem usuário e senha. Redirecionamentos não são seguidos. Cada conta tem até 5 endereços de aviso, e o painel guarda o histórico dos últimos avisos por 30 dias. Não há aviso por clique. Para acompanhar cliques, use as estatísticas de um link.

