Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Postmark Laravel Package

openbuildings/postmark

Laravel package for integrating Postmark email delivery into your app. Provides a simple mail driver and configuration for sending transactional emails via Postmark’s API, fitting neatly into Laravel’s mail system with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require openbuildings/postmark
    
  2. Configuration Publish the config file:

    php artisan vendor:publish --provider="OpenBuildings\Postmark\PostmarkServiceProvider"
    

    Update .env with your Postmark API key:

    POSTMARK_API_KEY=your_api_key_here
    
  3. First Use Case Replace Laravel's default Swift Mailer transport in config/mail.php:

    'transport' => [
        'driver' => 'postmark',
    ],
    

    Send a test email:

    Mail::raw('Test email body', function ($message) {
        $message->to('recipient@example.com')
                ->subject('Test Subject');
    });
    

Key Files to Review

  • config/postmark.php (default settings)
  • app/Providers/AppServiceProvider.php (if customizing mail transport binding)

Implementation Patterns

Common Workflows

1. Basic Email Sending

Use Laravel's Mail facade as usual:

Mail::to('user@example.com')->send(new WelcomeEmail($user));

2. Customizing Headers/Metadata

Attach Postmark-specific metadata or headers:

Mail::raw('Content', function ($message) {
    $message->to('user@example.com')
            ->subject('Subject')
            ->withSwiftMessage(function ($swiftMessage) {
                $swiftMessage->getHeaders()->addTextHeader('X-Metadata', 'key=value');
            });
});

3. Tracking and Analytics

Enable Postmark's tracking features via config:

'options' => [
    'track_opens' => true,
    'track_links' => true,
],

4. Batch Sending

Use Postmark's batch API for high-volume emails:

Mail::batch(['user1@example.com', 'user2@example.com'])
    ->send(new NewsletterEmail());

5. Fallback Transport

Combine with Laravel's default transport for fallback:

'transport' => [
    'driver' => 'failover',
    'options' => [
        'primary' => 'postmark',
        'secondary' => 'smtp',
    ],
],

Integration Tips

With Laravel Notifications

Extend Mailable or Notification classes to inject Postmark-specific data:

public function build()
{
    return $this->withSwiftMessage(function ($message) {
        $message->getHeaders()->addTextHeader('X-Custom-Header', 'value');
    });
}

With Queueing

Queue emails for async sending (Postmark supports this natively):

Mail::queue(new OrderConfirmation($order));

With Laravel Horizon

Monitor Postmark queue jobs in Horizon for debugging.

With API Keys per Environment

Use Laravel's .env files to switch keys per environment (e.g., POSTMARK_API_KEY_STAGING).


Gotchas and Tips

Pitfalls

  1. API Key Exposure

    • Never commit .env or hardcode keys in code.
    • Use Laravel's env() helper or config caching.
  2. Rate Limits

    • Postmark has rate limits. Monitor usage in the Postmark dashboard.
    • Implement exponential backoff for retries:
      'options' => [
          'retry' => true,
          'retry_delay' => 30, // seconds
      ],
      
  3. HTML vs. Text Emails

    • Postmark prioritizes HTML content. Ensure setBody() includes both:
      $message->setBody('HTML content', 'text/html')
              ->setBody('Plain text fallback', 'text/plain');
      
  4. Attachment Size Limits

    • Postmark has a 26MB attachment limit. Validate files before uploading:
      if ($file->getSize() > 26 * 1024 * 1024) {
          throw new \Exception('File too large for Postmark');
      }
      
  5. Debugging Failed Emails

    • Check Postmark's API logs for errors.
    • Enable Swift Mailer logging in config/mail.php:
      'log' => env('MAIL_LOG', true),
      

Debugging Tips

  1. Enable Verbose Logging Add to config/postmark.php:

    'debug' => env('APP_DEBUG', false),
    
  2. Inspect Raw Swift Message Use a MailMacro to log the Swift message before sending:

    Mail::macro('logSwiftMessage', function ($callback) {
        $callback(Mail::getSwiftMessage());
    });
    
  3. Test with Postmark's Sandbox Use the Postmark sandbox mode (enabled via API key) to test without sending real emails.

Extension Points

  1. Custom Transport Binding Override the transport binding in AppServiceProvider:

    public function register()
    {
        $this->app->bind(\Swift_Transport::class, function ($app) {
            return new \OpenBuildings\Postmark\PostmarkTransport(
                $app['config']['postmark.api_key'],
                $app['config']['postmark.options']
            );
        });
    }
    
  2. Event Listeners Listen for mail.sent events to log or process Postmark-specific data:

    Mail::sent(function ($message) {
        if ($message->getSwiftMessage()->getHeaders()->get('X-Metadata')) {
            // Handle Postmark metadata
        }
    });
    
  3. Middleware for Headers Create middleware to inject Postmark headers globally:

    public function handle($request, Closure $next)
    {
        Mail::macro('addPostmarkHeader', function ($key, $value) {
            Mail::getSwiftMessage()->getHeaders()->addTextHeader($key, $value);
        });
        return $next($request);
    }
    
  4. Testing Use Postmark's API mocking in PHPUnit:

    $this->partialMock(\OpenBuildings\Postmark\PostmarkTransport::class, ['send']);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor