securitySecuring Teachable Webhooks: The Secret Token Gateway
Teachable's webhook payloads aren't signed. Learn how to protect your server from spoofed API payloads using a secret token gateway.
When you build a custom webhook endpoint to listen for Teachable sales or enrollments, you are opening a door directly to your server.
With enterprise platforms like Shopify or Stripe, that door is guarded by cryptography. They sign every webhook using an HMAC-SHA256 hash, proving mathematically that the payload is authentic.
Teachable's webhooks don't include a signature. That means your endpoint can't tell a genuine request from a fake one on its own. If someone discovers your Render or AWS endpoint URL, they could send a POST request claiming they just bought your $5,000 course.
The Trap: Checking the "Origin" Header
Many developers try to fix this by checking if the request's HTTP header says Origin: https://teachable.com.
This is the equivalent of trusting the return address on a forged letter. Anyone with a basic terminal or Postman can manually type that header into their fake request. If your server only checks the envelope, a forged request gets through.
The Solution: The Secret Token Gateway
Without a signature to check, I use the next best standard: a cryptographically secure query parameter. The webhook URL itself becomes the password.
- Generate a Secret: Create a long, random string (e.g.,
sk_live_9a8b7c6d5e4f) and store it securely in your server's.envfile. - Configure Teachable: In your Teachable admin dashboard, append this token to your webhook URL:
https://your-api.com/webhooks/teachable?token=sk_live_9a8b7c6d5e4f. - Build the Gateway: Because the request travels over HTTPS, the URL parameters are fully encrypted in transit. Your Node.js server intercepts the request and checks the token before ever reading the payload.
The Code: Express.js Authentication Middleware
Instead of writing this check inside every single route, I build it as Express middleware. This acts as a bouncer, instantly rejecting unauthorized traffic across your entire application.
const express = require('express');
const app = express();
app.use(express.json());
// 1. Define the Gateway Middleware
function requireTeachableToken(req, res, next) {
const expectedToken = process.env.TEACHABLE_WEBHOOK_TOKEN;
const providedToken = req.query.token;
if (!expectedToken) {
console.error('CRITICAL: Webhook token not configured in environment.');
return res.status(500).send('Server configuration error');
}
// 2. Reject mismatched tokens instantly
if (providedToken !== expectedToken) {
console.warn(`Blocked unauthorized webhook attempt from IP: ${req.ip}`);
return res.status(401).send('Unauthorized: Invalid security token');
}
// 3. Token is valid, proceed to the business logic
next();
}
// Apply the middleware to your Teachable endpoints
app.post('/api/teachable-events', requireTeachableToken, (req, res) => {
// Acknowledge receipt immediately
res.status(200).send('Webhook verified and received safely');
const payload = req.body;
console.log(`Processing secure, verified event: ${payload.type}`);
// Safe to execute Airtable, ActiveCampaign, or database sync logic here...
});
app.listen(3000, () => console.log('Secure Teachable gateway running'));Why this architecture is mandatory
- Protects your Database: Bad actors cannot corrupt your CRM or Airtable base with forged student data.
- Saves Compute: By rejecting bad requests at the middleware level, your server doesn't waste CPU cycles or database read/writes parsing malicious JSON.
- Prevents Revenue Loss: It completely locks down automated enrollment systems, ensuring no one gets access to your intellectual property without a verified Teachable transaction.
Purple Hippo Web Studio
Need this built, not just documented?
I build custom Teachable integrations, webhook systems and B2B enrollment portals. Fixed scope, fixed price, no surprises.
Get in touch