PHPackages                             letmesendemail/letmesendemail-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. letmesendemail/letmesendemail-laravel

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

letmesendemail/letmesendemail-laravel
=====================================

letmesend.email for Laravel.

v0.2.2(4w ago)0103MITPHPPHP ^8.1CI passing

Since Jul 9Pushed 4w agoCompare

[ Source](https://github.com/letmesendemail/letmesendemail-laravel)[ Packagist](https://packagist.org/packages/letmesendemail/letmesendemail-laravel)[ Docs](https://letmesend.email/)[ RSS](/packages/letmesendemail-letmesendemail-laravel/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (36)Versions (13)Used By (0)

letmesend.email SDK for Laravel
===============================

[](#letmesendemail-sdk-for-laravel)

[![Packagist Downloads](https://camo.githubusercontent.com/404b91bb512fcf2069801108f672dd30523b397d3f46f0149ceb3dc015675ad3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c65746d6573656e64656d61696c2f6c65746d6573656e64656d61696c2d6c61726176656c3f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d303030303030)](https://packagist.org/packages/letmesendemail/letmesendemail-laravel)[![Packagist Version](https://camo.githubusercontent.com/b232a9e5c78ef7227669485a040037d50edf7118df3ac58a18bf6018689f80ad/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c65746d6573656e64656d61696c2f6c65746d6573656e64656d61696c2d6c61726176656c3f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d303030303030)](https://packagist.org/packages/letmesendemail/letmesendemail-laravel)[![License](https://camo.githubusercontent.com/f3596956d3a9b0a3b73573723a4a45beecefa1d0ddf0316f5c54c772642db8f1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6c65746d6573656e64656d61696c2f6c65746d6573656e64656d61696c2d6c61726176656c3f636f6c6f723d396366267374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d3030303030302663616368653d7631)](LICENSE.md)

The official Laravel package for the [letmesend.email](https://letmesend.email/) API.

Full Documentation
------------------

[](#full-documentation)

See the comprehensive [user manual](docs/docs.md) for complete documentation of every resource, configuration option, mail transport, webhooks, error handling, and detailed examples.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, 12, or 13

Installation
------------

[](#installation)

```
composer require letmesendemail/letmesendemail-laravel
```

Configuration
-------------

[](#configuration)

Set your API key in `.env`:

```
LETMESENDEMAIL_API_KEY=lms_live_...
```

Optionally configure the base URL, timeout, and retries:

```
LETMESENDEMAIL_BASE_URL=https://letmesend.email/api/v1
LETMESENDEMAIL_TIMEOUT=30
LETMESENDEMAIL_RETRIES=3
```

Publish the config file (optional):

```
php artisan vendor:publish --tag=letmesendemail-config
```

### Environment Variables

[](#environment-variables)

VariableDefaultDescription`LETMESENDEMAIL_API_KEY`—Your letmesend.email API key`LETMESENDEMAIL_BASE_URL``https://letmesend.email/api/v1`API base URL`LETMESENDEMAIL_TIMEOUT``30`Request timeout in seconds`LETMESENDEMAIL_RETRIES``0`Retry attempts for transient failures`LETMESENDEMAIL_WEBHOOK_SECRET`—Webhook signing secret`LETMESENDEMAIL_WEBHOOKS_ENABLED``false`Enable webhook route`LETMESENDEMAIL_WEBHOOK_PATH``/webhooks/letmesendemail`Webhook URI path### Explicit Configuration

[](#explicit-configuration)

For tests and multi-tenant applications, configure the client explicitly:

```
use LetMeSendEmail\Laravel\LetMeSendEmail;

$client = new LetMeSendEmail(
    apiKey: 'lms_live_...',
    baseUrl: 'https://letmesend.email/api/v1',
    timeout: 60,
    retries: 5,
);
```

You may also inject a preconfigured core `Client` or a `TransportInterface` for testing:

```
use LetMeSendEmail\Client;
use LetMeSendEmail\Configuration;
use LetMeSendEmail\Http\GuzzleTransport;
use GuzzleHttp\Client as GuzzleClient;

$httpClient = new LetMeSendEmail(
    client: new Client(
        new Configuration(apiKey: '...', retries: 5),
        new GuzzleTransport(new GuzzleClient()),
    ),
);
```

Usage
-----

[](#usage)

### Facade

[](#facade)

```
use LetMeSendEmail\Laravel\Facades\LetMeSendEmail;
```

### Emails

[](#emails)

```
// Send
$email = LetMeSendEmail::emails()->send(
    from: 'Acme ',
    to: ['person@example.com'],
    subject: 'Welcome',
    html: 'Hello from letmesend.email',
);

echo $email->getId();

// Send with template
$email = LetMeSendEmail::emails()->sendWithTemplate(
    from: 'Acme ',
    to: ['person@example.com'],
    templateId: '01ARZ3NDEKTSV4RRFFQ69G5FAV',
    templateVariables: [
        ['key' => 'USER_NAME', 'type' => 'string', 'value' => 'John'],
    ],
);

// Verify email
$result = LetMeSendEmail::emails()->verify('person@example.com');
echo $result->getStatus();

// List emails (cursor-based pagination)
$list = LetMeSendEmail::emails()->list(perPage: 20);

foreach ($list->items() as $email) {
    echo $email->getId() . ' - ' . $email->getSubject();
}

echo $list->pagination()->hasMore(); // true

// Next page
$list = LetMeSendEmail::emails()->list(perPage: 20, after: 'cursor_from_previous_page');

// Get email
$email = LetMeSendEmail::emails()->get('01kvv5dv472evp42a60sy4p7zx');
```

### Domains

[](#domains)

```
$list = LetMeSendEmail::domains()->list();
$domain = LetMeSendEmail::domains()->get($id);
$result = LetMeSendEmail::domains()->verify('example.com');
```

### Contacts

[](#contacts)

```
$contact = LetMeSendEmail::contacts()->create(
    email: 'john@example.com',
    firstName: 'John',
    lastName: 'Doe',
);

$list = LetMeSendEmail::contacts()->list();
$contact = LetMeSendEmail::contacts()->get($id);
$updated = LetMeSendEmail::contacts()->update($id, firstName: 'Jane');
$result = LetMeSendEmail::contacts()->delete($id);
```

### Contact Categories

[](#contact-categories)

```
$category = LetMeSendEmail::contactCategories()->create(name: 'New Name');
$list = LetMeSendEmail::contactCategories()->list();
$category = LetMeSendEmail::contactCategories()->get($id);
$category = LetMeSendEmail::contactCategories()->update($id, name: 'Updated');
$result = LetMeSendEmail::contactCategories()->delete($id);
```

### Email Topics

[](#email-topics)

```
$topic = LetMeSendEmail::emailTopics()->create(
    name: 'Product Updates',
    slug: 'product-updates',
);

$list = LetMeSendEmail::emailTopics()->list();
$topic = LetMeSendEmail::emailTopics()->get($id);
$topic = LetMeSendEmail::emailTopics()->update($id, name: 'Updated');
$result = LetMeSendEmail::emailTopics()->delete($id);
```

Laravel Mail Transport
----------------------

[](#laravel-mail-transport)

Send emails through Laravel's mail system using the `letmesendemail` mailer.

### Configuration

[](#configuration-1)

Set your `.env` mailer:

```
MAIL_MAILER=letmesendemail
```

Or configure `config/mail.php`:

```
'mailers' => [
    'letmesendemail' => [
        'transport' => 'letmesendemail',
    ],
],
```

### Sending a Mailable

[](#sending-a-mailable)

```
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function build(): static
    {
        return $this
            ->from('noreply@acme.com')
            ->subject('Welcome!')
            ->html('Welcome');
    }
}
```

```
Mail::to('user@example.com')->send(new WelcomeEmail());
```

### Attachments

[](#attachments)

```
use Illuminate\Mail\Mailables\Attachment;

$this->attachFromStorage('/path/to/report.pdf');
// or
$this->attachData('file content', 'report.txt', ['mime' => 'text/plain']);
```

Structural MIME headers (From, To, Cc, Bcc, Reply-To, Subject, Content-Type, MIME-Version, Date, Message-ID, Sender, Return-Path) are automatically excluded from the API custom headers.

### Idempotency

[](#idempotency)

Set an `Idempotency-Key` header on the Mailable:

```
use Illuminate\Support\Facades\Mail;
use Symfony\Component\Mime\Email;

Mail::to('user@example.com')->send(
    (new WelcomeEmail())
        ->withSymfonyMessage(function (Email $message) {
            $message->getHeaders()->addTextHeader('Idempotency-Key', 'my-unique-key');
        }),
);
```

The SDK detects `Idempotency-Key` case-insensitively and passes it through the core API's `idempotencyKey` parameter.

### Queue

[](#queue)

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

The transport's `ApiException` mapping to `Symfony TransportException` works in queued jobs.

### Testing

[](#testing)

```
use Illuminate\Support\Facades\Mail;

Mail::fake();

Mail::assertSent(WelcomeEmail::class);
```

Pagination
----------

[](#pagination)

List endpoints return a response with cursor-based pagination:

```
$list = LetMeSendEmail::emails()->list(perPage: 10);

foreach ($list->items() as $email) {
    echo $email->getId();
}

$pag = $list->pagination();
$pag->hasMore();   // bool
$pag->getTotal();  // int
$pag->getPerPage(); // int

// Next page
$next = LetMeSendEmail::emails()->list(perPage: 10, after: 'cursor_value');

// Previous page
$prev = LetMeSendEmail::emails()->list(perPage: 10, before: 'cursor_value');
```

Error Handling
--------------

[](#error-handling)

```
use LetMeSendEmail\Exceptions\ValidationError;
use LetMeSendEmail\Exceptions\AuthenticationError;
use LetMeSendEmail\Exceptions\RateLimitError;
use LetMeSendEmail\Exceptions\ApiException;

try {
    LetMeSendEmail::emails()->send(/* ... */);
} catch (ValidationError $e) {
    // field-level errors: $e->getValidationErrors()
} catch (AuthenticationError $e) {
    // check API key
} catch (RateLimitError $e) {
    // retry after $e->getRetryAfter()
} catch (ApiException $e) {
    // HTTP status: $e->getHttpStatus()
    // API code: $e->getApiCode()
}
```

ExceptionHTTP StatusDescription`ValidationError`400, 413, 422Request validation failed`AuthenticationError`401Invalid or missing API key`AuthorizationError`403Insufficient permissions`NotFoundError`404Resource not found`ConflictError`409Resource conflict`RateLimitError`429Rate limit exceeded`ApiError`500+Server error`NetworkError`—Connection failed`TimeoutError`—Request timed outWebhooks
--------

[](#webhooks)

### Configuration

[](#configuration-2)

Enable webhooks in your `.env`:

```
LETMESENDEMAIL_WEBHOOKS_ENABLED=true
LETMESENDEMAIL_WEBHOOK_SECRET=whsec_your_signing_secret
```

The webhook route is registered at `/webhooks/letmesendemail` by default. It uses the `VerifyWebhookSignature` middleware (aliased as `letmesendemail.webhook`) which verifies the signature before the controller executes.

### How it works

[](#how-it-works)

1. The middleware reads the raw request body and webhook headers, calls `WebhookSignature::verify()`, and stores the parsed payload on the request.
2. If the signature is invalid, the middleware returns a 400 response.
3. The controller reads the verified payload from the request and dispatches `LetMeSendEmail\Laravel\Events\WebhookReceived`.

### Listening for webhooks

[](#listening-for-webhooks)

```
namespace App\Listeners;

use LetMeSendEmail\Laravel\Events\WebhookReceived;

class HandleLetMeSendEmailWebhook
{
    public function handle(WebhookReceived $event): void
    {
        match ($event->payload['event'] ?? '') {
            'email.delivered' => // handle delivery
            'email.bounced'   => // handle bounce
            default           => // unknown event
        };
    }
}
```

Register the listener in `EventServiceProvider`:

```
protected $listen = [
    \LetMeSendEmail\Laravel\Events\WebhookReceived::class => [
        \App\Listeners\HandleLetMeSendEmailWebhook::class,
    ],
];
```

### Timestamp tolerance

[](#timestamp-tolerance)

The default tolerance is 300 seconds (5 minutes). Configure via config:

```
// config/letmesendemail.php
'webhooks' => [
    'tolerance' => 300,
],
```

Testing
-------

[](#testing-1)

```
composer install
vendor/bin/pest
```

### Mail::fake with the letmesendemail transport

[](#mailfake-with-the-letmesendemail-transport)

```
use Illuminate\Support\Facades\Mail;

Mail::fake();

Mail::assertSent(WelcomeEmail::class);
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance94

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~11 days

Recently: every ~4 days

Total

12

Last Release

28d ago

PHP version history (3 changes)1.0.0PHP ^8.2

1.0.2PHP ^8.2|^8.3|^8.4|^8.5

v0.1.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/b12b084b3ba23d69fd03407818c2918d94f31aca4a3f5b5f9be524cf9944a182?d=identicon)[letmesendemail](/maintainers/letmesendemail)

---

Top Contributors

[![gurindersingh](https://avatars.githubusercontent.com/u/6223752?v=4)](https://github.com/gurindersingh "gurindersingh (14 commits)")

---

Tags

phpapiclientlaravelsdkmailletmesendletmesend-email

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/letmesendemail-letmesendemail-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/letmesendemail-letmesendemail-laravel/health.svg)](https://phpackages.com/packages/letmesendemail-letmesendemail-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[resend/resend-laravel

Resend for Laravel

1223.2M11](/packages/resend-resend-laravel)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[illuminate/mail

The Illuminate Mail package.

5910.7M563](/packages/illuminate-mail)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

818355.4k3](/packages/defstudio-telegraph)[forjedio/inertia-table

Backend-driven dynamic tables for Laravel + Inertia.js

272.0k](/packages/forjedio-inertia-table)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
