We’re excited to announce that webhooks are now live in Snoooz!
This means you can connect Snoooz with your favorite tools and automate actions whenever an email matches one of your rules — no manual work needed.
Note: If you are on Appsumo Lifetime plan, then Webhooks are available only on Tier 3 and higher plans.
🧩 What Are Webhooks?
Webhooks let Snoooz send real-time data to your own applications or automation tools (like Zapier, Make, or your custom app).
Each time an email is processed and matches a rule, Snoooz will fire a webhook to your endpoint — instantly sharing the event data.
⚙️ How to Set Up Webhooks in Snoooz
Follow these simple steps to get started:
Step 1: Go to Settings
In your Snoooz dashboard, open the Settings menu.
Step 2: Enable Webhook Notifications
Click Enable Webhook Notifications to turn them on.
Step 3: Enter Your Endpoint
Paste your webhook endpoint URL — this is where Snoooz will send the event data.
Step 4: Test the Connection
Click Test to make sure Snoooz can reach your endpoint.
If you see a “Success” message, your endpoint is correctly receiving and responding to our test request.
Step 5: (Optional) Add a Secret for Security
For added security, we recommend generating a secret key.
This ensures only legitimate, signed requests from Snoooz reach your endpoint — all others you can safely reject.
Step 6: Click Save button
Make sure to hit the save button at the bottom of page to save the changes.
📨 When Does the Webhook Fire?
The webhook is triggered every time Snoooz processes an email that matches one of your rules.
This allows you to automate actions such as:
Logging emails in your CRM
Sending notifications to Slack
Starting an external workflow or script
📦 Example Payload
Here’s what a sample webhook payload looks like:
{
"event": "email.processed",
"timestamp": "2025-10-27T11:36:49.634Z",
"data": {
"message": {
"id": "19a252712f81bcd0",
"threadId": "19a252712f81bcd0",
"subject": "hey",
"snippet": "how are you? this is a test for webhooks.",
"direction": "inbound",
"body": {
"text": "Hey John,\n\nHow are you? This is a test for webhooks.\n\nBest,\nSam",
"html": "<p>Hey John,</p><p>How are you? This is a test for webhooks.</p><p>Best,<br>Sam</p>"
},
"attachments": {
"hasAttachment": true,
"count": 1,
"names": ["webhook_test_results.pdf"]
},
"meta": {
"sentiment": "positive",
"language": "en",
"category": "personal",
"dayOfWeek": "Monday",
"timezone": "America/New_York"
}
},
"sender": {
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Peters",
"fullName": "Sam Peters"
},
"recipient": {
"email": "[email protected]",
"addressedToMe": true,
"addressedOnlyToMe": true
},
"user": {
"email": "[email protected]"
},
"automation": {
"rulesMatched": [
{
"id": "rule_001",
"desc": "Auto-Reply to Test Emails"
}
],
"categoryMatched": "personal",
"calendarStatus": "free",
"actionTaken": "draftEmail",
"repliedOrDrafted": true,
"usedAI": true,
"generatedResponse": "<p>Hi Sam,</p><p>I'm doing well, thank you! I appreciate your message and the test for webhooks.</p><p>Best regards,<br>John</p>"
}
}
}
🔐 Secure Version
If you’re using a secret key, each request will include a signature header:
const SHARED_SECRET = 'f546b484a8aa59ac6b739643a5b2c8fa03ccb7da71c0d37f588424dba73fb0dd';
function decryptPayload(encryptedPayload, secret) {
const { data, iv, tag } = encryptedPayload;
const key = crypto.createHash('sha256').update(secret).digest();
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
key,
Buffer.from(iv, 'base64')
);
decipher.setAuthTag(Buffer.from(tag, 'base64'));
const decrypted = Buffer.concat([
decipher.update(Buffer.from(data, 'base64')),
decipher.final(),
]);
return JSON.parse(decrypted.toString('utf8'));
}
exports.webhookTest = onRequest(async (req, res) => {
try {
const encryptedPayload = req.body;
const signature = req.headers['x-app-signature'];
const timestamp = req.headers['x-app-timestamp'];
const securityMode = req.headers["x-app-security"] || "plaintext";
if (securityMode === "encrypted") {
// Perform signature validation + decryption
const expectedSig = crypto
.createHmac('sha256', SHARED_SECRET)
.update(`${timestamp}.${encryptedPayload.data}`)
.digest('hex');
if (expectedSig !== signature) {
return res.status(401).json({ error: 'Invalid Webhook Secret' });
}
const decrypted = decryptPayload(encryptedPayload, SHARED_SECRET);
console.log('Received payload: ', decrypted)
} else {
// Treat as normal JSON
console.log("Received plaintext webhook:", req.body);
}
res.status(200).json({ message: 'Successfully connected.' });
} catch (err) {
console.log('❌ Webhook error:', err);
res.status(400).json({ error: 'Invalid payload or decryption failed' });
}
});
You can verify this signature on your server to confirm that the request is from Snoooz.
🧠 Expected Endpoint Behavior
Your endpoint should:
Accept POST requests
Return a 200 OK response when successfully received
Optionally verify the request signature (if using a secret)
Example (plain text response):
OK
🛠 Need Custom Data?
If you’d like to include additional fields in your webhook payload, please submit a request here — we’d love to hear your suggestions!
💬 Having Trouble?
If you run into any issues, email us anytime at [email protected] — our team will be happy to assist.

