Skip to main content

Webhook-Driven Email Automation in 5 Minutes

· 10 min read
Jones
Co-Founder and Architect @ Codehooks

Every modern SaaS needs to react to events: a user signs up, a payment succeeds, a trial expires. Webhooks are the glue that connects these events to your business logic—but building reliable webhook infrastructure means managing servers, queues, retries, and databases.

Email automation platforms promise to handle this, but they come with baggage: vendor lock-in, limited webhook integrations, and opaque pricing that scales against you.

What if your webhook endpoints could directly power your email automation?

The Problem with Email Automation SaaS

Mailchimp, ConvertKit, ActiveCampaign—they all solve the same problem: sending automated email sequences. But they come with baggage:

  • Limited webhook support: Want to trigger emails from Stripe events? Custom webhooks from your app? Good luck integrating.
  • Vendor lock-in: Your subscribers live in their database
  • Black boxes: Webhook failed? Email bounced? You'll never know why.
  • Scaling costs: $50/month for 500 subscribers, $300/month for 10,000

What if you could own the entire stack—starting with your webhook endpoints?

Enter Codehooks.io: Webhooks Made Simple

Codehooks.io is built for webhooks. Deploy endpoint handlers in seconds, connect them to databases and queues, and let the platform handle the infrastructure.

I built a drip email template that showcases this:

Webhook-first architecture - Receive events from Stripe, signup forms, Zapier, or any service

Full control - You own the code, subscribers, and sending logic

Any email provider - SendGrid, Mailgun, Postmark—switch with one env var

Built-in queues & cron - No external services to configure

Production-ready - Scales to 100k+ subscribers with streaming architecture

And it deploys in 5 minutes.

View the source code: github.com/RestDB/codehooks-io-templates/drip-email-workflow

How It Works

Here's the webhook-driven architecture:

Webhook endpoints receive events. Cron processes them. Queues deliver emails. That's it.

Configure Your Workflow in JSON

{
"workflowSteps": [
{
"step": 1,
"hoursAfterSignup": 24,
"template": {
"subject": "Welcome to Our Community! 🎉",
"heading": "Welcome, {{name}}!",
"body": "Thanks for signing up...",
"buttonText": "Get Started",
"buttonUrl": "https://example.com/get-started"
}
},
{
"step": 2,
"hoursAfterSignup": 96,
"template": {
"subject": "Quick Tips to Get You Started 💡",
"heading": "Here are some tips, {{name}}",
"body": "..."
}
}
]
}

Add 3 steps or 30—same architecture, same simplicity.

Deploy in 5 Minutes

# 1. Create from template
coho create my-drip-campaign --template drip-email-workflow
cd my-drip-campaign
npm install

# 2. Deploy
coho deploy

# 3. Configure email provider (pick one)
coho set-env EMAIL_PROVIDER "sendgrid"
coho set-env SENDGRID_API_KEY "SG.your-key"
coho set-env FROM_EMAIL "[email protected]"
coho set-env FROM_NAME "Your Company"

# 4. Add a subscriber
curl -X POST https://your-project.api.codehooks.io/dev/subscribers \
-H "Content-Type: application/json" \
-H "x-apikey: YOUR_API_KEY" \
-d '{"name":"Jane Doe","email":"[email protected]"}'

Done. Your drip campaign is running.

Why Codehooks for Webhooks?

Building reliable webhook infrastructure traditionally requires stitching together:

  • Serverless functions (AWS Lambda)
  • API Gateway for HTTPS endpoints
  • Database (MongoDB Atlas)
  • Cron scheduler (CloudWatch Events)
  • Queue system (SQS) for async processing
  • Retry logic and dead letter queues
  • Environment secrets management

That's a lot of DevOps for receiving a webhook.

Codehooks gives you all of this in one platform, purpose-built for webhooks:

import { app, Datastore } from 'codehooks-js';

// Webhook endpoint - receives events from any service
app.post('/subscribers', async (req, res) => {
const conn = await Datastore.open();
await conn.insertOne('subscribers', { email: req.body.email });
res.json({ success: true });
});

// Webhook from Stripe - handle payment events
app.post('/stripe-webhook', async (req, res) => {
const event = req.body;
if (event.type === 'checkout.session.completed') {
const conn = await Datastore.open();
await conn.insertOne('subscribers', {
email: event.data.object.customer_email,
name: event.data.object.customer_details.name,
source: 'stripe'
});
}
res.json({ received: true });
});

// Built-in cron job - process subscribers periodically
app.job('*/15 * * * *', async (req, res) => {
// Find subscribers ready for next email
// Queue them for sending
});

// Built-in queue worker - handle async email delivery
app.worker('send-email', async (req, res) => {
// Send the email
});

export default app.init();

No Docker. No Kubernetes. No infrastructure YAML files. Just write webhook handlers and deploy.

The Architecture Scales

Here's what makes this production-ready:

1. Streaming Architecture

Instead of loading all subscribers into memory:

// ❌ Memory issues with large lists
const subscribers = await conn.getMany('subscribers').toArray();
for (const sub of subscribers) {
await processSubscriber(sub);
}

// ✅ Constant memory usage
await conn.getMany('subscribers').forEach(async (sub) => {
await processSubscriber(sub);
});

Handles 100k subscribers as easily as 100.

2. Race Condition Prevention

The cron job atomically marks emails as sent before queueing:

const result = await conn.updateOne(
'subscribers',
{
_id: subscriber._id,
emailsSent: { $nin: [step] } // Only if not already sent
},
{ $push: { emailsSent: step } }
);

// Only queue if we won the race
if (result) {
await conn.enqueue('send-email', { subscriberId, step });
}

No duplicate emails even if cron jobs overlap.

3. Automatic Retry on Failure

If email sending fails, the worker removes it from the sent list:

catch (error) {
await conn.updateOne(
'subscribers',
{ _id: subscriberId },
{ $pull: { emailsSent: step } }
);
// Next cron run will retry
}

Ensures delivery without manual intervention.

Real-World Webhook Integrations

Stripe Webhooks → Onboarding Emails

When a customer completes checkout, automatically start their onboarding sequence:

app.post('/stripe-webhook', async (req, res) => {
const sig = req.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(req.rawBody, sig, webhookSecret);

if (event.type === 'checkout.session.completed') {
const session = event.data.object;
const conn = await Datastore.open();
await conn.insertOne('subscribers', {
email: session.customer_email,
name: session.customer_details.name,
plan: session.metadata.plan,
source: 'stripe_checkout'
});
}
res.json({ received: true });
});

Point your Stripe webhook to https://your-project.api.codehooks.io/dev/stripe-webhook and customers automatically enter your drip sequence.

Signup Form Webhooks

Connect any form provider—Typeform, Tally, your own frontend:

app.post('/subscribers', async (req, res) => {
const conn = await Datastore.open();
await conn.insertOne('subscribers', {
email: req.body.email,
name: req.body.name,
source: req.body.source || 'api'
});
res.json({ success: true });
});

Webhook from Your App

Add users to campaigns directly from your application:

// In your app's signup flow
await fetch('https://your-project.api.codehooks.io/dev/subscribers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-apikey': process.env.DRIP_API_KEY
},
body: JSON.stringify({
name: user.name,
email: user.email,
source: 'app_signup'
})
});

The cron job handles everything else automatically.

Test Without Sending Emails

coho set-env DRY_RUN "true"
# Watch logs to verify workflow logic
coho logs --follow

No redeployment needed—DRY_RUN is checked at runtime.

Switch Email Providers

# Currently using SendGrid? Switch to Mailgun:
coho set-env EMAIL_PROVIDER "mailgun"
coho set-env MAILGUN_API_KEY "your-key"
coho set-env MAILGUN_DOMAIN "mg.yourdomain.com"

Your campaign keeps running. Zero downtime.

Handle Email Provider Webhooks

Receive delivery status, bounces, and unsubscribes from your email provider:

// SendGrid Event Webhook
app.post('/sendgrid-events', async (req, res) => {
const events = req.body;
const conn = await Datastore.open();

for (const event of events) {
if (event.event === 'bounce' || event.event === 'dropped') {
await conn.updateOne('subscribers',
{ email: event.email },
{ $set: { status: 'bounced', bouncedAt: new Date() }}
);
}
if (event.event === 'unsubscribe') {
await conn.updateOne('subscribers',
{ email: event.email },
{ $set: { status: 'unsubscribed' }}
);
}
}
res.json({ received: true });
});

Your email provider sends events to your webhook, and your campaign stays clean automatically.

The Cost Breakdown

Here's what running a production drip campaign actually costs:

For 5,000 subscribers (3-step sequence):

Self-hosted:

  • Codehooks Pro: $19/month
  • SendGrid Essentials: $19.95/month (50k emails/month)
  • Total: $467/year

Email automation SaaS:

  • Mailchimp Standard: ~$55-85/month = $660-1,020/year
  • ActiveCampaign: ~$125/month = $1,500/year
  • ConvertKit: Custom pricing, typically $700-900/year

Savings: $193-1,033/year while owning your infrastructure.

For 50,000 subscribers:

Self-hosted:

  • Codehooks Pro: $19/month
  • SendGrid Pro: $89.95/month (up to 700k emails/month)
  • Total: $1,307/year

Email automation SaaS:

  • Mailchimp: ~$300-400/month = $3,600-4,800/year
  • ActiveCampaign: ~$500+/month = $6,000+/year
  • ConvertKit: Custom enterprise pricing = $4,000-6,000+/year

Savings: $2,293-4,693/year at scale.

The difference? You own the code, control the data, and can switch email providers anytime. No vendor lock-in, no surprise overage fees, complete transparency.

Get Started

The drip email workflow template is open source and ready to deploy:

npm install -g codehooks
coho create my-campaign --template drip-email-workflow
cd my-campaign
coho deploy

What's included:

  • Webhook endpoints for subscriber management (connect Stripe, forms, your app)
  • Built-in cron jobs and queue workers
  • Professional responsive email templates
  • Email provider webhooks for bounces/unsubscribes
  • SendGrid, Mailgun, and Postmark integrations
  • Example configurations for common use cases

Browse all templates: codehooks.io/templates

When to Use This

This webhook-driven approach is perfect for:

  • Event-driven onboarding - Stripe checkout → welcome sequence
  • Multi-source campaigns - Aggregate subscribers from forms, apps, payment events
  • Course delivery - Timed content drips triggered by purchase webhooks
  • Lead nurturing - Connect your CRM webhooks to email automation

But maybe not ideal for:

  • Transactional emails with <1min SLA (use a dedicated service)
  • Teams that need no-code visual builders
  • Simple newsletters without automation logic

Why This Matters

Webhooks are the backbone of modern SaaS integrations. But building reliable webhook infrastructure—endpoints that validate, store, queue, and process events—shouldn't require a DevOps team.

With Codehooks, you get:

  1. Webhook-native platform - Purpose-built for receiving and processing events
  2. Instant deployment - From zero to production webhook endpoints in 5 minutes
  3. Built-in reliability - Queues, retries, and cron jobs out of the box
  4. Proven scalability - Streaming architecture handles 100k+ events
  5. Complete flexibility - Connect Stripe, forms, your app—any webhook source

The template showcases what's possible: webhook endpoints, cron scheduling, queue workers, database, email delivery—all in one platform. No Docker, no Kubernetes, no infrastructure complexity.

This is what Codehooks is built for: turning webhooks into action.

Future Email Provider Integrations

The drip email template currently supports SendGrid, Mailgun, and Postmark—but we're actively expanding provider support based on community feedback.

Coming Soon

Amazon SES - AWS's cost-effective email service ($0.10 per 1,000 emails) is perfect for high-volume campaigns. With its proven reliability and deep AWS integration, SES is a natural fit for teams already on AWS infrastructure.

Brevo (formerly Sendinblue) - European privacy-focused alternative with generous free tier (300 emails/day) and advanced marketing automation features. Great for GDPR-conscious teams and startups testing their first drip campaigns.

Postal (Open Source) - For teams that want complete control, Postal offers a self-hosted email delivery platform. Deploy it alongside your Codehooks webhooks and own your entire email infrastructure—from webhook to inbox.

Why Multiple Providers Matter

Email deliverability isn't one-size-fits-all:

  • Geographic optimization - SES for US, Brevo for EU compliance
  • Failover resilience - Switch providers if deliverability drops
  • Cost optimization - Test providers to find your best rate
  • Exit strategy - Never locked into one vendor

The template's provider abstraction makes adding new integrations straightforward—just implement the email sending interface and configure the environment variables.

Want a specific provider? Open an issue or contribute an integration. The template is open source and accepts pull requests.


Next Steps

New to Codehooks? Sign up for free and deploy your first webhook endpoint:

npm install -g codehooks
coho create my-drip-campaign --template drip-email-workflow

Explore the code: Browse the complete template source code on GitHub to see how it works.

Want to explore more? Check out our other templates, webhook documentation, and queue workers.

Questions? Email us at [email protected].


This template is open source and production-ready. Deploy your webhook endpoints today and take back control of your automation stack.