mcpField
P
postmark-webhooks

postmark-webhooks

github.com/hookdeckDevelopment95203 installsUpdated today
Repository

About postmark-webhooks

A skill for developers building Postmark webhook handlers. It covers email event processing, URL-based authentication, security checks, and local testing.

Key features

  1. 01Process delivery, bounce, open, and click events
  2. 02Handle complaints and subscription changes
  3. 03Authenticate with URL credentials
  4. 04Validate payloads and secure endpoints
  5. 05Test locally with Hookdeck CLI

Use cases

  1. 01Track email engagement and delivery
  2. 02Update contacts after bounces or complaints
  3. 03Implement unsubscribe and resubscribe handling

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/hookdeck/webhook-skills --skill postmark-webhooks

After installing, type/postmark-webhooksin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

TODO.md
examples/express/
.env.example
package.json
README.md
examples/express/src/
index.js
examples/express/test/
webhook.test.js
examples/fastapi/
.env.example
main.py
README.md
requirements.txt
test_webhook.py
examples/nextjs/
.env.example
package.json
README.md
vitest.config.ts
examples/nextjs/app/webhooks/postmark/
route.ts
examples/nextjs/test/
webhook.test.ts
references/
overview.md
setup.md
verification.md

Details

From the project README

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.

// Express - Basic Auth in URL
// Configure webhook URL in Postmark as:
// https://username:[email protected]/webhooks/postmark

app.post('/webhooks/postmark', express.json(), (req, res) => {
  // Basic auth is handled by your web server or proxy
  // Additional validation can check expected payload structure

  const event = req.body;

  // Validate expected fields exist
  if (!event.RecordType || !event.MessageID) {
    return res.status(400).send('Invalid payload structure');
  }

  // Process event
  console.log(`Received ${event.RecordType} event for ${event.Email}`);

  res.sendStatus(200);
});

// Alternative: Token in URL
// Configure webhook URL as:
// https://yourdomain.com/webhooks/postmark?token=your-secret-token

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
// Postmark sends one event per request (not batched)
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}`);
      // Update contact as undeliverable
      break;

    case 'SpamComplaint':
      console.log(`Spam complaint: ${event.Email}`);
      // Remove from mailing list
      break;

    case 'Open':
      console.log(`Email opened: ${event.Email} at ${event.ReceivedAt}`);
      // Track engagement
      break;

    case 'Click':
      console.log(`Link clicked: ${event.Email} - ${event.OriginalLink}`);
      // Track click-through rate
      break;

    case 'Delivery':
      console.log(`Delivered: ${event.Email} at ${event.DeliveredAt}`);
      // Confirm delivery
      break;

    case 'SubscriptionChange':
      console.log(`Subscription change: ${event.Email} - ${event.ChangedAt}`);
      // Update subscription preferences
      break;

    case 'Inbound':
      console.log(`Inbound email from: ${event.Email} - Subject: ${event.Subject}`);
      // Process incoming email
      break;

    case 'SMTP API Error':
      console.log(`SMTP API error: ${event.Email} - ${event.Error}`);
      // Handle API error, maybe retry
      break;

    default:
      console.log(`Unknown event type: ${event.RecordType}`);
  }

  res.sendStatus(200);
});

Common Event Types

EventRecordTypeDescriptionKey Fields
BounceBounceHard/soft bounce or blocked emailEmail, Type, TypeCode, Description
Spam ComplaintSpamComplaintRecipient marked as spamEmail, BouncedAt
OpenOpenEmail opened (requires open tracking)Email, ReceivedAt, Platform, UserAgent
ClickClickLink clicked (requires click tracking)Email, ClickedAt, OriginalLink
DeliveryDeliverySuccessfully deliveredEmail, DeliveredAt, Details
Subscription ChangeSubscriptionChangeUnsubscribe/resubscribeEmail, ChangedAt, SuppressionReason
InboundInboundIncoming email receivedEmail, FromFull, Subject, TextBody, HtmlBody
SMTP API ErrorSMTP API ErrorSMTP API call failedEmail, Error, ErrorCode, MessageID

Environment Variables

# For token-based authentication
POSTMARK_WEBHOOK_TOKEN="your-secret-token-here"

# For basic auth (if not using URL-embedded credentials)
WEBHOOK_USERNAME="your-username"
WEBHOOK_PASSWORD="your-password"

Security Best Practices

  1. Always use HTTPS - Never configure webhooks with HTTP URLs
  2. Use strong credentials - Generate long, random tokens or passwords
  3. Validate payload structure - Check for expected fields before processing
  4. Implement IP allowlisting - Postmark publishes their IP ranges
  5. 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

Comments

Markdown supported