Skip to main content

1. Installation

Install the package via Composer:
composer require lettermint/lettermint-laravel
Publish the configuration file:
php artisan vendor:publish --tag="lettermint-config"
Requires PHP 8.2+ and Laravel 9+.

2. Configuration

Environment Variables

Add your Lettermint credentials to .env:
.env
LETTERMINT_TOKEN=your-api-token
LETTERMINT_ROUTE_ID=your-route-id

Services Configuration

Add to config/services.php:
config/services.php
'lettermint' => [
    'token' => env('LETTERMINT_TOKEN'),
],

Mail Configuration

Add the Lettermint mailer to config/mail.php:
config/mail.php
'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:
.env
MAIL_MAILER=lettermint

3. Send Your First Email

Send emails using Laravel’s standard Mail facade:
use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;

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

4. Tags

Categorize emails for filtering and analytics in your Lettermint dashboard.

Using the tag() Method

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

In Mailable Envelope

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

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

In Mailable Envelope

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.):
config/mail.php
'mailers' => [
    'lettermint_transactional' => [
        'transport' => 'lettermint',
        'route_id' => env('LETTERMINT_TRANSACTIONAL_ROUTE_ID'),
    ],

    'lettermint_marketing' => [
        'transport' => 'lettermint',
        'route_id' => env('LETTERMINT_MARKETING_ROUTE_ID'),
    ],
],
.env
LETTERMINT_TRANSACTIONAL_ROUTE_ID=your-transactional-route-id
LETTERMINT_MARKETING_ROUTE_ID=your-marketing-route-id
Send to specific routes:
// 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

config/mail.php
'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:
use Illuminate\Mail\Mailables\Headers;

public function headers(): Headers
{
    return new Headers(
        text: [
            'Idempotency-Key' => "welcome-{$this->user->id}",
        ],
    );
}
Set idempotency_window to 86400 or higher for permanent deduplication within API retention.

8. Webhooks

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

Configuration

.env
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

app/Providers/EventServiceProvider.php
use Lettermint\Laravel\Events\MessageDelivered;
use Lettermint\Laravel\Events\MessageHardBounced;

protected $listen = [
    MessageDelivered::class => [
        \App\Listeners\HandleEmailDelivered::class,
    ],
    MessageHardBounced::class => [
        \App\Listeners\HandleEmailBounced::class,
    ],
];
app/Listeners/HandleEmailDelivered.php
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,
        ]);
    }
}

Next Steps

GitHub Repository

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