| name | postmark-webhooks |
| description | Receive and process Postmark webhooks. Use when setting up Postmark webhook handlers, handling email delivery events, processing bounces, opens, clicks, spam complaints, or subscription changes.
|
| license | MIT |
| metadata | {"author":"hookdeck","version":"0.1.0","repository":"https://github.com/hookdeck/webhook-skills"} |
Postmark Webhooks
When to Use This Skill
- Setting up Postmark webhook handlers for email event tracking
- Processing email delivery events (bounce, delivered, open, click)
- Handling spam complaints and subscription changes
- Implementing email engagement analytics
- Troubleshooting webhook authentication issues
Essential Code
Authentication
Postmark does NOT use signature verification. Instead, webhooks are authenticated by including credentials in the webhook URL itself.
app.post('/webhooks/postmark', express.json(), (req, res) => {
const event = req.body;
if (!event.RecordType || !event.MessageID) {
return res.status(400).send('Invalid payload structure');
}
console.log(`Received ${event.RecordType} event for ${event.Email}`);
res.sendStatus(200);
});
app.post('/webhooks/postmark', express.json(), (req, res) => {
const token = req.query.token;
if (token !== process.env.POSTMARK_WEBHOOK_TOKEN) {
return res.status(401).send('Unauthorized');
}
const event = req.body;
console.log(`Received ${event.RecordType} event`);
res.sendStatus(200);
});
Handling Multiple Events
app.post('/webhooks/postmark', express.json(), (req, res) => {
const event = req.body;
switch (event.RecordType) {
case 'Bounce':
console.log(`Bounce: ${event.Email} - ${event.Type} - ${event.Description}`);
break;
case 'SpamComplaint':
console.log(`Spam complaint: ${event.Email}`);
break;
case 'Open':
console.log(`Email opened: ${event.Email} at ${event.ReceivedAt}`);
break;
case 'Click':
console.log(`Link clicked: ${event.Email} - ${event.OriginalLink}`);
break;
case 'Delivery':
console.log(`Delivered: ${event.Email} at ${event.DeliveredAt}`);
break;
case 'SubscriptionChange':
console.log(`Subscription change: ${event.Email} - ${event.ChangedAt}`);
break;
case 'Inbound':
console.log(`Inbound email from: ${event.Email} - Subject: ${event.Subject}`);
break;
case 'SMTP API Error':
console.log(`SMTP API error: ${event.Email} - ${event.Error}`);
break;
default:
console.log(`Unknown event type: ${event.RecordType}`);
}
res.sendStatus(200);
});
Common Event Types
| Event | RecordType | Description | Key Fields |
|---|
| Bounce | Bounce | Hard/soft bounce or blocked email | Email, Type, TypeCode, Description |
| Spam Complaint | SpamComplaint | Recipient marked as spam | Email, BouncedAt |
| Open | Open | Email opened (requires open tracking) | Email, ReceivedAt, Platform, UserAgent |
| Click | Click | Link clicked (requires click tracking) | Email, ClickedAt, OriginalLink |
| Delivery | Delivery | Successfully delivered | Email, DeliveredAt, Details |
| Subscription Change | SubscriptionChange | Unsubscribe/resubscribe | Email, ChangedAt, SuppressionReason |
| Inbound | Inbound | Incoming email received | Email, FromFull, Subject, TextBody, HtmlBody |
| SMTP API Error | SMTP API Error | SMTP API call failed | Email, Error, ErrorCode, MessageID |
Environment Variables
POSTMARK_WEBHOOK_TOKEN="your-secret-token-here"
WEBHOOK_USERNAME="your-username"
WEBHOOK_PASSWORD="your-password"
Security Best Practices
- Always use HTTPS - Never configure webhooks with HTTP URLs
- Use strong credentials - Generate long, random tokens or passwords
- Validate payload structure - Check for expected fields before processing
- Implement IP allowlisting - Postmark publishes their IP ranges
- Consider using a webhook gateway - Like Hookdeck for additional security layers
Local Development
For local webhook testing, use Hookdeck CLI:
npx hookdeck-cli listen 3000 postmark --path /webhooks/postmark
No account required. Provides local tunnel + web UI for inspecting requests.
Resources
- overview.md - What Postmark webhooks are, common event types
- setup.md - Configure webhooks in Postmark dashboard
- verification.md - Authentication methods and security best practices
- examples/ - Complete implementations for Express, Next.js, and FastAPI
Recommended: webhook-handler-patterns
For production-ready webhook handling, also install the webhook-handler-patterns skill:
Related Skills