Documentation
DocsCore ConceptsWebhooks & Events
Webhooks & Events
Receive real-time notifications when events occur. Configure endpoints, subscribe to event types, and verify signed payloads.
Event Types
| Event | Description |
|---|---|
message.sent | Message accepted and queued for delivery |
message.received | Inbound message arrived at an inbox |
message.delivered | Recipient's mail server accepted the message |
message.bounced | Message rejected by recipient's mail server |
enrollment.progressed | Contact advanced to next workflow step |
Setting Up Webhooks
TypeScript
const endpoint = await client.createWebhookEndpoint({
url: "https://your-server.com/webhooks/outreachagent",
subscribedEvents: ["message.received", "message.delivered"]
});
// Update subscribed events
await client.updateWebhookEndpoint(endpoint.id, {
subscribedEvents: ["message.received", "message.delivered", "message.bounced"]
});curl
curl -X POST https://api.outreachagent.dev/v1/webhooks/endpoints \
-H "Authorization: Bearer $OUTREACHAGENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/outreachagent",
"subscribedEvents": ["message.received", "message.delivered"]
}'Signature Verification
Every webhook includes an X-OutreachAgent-Signature header — an HMAC-SHA256 hash of the request body using your webhook secret. Always verify before processing:
Node.js Verification
import { createHmac, timingSafeEqual } from "crypto";
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = createHmac("sha256", secret).update(body).digest("hex");
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Retry Policy
Failed deliveries (non-2xx or timeout after 30s) are retried with exponential backoff:
- Attempt 1 — Immediate
- Attempt 2 — After 1 minute
- Attempt 3 — After 5 minutes
- Attempt 4 — After 30 minutes
- Attempt 5 — After 2 hours
After 5 failures, the event is marked failed. Replay failed events from the console.
Endpoint Health
WebhookEndpoint
{
id: string,
url: string,
status: "healthy" | "degraded" | "failing",
subscribedEvents: string[],
errorRate: number, // 0–1
createdAt: string
}