LettermintLettermint
  • Knowledge base
  • Community
  • Changelog
  • Support
  • Documentation
  • Sending API
  • Team API
  • MCP server
Get started
Send email
    Send with
      SDKs
      Frameworks
        LaravelSymfonyNuxtMagento 2WordPress
    SMTP
    Email activitySchedulingTest emailsTLSIdempotencySuppressionsTagsInline imagesData retentionSending limits
    Tracking
Receive email
Manage
Resources
Frameworks

Laravel

Use the official Lettermint Laravel package with Mailables, notifications, queued mail, tags, metadata, and idempotency. The package uses the PHP SDK. See Integrations for other packages.

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'], ); }

This SDK example uses the existing singular tag. It has no deprecation date. Use the raw HTTP API to send structured tags until this SDK has a multi-tag method. See Tags documentation.

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 delivery events through webhooks.

SMTP Alternative

Send via SMTP instead of the API.

GitHub Repository

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

RustSymfony
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