Configurar webhooks para eventos de agentes
Receba um POST assinado em seu próprio endpoint https quando o trabalho de um agente for concluído ou falhar, quando um agente aguardar aprovação ou quando um site de documentação for publicado. Eventos, payloads, verificação de assinatura, novas tentativas e desativação automática.
Um webhook envia um POST assinado para o seu próprio endpoint no momento em que algo acontece, como a conclusão do trabalho de um agente ou um agente aguardando aprovação, para que seus sistemas não precisem fazer consultas (polling). Este artigo aborda como adicionar um endpoint, os eventos, o payload, a verificação da assinatura e o que acontece quando as entregas falham.
Antes de começar
- Os webhooks estão disponíveis nos planos Pro, Business e Custom ("Webhooks estão disponíveis no plano Pro em diante.").
- Apenas o proprietário do workspace e os administradores gerenciam webhooks. Outros membros veem "Apenas proprietários e administradores gerenciam webhooks".
- Você precisa de um endereço https público que responda com um status
2xxem até 10 segundos. - Um workspace pode ter até 10 webhooks.
Adicionar um webhook
Abra a aba Webhooks
Abra o menu do workspace, escolha AI agents & API, depois abra Webhooks. Clique em Novo webhook.

Cada webhook mostra seus eventos, quando enviou pela última vez e o final do seu segredo. Insira o endpoint
- URL do endpoint: "Um endereço HTTPS público." Por exemplo,
https://example.com/clevera/webhooks. - Descrição: opcional, até 200 caracteres, por exemplo, "Relé do Slack".
- URL do endpoint: "Um endereço HTTPS público." Por exemplo,
Escolha os eventos
Marque os eventos que deseja receber ou Todos os eventos, incluindo novos. Eventos marcados como Em breve são aceitos, mas "Nada envia este evento ainda."

Eventos marcados como Em breve são aceitos, mas ainda não são enviados. Crie-o e armazene o segredo
Clique em Criar webhook. O Segredo de assinatura (que começa com
whsec_) é exibido apenas uma vez: "Copie agora: você não verá isso novamente. Use-o para verificar o cabeçalho Clevera-Signature." Armazene-o como uma senha e clique em Eu armazenei.Enviar um evento de teste
Abra o menu ⋯ do webhook e escolha Enviar evento de teste. O Clevera envia um evento
pingassinado uma vez (sem novas tentativas). "Evento de teste enviado" significa que ele saiu do Clevera; verifique as Entregas para ver a resposta do seu endpoint.
Eventos
| Evento | Enviado quando |
|---|---|
job.started |
Um trabalho que um agente iniciou começa a ser executado. |
job.needs_input |
Um trabalho aguarda uma pessoa, por exemplo, uma aprovação. Inclui o link e quando a solicitação expira. |
job.succeeded |
O trabalho foi concluído. |
job.failed |
O trabalho falhou. Inclui o código de erro. |
job.canceled |
O trabalho foi cancelado, ou sua aprovação foi negada ou expirou. |
approval.requested |
Um agente solicitou aprovação em Solicitações do agente. |
approval.decided |
Alguém aprovou ou negou a solicitação, ou ela expirou. |
site.published |
Um site de documentação foi publicado. |
site.build_failed |
A publicação de um site de documentação falhou. |
ping |
Você clicou em Enviar evento de teste. Não requer assinatura. |
Estes eventos estão listados como Em breve e ainda não são enviados: job.progress, video.ready, article.ready, research.completed, insights.weekly.
Os eventos de trabalho abrangem trabalhos que os agentes iniciam (através de um token de API ou um aplicativo conectado), não vídeos que as pessoas iniciam no aplicativo.
O que o Clevera envia
Cada entrega é um POST com um corpo JSON e estes cabeçalhos:
| Cabeçalho | Valor |
|---|---|
Content-Type |
application/json |
User-Agent |
Clevera-Webhooks/1.0 |
Clevera-Event |
O nome do evento, como job.succeeded |
Clevera-Delivery |
O ID exclusivo da entrega. Uma reentrega repete o mesmo ID, então use-o para ignorar duplicatas. |
Clevera-Signature |
t=<unix time>,v1=<signature> |
Os payloads carregam IDs, links, status e números, nunca o conteúdo em si. Para ler um vídeo ou artigo concluído, chame a API com um token.
{
"id": "6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f",
"event": "job.succeeded",
"created_at": "2026-10-20T14:03:11Z",
"data": {
"job": {
"id": "job_8k2m4n6p8r0t2v4x",
"kind": "video.create",
"status": "succeeded",
"error_code": null,
"subject": { "type": "video", "id": "vid_example" },
"credits_spent": 64
},
"needs_input": null,
"workspace": { "id": "tm_example" }
}
}
{
"id": "0b9a8c7d-6e5f-4a3b-9c2d-1e0f9a8b7c6d",
"event": "approval.requested",
"created_at": "2026-10-20T14:01:02Z",
"data": {
"approval": {
"id": "apr_example",
"kind": "spend",
"status": "pending",
"credits_high": 80,
"expires_at": "2026-10-21T14:01:02Z",
"decided_at": null,
"url": "https://app.clevera.ai/agents?tab=requests&team=tm_example"
},
"job": { "id": "job_8k2m4n6p8r0t2v4x", "kind": "video.create" },
"workspace": { "id": "tm_example" }
}
}
Verificar a assinatura
Verifique cada entrega antes de confiar nela. A assinatura é um HMAC-SHA256, codificado com seu segredo de assinatura, do timestamp, um ponto e o corpo da solicitação bruto: <t>.<body>.
- Leia
tev1do cabeçalhoClevera-Signature. - Calcule
HMAC-SHA256(secret, t + "." + rawBody)como hexadecimal. - Compare-o com
v1em tempo constante. - Rejeite entregas cujo
ttenha mais de 5 minutos, para que uma solicitação capturada não possa ser reproduzida.
import crypto from 'node:crypto';
export function verifyClevera(rawBody, header, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split('=')));
const t = Number(parts.t);
if (!parts.v1 || !Number.isInteger(t)) return false;
if (Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return expected.length === parts.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
import hashlib, hmac, time
def verify_clevera(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.strip().split("=", 1) for p in header.split(","))
t, v1 = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or not v1 or abs(time.time() - int(t)) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, v1)
function verifyClevera(string $rawBody, string $header, string $secret, int $tolerance = 300): bool
{
parse_str(str_replace(',', '&', $header), $parts);
$t = $parts['t'] ?? '';
$v1 = $parts['v1'] ?? '';
if (! ctype_digit($t) || $v1 === '' || abs(time() - (int) $t) > $tolerance) {
return false;
}
return hash_equals(hash_hmac('sha256', $t.'.'.$rawBody, $secret), $v1);
}
Use o corpo exatamente como recebido. Analisar e recodificar o JSON primeiro altera os bytes e a assinatura não corresponderá.
Novas tentativas e falhas
Uma entrega conta como entregue quando seu endpoint responde com um status 2xx. Qualquer outra coisa faz a tentativa falhar:
- qualquer outro status, incluindo redirecionamentos (
3xxnão são seguidos); - nenhuma resposta em 10 segundos (5 segundos para conectar);
- um endereço que não resolve mais para a internet pública.
O Clevera tenta novamente uma entrega com falha 5 vezes, após 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas. O corpo da resposta do seu endpoint nunca é lido.
Quando 15 entregas seguidas falham em todas as tentativas, o webhook é desativado: "Desativado após 15 entregas com falha consecutivas. Corrija o endpoint e ative-o novamente." O proprietário e os administradores recebem uma notificação "Webhook para host desativado": "Suas entregas continuaram falhando. Corrija o endpoint e ative-o novamente." Eventos que ocorrem enquanto ele está desativado não são enviados. Eventos de teste não contam para isso.
Gerenciar um webhook
Clique em Entregas em um webhook para ver seu log, ou abra seu menu ⋯ para o restante:
| Opção | O que faz |
|---|---|
| Editar | Altera a URL, eventos ou descrição. |
| Entregas | As últimas 100 entregas com seu status (Entregue, Falhou, Enviando), Tentativas e o código HTTP. Reenviar envia uma novamente. As entregas são mantidas por 30 dias. |
| Enviar evento de teste | Envia um ping assinado. |
| Regenerar segredo | "As entregas são assinadas com o novo segredo imediatamente. Atualize seu endpoint para verificá-lo." Não há sobreposição, então atualize seu endpoint logo em seguida. |
| Desativar / Ativar | Pausa e retoma as entregas. |
| Excluir | "Paramos de enviar eventos para ele e descartamos seu log de entrega. Isso não pode ser desfeito." |
Se o workspace sair do plano Pro
Os webhooks permanecem listados e ainda podem ser editados e excluídos, mas nada é enviado. Entregas aguardando uma nova tentativa terminam como falhas com plan_locked, e Enviar evento de teste e Reenviar informam "Webhooks não estão no seu plano." Fazer o upgrade de volta para o Pro inicia o envio novamente; nada é excluído.
Solução de problemas
| Mensagem | Causa | Correção |
|---|---|---|
| "Webhooks não estão no seu plano." | O workspace não está no plano Pro, Business ou Custom. | Faça upgrade para o Pro. |
| "Use um endereço https://." | A URL começa com http://. |
Sirva o endpoint via HTTPS. |
| "Use um nome de host, não um endereço IP." | A URL usa um endereço IP. | Use um nome de domínio. |
| "Este endereço não é acessível na internet pública." | O host resolve para um endereço privado ou local. | Use um endpoint público ou um relé. |
| "Remova o nome de usuário e a senha do endereço." | A URL tem user:password@. |
Remova-os; verifique a assinatura em vez disso. |
| "Insira um endereço da web válido." | A URL não é válida. | Verifique se há erros de digitação. |
| "Escolha pelo menos um evento." | Nenhum evento marcado. | Marque pelo menos um evento. |
| "Este workspace já tem 10 webhooks." | O limite do workspace. | Exclua um que você não usa. |
| "Ative o webhook primeiro." | Você tentou reenviar em um webhook que está desativado. | Ative-o e, em seguida, reenvie. |
| "Esta entrega ainda está sendo enviada." | A entrega ainda está tentando novamente. | Aguarde a conclusão. |
| Entregas falham com um código HTTP | Seu endpoint respondeu com um erro. | Verifique os logs do seu endpoint e se ele retorna 2xx rapidamente; faça trabalhos lentos após responder. |
| Assinaturas nunca correspondem | O corpo foi alterado antes da verificação, ou o segredo é antigo. | Verifique em relação ao corpo bruto; regenere o segredo se não tiver certeza. |