Integrations
Webhooks
Cleanmails fires real-time webhook events when things happen in your outreach. Use webhooks to sync with CRMs, trigger automation platforms (Zapier, Make, n8n), or build custom dashboards.
Event Types
| Event | Fired When |
|---|---|
lead.replied | A lead replies to a campaign email |
lead.bounced | Email bounces (hard or soft) |
lead.opened | Recipient opens the email (tracking pixel loaded) |
lead.clicked | Recipient clicks a tracked link |
lead.unsubscribed | Lead clicks the unsubscribe link |
campaign.started | Campaign status changes to active |
campaign.paused | Campaign is paused (manual or auto due to bounce rate) |
campaign.completed | All leads processed through all steps |
meeting.booked | Lead thread marked as "Meeting Booked" in unibox |
Creating a Webhook
bash
curl -X POST https://YOUR_SERVER/api/v1/workspaces/1/webhooks \
-H "Content-Type: application/json" \
-H "Cookie: auth_token=YOUR_JWT_TOKEN" \
-d '{
"url": "https://your-app.com/webhook/cleanmails",
"secret": "your-hmac-signing-secret",
"events": ["lead.replied", "lead.bounced", "meeting.booked"]
}'Event filtering
Specify which events you want to receive. Only matching events will be delivered to your endpoint.
Webhook Payload
POST to your URL
{
"event": "lead.replied",
"workspace_id": "uuid-here",
"timestamp": "2026-05-12T14:30:00Z",
"data": {
"lead_email": "john@example.com",
"lead_name": "John Smith",
"company": "Acme Inc",
"campaign_name": "Q2 Outreach",
"snippet": "Thanks for reaching out! I'd love to learn more about..."
}
}Signature Verification
Every delivery includes an HMAC-SHA256 signature header for payload verification:
text
X-Webhook-Signature: sha256=a1b2c3d4e5f6...Verify it server-side:
Node.js verification
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry & Auto-Deactivate
- Retries: Automatic retry with exponential backoff on failure
- Auto-deactivate: After 10 consecutive failures, the webhook is automatically deactivated
- Delivery logs: Each delivery attempt is logged with status code and response body
- Re-enable: Fix your endpoint, then update the webhook to re-activate
Delivery Logs
bash
# View delivery history for a webhook
curl https://YOUR_SERVER/api/v1/workspaces/1/webhooks/WEBHOOK_ID/logs \
-H "Cookie: auth_token=YOUR_JWT_TOKEN"Logs include: timestamp, event type, HTTP status code, response body, and delivery duration.
Webhook Dispatch
Webhook payloads are delivered as background jobs via the Asynq worker queue. This ensures:
- Webhook delivery doesn't block the main request flow
- Failed deliveries are retried automatically
- High-volume events don't overwhelm your endpoint
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/workspaces/:wid/webhooks | List all webhooks |
| POST | /api/v1/workspaces/:wid/webhooks | Create webhook |
| PUT | /api/v1/workspaces/:wid/webhooks/:id | Update webhook |
| DELETE | /api/v1/workspaces/:wid/webhooks/:id | Delete webhook |
| GET | /api/v1/workspaces/:wid/webhooks/:id/logs | View delivery logs |
Using with Automation Platforms
Webhooks are the bridge to automation platforms:
| Platform | Setup |
|---|---|
| Zapier | Use "Catch Hook" trigger → paste the Zap webhook URL into Cleanmails |
| Make (Integromat) | Use "Custom Webhook" module → paste the Make webhook URL |
| n8n | Use "Webhook" node → paste the n8n webhook URL |
| Activepieces | Use "Webhook Trigger" → paste the webhook URL |
This lets you push Cleanmails events into any of the 5,000+ apps these platforms support.