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('[email protected]')
                ->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('[email protected]')->send(new WelcomeEmail($user));

2. Customizing Headers/Metadata

Attach Postmark-specific metadata or headers:

Mail::raw('Content', function ($message) {
    $message->to('[email protected]')
            ->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(['[email protected]', '[email protected]'])
    ->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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle