Pular para o conteúdo principal
Proton v5

Webhooks

O Proton manda um POST assinado para o endereço da empresa quando algo acontece nas automações: uma execução termina, um lote termina ou não roda, uma ocorrência abre, é atribuída ou resolvida, um runner cai ou volta. É o caminho para a ferramenta de monitoramento, de chamados ou de mensagens da empresa. Para ler os mesmos eventos sob demanda, use GET /v1/events.

Os webhooks fazem parte do plano Enterprise. O cadastro fica em Configurações > Alertas e webhooks, na aba Webhooks: o nome, o endereço e os eventos (ou todos).

O que chega​

O envio segue o padrão Standard Webhooks:

POST https://monitoramento.exemplo.com/proton
content-type: application/json
user-agent: Proton-Webhooks/1.0
webhook-id: evt_1532
webhook-timestamp: 1760886000
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
{
"type": "run.finished",
"timestamp": "2026-10-19T15:00:00.000Z",
"version": "1",
"data": {
"organizationId": 12,
"link": "https://app.protoncloud.com.br/automations/center/dataset/40/cycle/7/dataset-run/981/details",
"run": {
"id": 981,
"status": "Failed",
"endReason": "technical_error",
"startedAt": "2026-10-19T14:58:00.000Z",
"finishedAt": "2026-10-19T15:00:00.000Z",
"durationMs": 120000,
"correlationId": "7f6c2d2e-5f0b-4a4a-9b9b-3c1f2a9e0d11",
"retryScheduled": false,
"link": "https://app.protoncloud.com.br/automations/center/dataset/40/cycle/7/dataset-run/981/details"
},
"automation": { "id": 5, "name": "Cadastro de fornecedor" },
"dataset": { "id": 40, "name": "Filial 01" },
"group": { "id": 3, "name": "Operação", "purpose": "operation" },
"cycle": { "id": 7, "name": "Outubro" },
"environment": { "id": 2, "name": "Produção", "production": true },
"runner": { "id": 9, "name": "rpa-01", "hostname": "rpa-01" }
}
}

Os eventos​

TipoQuandoCampos em data
run.finishedUma execução terminourun (status, motivo do fim, início, fim, duração, Correlation ID), automation, dataset, group, cycle, environment, runner
batch.finishedUm lote terminoubatch (total, passed, failed, stopped), group, cycle, environment, runner
batch.not_runUm agendamento não saiubatch (com o reason), group, cycle, environment, runner
exception.opened, exception.assigned, exception.resolvedUma ocorrência da operação abriu, foi atribuída ou resolvidaexception (kind, status, occurrences, reason, errorSummary, assignee), automation, dataset, group, cycle, environment
runner.offline, runner.onlineUm runner caiu (depois de 2 minutos fora) ou voltourunner (name, owner, hostname, offlineSince, shared)
webhook.testO teste pela telaorganizationId, message

O motivo do fim da execução (endReason) é um destes: passed, business_error, technical_error, environment_error, stopped, not_dispatched, runner_lost.

A versão do corpo (version) só muda se um campo sair ou mudar de sentido. Campo novo pode aparecer a qualquer momento: trate o que não conhece como opcional.

Conferir a assinatura​

O segredo do webhook (whsec_...) aparece uma vez só, no cadastro e na troca. A assinatura é o HMAC-SHA256 de webhook-id.webhook-timestamp.corpo, com a chave em base64 que vem depois de whsec_, codificado em base64 e precedido de v1,. Confira sempre o corpo exatamente como chegou, antes de interpretar o JSON, e recuse mensagem com webhook-timestamp muito antigo (mais de 5 minutos).

import base64
import hashlib
import hmac
import time


def assinatura_valida(segredo: str, cabecalhos: dict, corpo: bytes, tolerancia: int = 300) -> bool:
chave = base64.b64decode(segredo.removeprefix("whsec_"))
id_da_mensagem = cabecalhos["webhook-id"]
momento = cabecalhos["webhook-timestamp"]
if abs(time.time() - int(momento)) > tolerancia:
return False

conteudo = f"{id_da_mensagem}.{momento}.".encode() + corpo
esperada = base64.b64encode(hmac.new(chave, conteudo, hashlib.sha256).digest()).decode()

for assinatura in cabecalhos["webhook-signature"].split(" "):
versao, _, valor = assinatura.partition(",")
if versao == "v1" and hmac.compare_digest(valor, esperada):
return True
return False

As bibliotecas do Standard Webhooks (para Python, Node.js, Java, Go, C# e outras) fazem essa conferência.

Entrega e novas tentativas​

  • Resposta: qualquer 2xx em até 10 segundos conta como entregue. Responda rápido e processe depois.
  • Novas tentativas: sem 2xx, o Proton tenta de novo com espera crescente (30 segundos, 1 minuto, 2 minutos... até 1 hora entre uma e outra), até 8 tentativas.
  • Repetição: o webhook-id é o mesmo em todas as tentativas do mesmo evento. Guarde os ids recebidos e descarte o repetido.
  • Endereço: só https, num endereço público. Redirecionamento não é seguido.
  • Acompanhamento: a aba Histórico de Alertas e webhooks mostra cada entrega, com o resultado, o status HTTP e o erro, e permite reenviar a que falhou. O botão de teste manda um webhook.test.