bernskiold/laravel-postmark
A Laravel package for sending email through Postmark, wiring Postmark's API into Laravel's mail system with sensible configuration and a simple setup for apps that need reliable transactional delivery.
composer require plus a route registration. The decision is now mostly about whether you want webhook handling to be a maintained dependency or owned code.EmailBounced and EmailComplained events give you the hooks to suppress bad addresses, flag accounts, and protect sender reputation. InactiveRecipients specifically targets Postmark's 406 "inactive recipient" rejections and extracts the offending addresses — this is the raw material for an automatic suppression list, which is a compliance and deliverability requirement rather than a nice-to-have.EmailOpened, EmailClicked): Enables product-level decisions like "did this onboarding sequence land," per-user engagement scoring, or triggering in-app nudges from email activity. Useful, but treat open tracking as directional only (Apple Mail Privacy Protection and image blocking distort it) — don't let a roadmap decision hinge on open rates alone.EmailSubscriptionChanged): Lets you reconcile Postmark's subscription state with your own preferences model, so unsubscribes propagate to your product rather than living only in the ESP. This is the event that reduces "we emailed someone who opted out" incidents.RecordType maps record type → event), so the backlog item can be written concretely: which events do we consume, what do we store, what do we act on.ProcessPostmarkWebhook job exposes configurable connection and queue. That's a deliberate product-level lever: webhook traffic spikes (a large send, a provider incident) shouldn't starve user-facing jobs. Worth deciding up front rather than discovering during an incident.VerifyPostmarkWebhook enforces HTTP Basic Auth on the endpoint, and the route macro wires it in. This lets you accept webhook traffic on a public URL without a bespoke auth story, which shortens security review and reduces the chance of shipping an unauthenticated endpoint under deadline pressure.Adopt when:
Look elsewhere or build in-house when:
Adoption caveats to plan for: version 1.0.0 means the pre-1.0 churn risk is behind it, but the project has no demonstrated release history. Pin the version, wrap the events in your own handlers rather than coupling business logic directly to package classes, and verify the middleware actually rejects unsigned/incorrectly-authenticated requests in a staging test before trusting it. Also decide explicitly what happens when the queue backs up or a job fails — webhooks are not retried indefinitely by Postmark, so a poison job can silently lose a bounce.
To executives: This is a small, focused library that connects Postmark's email delivery notifications to our application. It lets us automatically handle bounces, spam complaints, and unsubscribes instead of relying on manual processes or in-house glue code. The business value is sender reputation and list hygiene — bad addresses and complaints damage deliverability for everyone, which directly affects whether revenue-generating email reaches the inbox. Cost is near-zero (a dependency, not a service), and the work is a contained integration rather than a project.
To engineering: First stable release of a Postmark webhook package for Laravel 11–13 / PHP 8.2–8.4. It registers an authenticated webhook route via Route::postmarkWebhooks(), verifies HTTP Basic Auth in VerifyPostmarkWebhook, and dispatches a queued ProcessPostmarkWebhook job with configurable connection and queue so webhook traffic can be isolated from user-facing work. Payloads arrive as typed events (EmailBounced, EmailDelivered, EmailOpened, EmailClicked, EmailComplained, EmailSubscriptionChanged) with typed accessors for payload, metadata, client, and location; a RecordType enum maps record types to events. InactiveRecipients parses Postmark's 406 inactive-recipient rejections and extracts the addresses, which is the hook for automated suppression.
Known gaps to state plainly: no outbound sending, no built-in persistence or replay of raw webhooks, no idempotency guarantees, and no support contract. Treat 1.0.0 as early — pin the version, keep business logic in our own listeners, and add a staging test that confirms the middleware rejects bad credentials before this goes anywhere near production.
How can I help you explore Laravel packages today?