LettermintLettermint
  • Knowledge base
  • Community
  • Changelog
  • Support
  • Documentation
  • Sending API
  • Team API
Getting started
Guides
    Node.jsPHPPythonGoLaravelMagento 2WordPressNuxtJava
    SMTP
Platform
Resources
Guides

Laravel

The official Lettermint Laravel package adds a mail driver that sends Laravel's email through Lettermint. It is a drop-in transport, so the Mail facade, Mailables, notifications, and queued mail keep working exactly as before, now delivered through Lettermint. On top of that, it adds tags, metadata, per-route mailers, idempotency, and webhook events as first-class Laravel features.

Every message is delivered through Lettermint's European infrastructure, which runs entirely inside the EU and processes mail in line with GDPR. That makes it a solid fit for transactional email from a Laravel app, such as order confirmations, password resets, and account notifications. The package wraps the Lettermint PHP SDK, so if you are not on Laravel you can use that directly instead.

Requirements

Before you start you need:

  • PHP 8.2 or newer with Laravel 10 or newer
  • A Lettermint account with a verified sending domain
  • A Project API token from your project settings

If your domain is not verified yet, follow the domain setup guide first so your mail reaches the inbox instead of the spam folder.

1. Installation

Install the package via Composer:

TerminalCode
composer require lettermint/lettermint-laravel

Publish the configuration file:

TerminalCode
php artisan vendor:publish --tag="lettermint-config"

2. Configuration

Environment Variables

Add your Lettermint credentials to .env:

Code
LETTERMINT_PROJECT_TOKEN=your-lettermint-project-token # Optional: required only when using the Team API client LETTERMINT_TEAM_TOKEN=your-lettermint-team-token LETTERMINT_ROUTE_ID=your-route-id

LETTERMINT_PROJECT_TOKEN is used for sending email through Laravel mail. The legacy LETTERMINT_TOKEN variable is still supported as a fallback, but LETTERMINT_PROJECT_TOKEN is preferred for new applications and v2 upgrades.

Services Configuration

Add to config/services.php:

Code
'lettermint' => [ 'token' => env('LETTERMINT_PROJECT_TOKEN', env('LETTERMINT_TOKEN')), 'api_token' => env('LETTERMINT_TEAM_TOKEN'), ],

api_token is only needed when resolving the Team API client from Laravel's container. Use a Team API token for that value.

Mail Configuration

Add the Lettermint mailer to config/mail.php:

Code
'mailers' => [ // ... other mailers 'lettermint' => [ 'transport' => 'lettermint', 'route_id' => env('LETTERMINT_ROUTE_ID'), 'idempotency' => true, 'idempotency_window' => 86400, ], ],

Set Lettermint as your default mailer in .env:

Code
MAIL_MAILER=lettermint

3. Send Your First Email

Send emails using Laravel's standard Mail facade:

Code
use App\Mail\WelcomeEmail; use Illuminate\Support\Facades\Mail; Mail::to('recipient@example.com')->send(new WelcomeEmail($user));

Or specify the mailer explicitly:

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

Queued and Bulk Sending

Because Lettermint is a standard Laravel mail driver, it works with Laravel's queue and notification systems out of the box. Queue a message so sending happens in the background:

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

Or have a Mailable always queue by implementing ShouldQueue:

Code
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; class WelcomeEmail extends Mailable implements ShouldQueue { // ... }

For higher volumes, dispatch onto a dedicated queue and process it with Horizon or queue:work, exactly as you would with any Laravel mailer.

4. Tags

Categorize emails for filtering and analytics in your Lettermint dashboard.

Using the tag() Method

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

In Mailable Envelope

Code
use Illuminate\Mail\Mailables\Envelope; public function envelope(): Envelope { return new Envelope( subject: 'Welcome to Our Platform', tags: ['onboarding'], ); }

One tag per message. Tags can contain letters, numbers, hyphens, underscores, and spaces (max 255 characters). See Tags documentation for more details.

5. Metadata

Attach custom data for tracking and webhook payloads.

Using the metadata() Method

Code
Mail::to('customer@example.com') ->send( (new OrderConfirmation($order)) ->metadata('order_id', $order->id) ->metadata('customer_id', $order->customer_id) );

In Mailable Envelope

Code
use Illuminate\Mail\Mailables\Envelope; public function envelope(): Envelope { return new Envelope( subject: 'Order Confirmation', metadata: [ 'order_id' => $this->order->id, 'customer_id' => $this->order->customer_id, 'order_total' => $this->order->total, ], ); }

Metadata is included in webhook payloads but not sent to recipients.

6. Multiple Routes

Configure separate mailers for different email types (transactional, marketing, etc.):

Code
'mailers' => [ 'lettermint_transactional' => [ 'transport' => 'lettermint', 'route_id' => env('LETTERMINT_TRANSACTIONAL_ROUTE_ID'), ], 'lettermint_marketing' => [ 'transport' => 'lettermint', 'route_id' => env('LETTERMINT_MARKETING_ROUTE_ID'), ], ],
Code
LETTERMINT_TRANSACTIONAL_ROUTE_ID=your-transactional-route-id LETTERMINT_MARKETING_ROUTE_ID=your-marketing-route-id

Send to specific routes:

Code
// Transactional emails (password resets, order confirmations) Mail::mailer('lettermint_transactional') ->to($user) ->send(new PasswordResetEmail()); // Marketing emails (newsletters, promotions) Mail::mailer('lettermint_marketing') ->to($user) ->send(new NewsletterEmail());

7. Idempotency

Prevent duplicate emails when retrying failed requests.

Configuration

Code
'lettermint' => [ 'transport' => 'lettermint', 'idempotency' => true, // Enable automatic deduplication 'idempotency_window' => 86400, // Window in seconds (24 hours) ],

Custom Idempotency Key

Override the automatic key for specific emails:

Code
use Illuminate\Mail\Mailables\Headers; public function headers(): Headers { return new Headers( text: [ 'Idempotency-Key' => "welcome-{$this->user->id}", ], ); }

Keep idempotency_window at 86400 seconds to align with Lettermint's 24-hour idempotency key validity. Keys are scoped per project; retrying the same payload returns the cached 202 Accepted response, while reusing a key with a different payload returns 409 Conflict.

8. Webhooks

The driver automatically registers a webhook endpoint and dispatches Laravel events.

Configuration

Code
LETTERMINT_WEBHOOK_SECRET=your-webhook-signing-secret LETTERMINT_WEBHOOK_PREFIX=lettermint LETTERMINT_WEBHOOK_TOLERANCE=300

The webhook endpoint is available at POST /{prefix}/webhook (default: /lettermint/webhook).

Available Events

Event ClassTrigger
MessageCreatedEmail accepted for processing
MessageSentEmail sent to recipient server
MessageDeliveredEmail successfully delivered
MessageHardBouncedPermanent delivery failure
MessageSpamComplaintRecipient marked as spam

Listening to Events

Code
use Lettermint\Laravel\Events\MessageDelivered; use Lettermint\Laravel\Events\MessageHardBounced; protected $listen = [ MessageDelivered::class => [ \App\Listeners\HandleEmailDelivered::class, ], MessageHardBounced::class => [ \App\Listeners\HandleEmailBounced::class, ], ];
Code
namespace App\Listeners; use Lettermint\Laravel\Events\MessageDelivered; class HandleEmailDelivered { public function handle(MessageDelivered $event): void { logger('Email delivered', [ 'message_id' => $event->data->messageId, 'recipient' => $event->data->recipient, ]); } }

FAQ

Which Laravel and PHP versions are supported?

PHP 8.2 or newer and Laravel 10 or newer. The package is tested against the current Laravel majors and installs through Composer like any other package.

Do Mailables, notifications, and queued mail work as usual?

Yes. Lettermint registers as a standard mail transport, so everything you already build with the Mail facade, Mailables, notifications, and queues keeps working. Only the delivery happens through Lettermint.

How do I prevent duplicate emails?

Idempotency is enabled by default with a 24-hour window (idempotency_window). Retrying the same payload returns the cached result instead of sending again. Override the key per message with an Idempotency-Key header, as shown in the idempotency section above.

How do I track deliveries and bounces?

The driver dispatches Laravel events such as MessageDelivered and MessageHardBounced from Lettermint's webhooks, so you can react in your app. For opens and clicks, enable tracking on the route your mailer uses.

Is Lettermint email GDPR compliant and EU-hosted?

Yes. Lettermint runs exclusively on European infrastructure and processes email in line with GDPR, so transactional mail from your Laravel app is handled inside the EU.

Next Steps

Tags

Organize and filter emails with tags.

Tracking

Track opens, clicks, and deliverability.

Webhooks

Receive real-time delivery notifications.

SMTP Alternative

Send via SMTP instead of the API.

GitHub Repository

Find the complete source code, report issues, or contribute on GitHub.

Last modified on July 21, 2026
GoMagento 2
On this page
  • Requirements
  • 1. Installation
  • 2. Configuration
    • Environment Variables
    • Services Configuration
    • Mail Configuration
  • 3. Send Your First Email
    • Queued and Bulk Sending
  • 4. Tags
    • Using the tag() Method
    • In Mailable Envelope
  • 5. Metadata
    • Using the metadata() Method
    • In Mailable Envelope
  • 6. Multiple Routes
  • 7. Idempotency
    • Configuration
    • Custom Idempotency Key
  • 8. Webhooks
    • Configuration
    • Available Events
    • Listening to Events
  • FAQ
  • Next Steps
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP
PHP