symfony/postmark-mailer
Symfony Mailer bridge for Postmark. Send email via Postmark using SMTP or the API by setting a postmark DSN (postmark+smtp://TOKEN@default or postmark+api://TOKEN@default). Provides seamless Postmark integration in Symfony apps.
Install the Package
Add to composer.json:
composer require symfony/postmark-mailer
Configure .env
Use either SMTP or API transport:
# SMTP Transport (recommended for transactional emails)
MAIL_MAILER=postmark
MAILER_DSN=postmark+smtp://YOUR_POSTMARK_SERVER_TOKEN@default
# API Transport (alternative)
MAILER_DSN=postmark+api://YOUR_POSTMARK_SERVER_TOKEN@default
First Use Case: Send a Test Email
Leverage Laravel’s Mail facade or Symfony’s MailerInterface:
use Illuminate\Support\Facades\Mail;
use App\Mail\TestEmail;
Mail::to('user@example.com')->send(new TestEmail());
Or via Symfony’s Mailer:
$mailer = $container->get(MailerInterface::class);
$email = (new Email())
->from('noreply@example.com')
->to('user@example.com')
->subject('Test Email')
->text('Hello, this is a test!');
$mailer->send($email);
Verify in Postmark Dashboard Check the Postmark web interface for delivered emails and analytics.
// Configure in config/mail.php
'postmark' => [
'transport' => 'postmark+smtp://token@default',
'options' => [
'host' => 'smtp.postmarkapp.com',
'port' => 587,
'encryption' => 'tls',
],
];
// Send via Laravel Mail
Mail::to($user->email)->send(new PasswordResetMail($token));
// Custom Symfony Mailer transport in Laravel
$mailer = app(MailerInterface::class);
$email = (new Email())
->from('marketing@example.com')
->to('user@example.com')
->subject('Summer Sale')
->html(view('emails.promo'))
->addHeader('X-Postmark-Send-With', 'PostmarkAPI'); // Force API transport
$mailer->send($email);
Http client.// Route webhook to Laravel controller
Route::post('/postmark/webhook', [PostmarkWebhookController::class, 'handle']);
// Controller logic
public function handle(Request $request) {
$payload = $request->json()->all();
if ($payload['MessageID'] && $payload['To']) {
// Parse and process inbound email
$this->processInboundEmail($payload);
}
}
// Dispatch a queued mailable
Mail::to($user->email)->queue(new WelcomeEmail($user));
// Configure queue in config/mail.php
'postmark' => [
'queue' => 'default', // Use Laravel queues
];
Laravel-Symfony Bridge
PostmarkTransport for Laravel:
use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Mailer\Transport\Dsn;
class PostmarkTransport extends \Symfony\Component\Mailer\Transport\PostmarkTransport
{
public function __construct(Dsn $dsn, array $options = [])
{
parent::__construct($dsn, $options);
}
}
AppServiceProvider:
public function register()
{
$this->app->singleton(TransportInterface::class, function ($app) {
$dsn = new Dsn(config('mail.postmark.transport'));
return new PostmarkTransport($dsn, config('mail.postmark.options'));
});
}
Postmark Templates
$email = (new Email())
->from('noreply@example.com')
->to('user@example.com')
->subject('Welcome!')
->html(view('emails.welcome', ['user' => $user]))
->addHeader('X-Postmark-Template-ID', '12345'); // Your Postmark template ID
Error Handling
TransportException for Laravel’s exception handler:
try {
$mailer->send($email);
} catch (\Symfony\Component\Mailer\Exception\TransportException $e) {
report($e); // Log via Laravel's reporting
throw new \Exception('Failed to send email: ' . $e->getMessage());
}
Testing
TestMailer or Laravel’s MailFake:
// Laravel test example
public function test_email_sends()
{
Mail::fake();
Mail::to('user@example.com')->send(new TestEmail());
Mail::assertSent(TestEmail::class);
}
SMTP vs. API Transport Quirks
Date Header Dropped in API Transport
Date header (as per #60256).
$email->addHeader('Date', (new \DateTime())->format('r'));
Attachment CID Issues
$email->attachFromPath($path)
->if(function ($message) {
$message->getHeaders()->addTextHeader('Content-ID', '<unique-id>');
});
Payload Too Large Errors
Webhook IP Allowlist
Enable Verbose Logging
Configure Symfony’s logger in config/mail.php:
'postmark' => [
'options' => [
'debug' => env('MAIL_DEBUG', false),
],
];
storage/logs/laravel.log) for transport errors.Postmark API Debugging
curl -X POST https://api.postmarkapp.com/email \
-H "X-Postmark-Server-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"From": "sender@example.com", "To": "recipient@example.com", "Subject": "Test", "HtmlBody": "<p>Hello</p>"}'
Common Errors and Fixes
| Error | Cause | Solution |
|---|---|---|
Invalid Server Token |
Wrong MAILER_DSN token |
Verify .env and Postmark account. |
Payload Too Large |
Email > 10MB | Use SMTP or compress attachments. |
Date header missing |
API transport quirk | Manually add Date header. |
Webhook IP not allowed |
Missing IP allowlist | Wh |
How can I help you explore Laravel packages today?