Webhooks
Seja notificado em tempo real quando eventos acontecerem na sua conta AgentSend — novos emails recebidos, entregas confirmadas, bounces detectados e muito mais.
Visão Geral
Em vez de fazer polling na API para verificar novas mensagens, os webhooks permitem que o AgentSend envie dados de eventos para seu servidor no momento em que algo acontece. Registre um endpoint HTTPS e o AgentSend enviará uma requisição POST com um payload JSON sempre que um evento inscrito for disparado.
Os webhooks são a forma recomendada de construir agentes reativos. Quando uma resposta chega na caixa de entrada do seu agente, sua aplicação recebe o payload completo da mensagem em segundos e pode agir imediatamente.
Os endpoints de webhook devem ser publicamente acessíveis via HTTPS. URLs localhost não são aceitas. Use uma ferramenta como ngrok ou um serviço de túnel ao desenvolver localmente.
Criando um Webhook
Registre um novo webhook enviando uma requisição POST request to /webhooks. Você deve fornecer um campo url ; todos os outros campos são opcionais.
/webhooks
| Parâmetro | Tipo | Descrição |
|---|---|---|
url obrigatório |
string | A URL HTTPS para a qual o AgentSend enviará eventos via POST. |
description |
string | Um rótulo legível para identificar o webhook no painel. |
events |
string[] | Lista de tipos de evento para assinar. Omita para receber todos os eventos. |
const res = await fetch("https://api.agentsend.io/webhooks", { method: "POST", headers: { "x-api-key": process.env.AGENTSEND_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://myapp.example.com/hooks/agentsend", description: "Production inbox events", events: ["message.received", "message.bounced"], }), }); const webhook = await res.json(); console.log(webhook.id); // wh_01j9... console.log(webhook.secret); // whsec_... store this securely!
The secret é retornado apenas uma vez na resposta de criação. Armazene-o em uma variável de ambiente segura imediatamente — não pode ser recuperado novamente, mas você pode rotacioná-lo via PUT /webhooks/{id}.
Tipos de Evento
Assine eventos específicos passando seus identificadores no array events . Se você omitir o array, o AgentSend entrega todos os tipos de evento ao seu endpoint.
| Evento | Descrição |
|---|---|
domain.verified |
Um domínio personalizado passou na verificação de DNS e está pronto para uso. |
message.received |
Um email de entrada chegou em uma das caixas de entrada do seu agente. |
message.sent |
Uma mensagem de saída foi aceita e enfileirada para entrega. |
message.delivered |
O servidor de email do destinatário confirmou a entrega bem-sucedida. |
message.bounced |
A mensagem não pôde ser entregue (bounce permanente ou temporário). |
message.complained |
O destinatário marcou a mensagem como spam através do seu cliente de email. |
Payload do Webhook
Toda entrega de webhook é uma requisição POST request with a Content-Type: application/json . O payload possui um envelope consistente independente do tipo de evento.
{
"id": "evt_01j9xkq7z8abc",
"type": "message.received",
"createdAt": "2026-04-16T10:23:45.000Z",
"webhookId": "wh_01j9abc123",
"data": {
"id": "msg_01j9xkp4n5def",
"inboxId": "inbox_01j8mq3r2t",
"threadId": "thr_01j9xkp4m1ghi",
"fromAddress": "alice@example.com",
"fromName": "Alice Chen",
"toAddresses": ["a1b2c3@agentsend.io"],
"subject": "Re: Your proposal",
"bodyText": "Looks great, let's move forward.",
"bodyHtml": "<p>Looks great, let's move forward.</p>",
"hasAttachments": false,
"receivedAt": "2026-04-16T10:23:44.812Z"
}
}Verificando Assinaturas
Toda requisição de webhook inclui um cabeçalho X-AgentSend-Signature . Este é um hash HMAC-SHA256 do corpo bruto da requisição, assinado com o secretdo seu webhook. Sempre verifique esta assinatura antes de processar uma entrega para se proteger contra requisições forjadas.
import crypto from "node:crypto"; app.post("/hooks/agentsend", express.raw({ type: "application/json" }), (req, res) => { const sig = req.headers["x-agentsend-signature"]; const secret = process.env.AGENTSEND_WEBHOOK_SECRET; const expected = crypto .createHmac("sha256", secret) .update(req.body) // raw Buffer — do NOT parse JSON first .digest("hex"); if (!crypto.timingSafeEqual( Buffer.from(sig), Buffer.from(expected) )) { return res.status(401).send("Invalid signature"); } const event = JSON.parse(req.body); // handle event.type … res.sendStatus(200); });
import hmac, hashlib, os from flask import Flask, request, abort app = Flask(__name__) @app.route("/hooks/agentsend", methods=["POST"]) def webhook(): sig = request.headers.get("X-AgentSend-Signature", "") secret = os.environ["AGENTSEND_WEBHOOK_SECRET"].encode() expected = hmac.new(secret, request.data, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): abort(401) event = request.get_json() # handle event["type"] … return "", 200
Sempre use uma comparação de tempo constante (e.g. crypto.timingSafeEqual or hmac.compare_digest) ao verificar assinaturas para prevenir ataques de timing.
Política de Retry
O AgentSend considera uma entrega bem-sucedida quando seu endpoint responde com qualquer código de status HTTP 2xx dentro de 10 segundos. Se a requisição expirar ou retornar uma resposta não-2xx , a entrega é tentada novamente com back-off exponencial:
| Tentativa | Atraso após tentativa anterior |
|---|---|
| 1ª tentativa | 5 segundos |
| 2ª tentativa | 30 segundos |
| 3ª tentativa | 5 minutos |
| 4ª tentativa | 30 minutos |
| 5ª tentativa | 2 horas |
Após 5 tentativas falhas (6 tentativas no total), a entrega é marcada como failed e nenhuma tentativa adicional é feita. Você pode inspecionar entregas falhas nos logs de entrega e repeti-las manualmente do painel.
Responda com 200 OK o mais rápido possível. Se sua lógica de processamento levar tempo, aceite o payload imediatamente e processe-o de forma assíncrona com uma fila ou job em segundo plano.
Gerenciando Webhooks
A API de webhooks permite listar, atualizar e excluir seus endpoints registrados.
Listar webhooks
Retorna todos os webhooks registrados na sua conta.
# GET /webhooks curl https://api.agentsend.io/webhooks \ -H "x-api-key: $AGENTSEND_API_KEY"
Atualizar um webhook
Altere a URL, descrição ou tipos de evento assinados. Você também pode rotacionar o segredo de assinatura passando "rotateSecret": true — a resposta incluirá um novo secret.
# PUT /webhooks/{id} curl -X PUT https://api.agentsend.io/webhooks/wh_01j9abc123 \ -H "x-api-key: $AGENTSEND_API_KEY" \ -H "Content-Type: application/json" \ -d '{"events": ["message.received", "message.delivered", "message.bounced"]}'
Excluir um webhook
Remove o webhook permanentemente. Entregas em andamento ainda são tentadas antes que a exclusão entre em vigor.
# DELETE /webhooks/{id} curl -X DELETE https://api.agentsend.io/webhooks/wh_01j9abc123 \ -H "x-api-key: $AGENTSEND_API_KEY"
Monitoramento de atividade
Obtenha um resumo do volume recente de eventos e taxas de erro para um webhook específico.
# GET /webhooks/activity curl "https://api.agentsend.io/webhooks/activity?webhookId=wh_01j9abc123" \ -H "x-api-key: $AGENTSEND_API_KEY"
Logs de Entrega
Toda tentativa de entrega é registrada. Consulte o endpoint de logs para inspecionar o histórico completo de um webhook, incluindo códigos de resposta HTTP, corpos de resposta e tempos.
GET/webhooks/logs
| Parâmetro de Consulta | Tipo | Descrição |
|---|---|---|
webhookId |
string | Filtrar logs para um webhook específico. |
status |
string | success, failed, or pending. |
limit |
number | Número de registros a retornar (padrão 50, máximo 200). |
before |
string | Cursor para paginação; passe o id do último registro visto. |
# Fetch failed deliveries for a webhook curl "https://api.agentsend.io/webhooks/logs?webhookId=wh_01j9abc123&status=failed" \ -H "x-api-key: $AGENTSEND_API_KEY"
Cada entrada de log inclui:
- id — ID único da tentativa de entrega.
- eventId — O ID do evento de origem.
- eventType — ex.
message.received. - status —
success,failed, orpending. - httpStatus — O código de resposta HTTP retornado pelo seu endpoint.
- durationMs — Tempo de ida e volta em milissegundos.
- attempt — Qual tentativa foi esta (1 = primeira entrega).
- createdAt — Data e hora da tentativa.