darvis / mailtrap
Mailtrap for Laravel: validates recipients before sending, logs every outgoing mail, processes signed Mailtrap webhook events and ships an inbox UI.
Requires
- php: ^8.2
- laravel/framework: ^11.0|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- livewire/flux: ^2.11
- livewire/livewire: ^3.7.4|^4.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- phpunit/phpunit: ^11.0|^12.0|^13.0
Suggests
- livewire/flux: Required for the inbox UI (^2.11, the free edition is enough).
- livewire/livewire: Required for the inbox UI (^3.7.4 or ^4.0).
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-24 06:54:43 UTC
README
A Laravel package that checks every recipient before a mail goes out, logs every outgoing mail, processes signed Mailtrap webhook events (delivery, bounce, spam, reject) and adds an inbox page to inspect it all. Validation and logging work with any Laravel mailer; only the webhook needs Mailtrap.
Unofficial. This is an independent open-source package, not an official Mailtrap product. It is not made, supported or endorsed by Mailtrap.
Features
- Recipient check before sending: format and MX lookup for every To, Cc and Bcc address; a blocked address aborts the send with a
TransportException - Blocking per address:
EmailValidation::markAsBlocked()stops mail to one address, never to its whole domain - Mail log: one
mail_logsrow per recipient, optionally linked to a model throughX-Mail-*headers, with query scopes and pruning - Signed webhook:
POST /api/webhooks/mailtrapchecks theMailtrap-Signatureheader (HMAC-SHA256) and updates logs and address verdicts - Events:
MailBlockedandMailtrapEventReceivedfor your own listeners - Inbox page: a Livewire/Flux page to search, inspect and clean up the mail log, closed by a
viewMailtrapgate - Commands:
mailtrap:install(setup wizard),mailtrap:webhook(creates the webhook and stores its secret),mailtrap:test(health check with exit code)
Requirements
- PHP 8.2 or higher
- Laravel 11, 12 or 13
- Only for the inbox page:
livewire/livewire^3.7.4 or ^4.0 andlivewire/flux^2.11 (the free edition is enough)
Installation
composer require darvis/mailtrap php artisan mailtrap:install
The wizard runs the migrations and walks you through the Mailtrap tokens, the mailer, the webhook, validation and the inbox page. It writes every answer to .env, so run it on every server. See Installation for the manual steps and Environment variables for every .env variable and what it is for.
The .env variables you will use most
The wizard writes these for you. To set them by hand:
# Webhook: Mailtrap reports delivered, opened, bounced and spam per mail MAILTRAP_WEBHOOK_ENABLED=true MAILTRAP_WEBHOOK_SECRET=<signing secret of the webhook> MAILTRAP_API_TOKEN=<account API token with Admin access>
MAILTRAP_WEBHOOK_SECRETis not a token you create: Mailtrap generates it for the webhook.php artisan mailtrap:webhook(or the wizard) creates the webhook and writes the secret for you. Made the webhook yourself in the Mailtrap dashboard? Open it under Settings → Webhooks and copy the signing secret from its detail panel. Without a secret the endpoint answers403to every call.MAILTRAP_API_TOKENis an account token: Mailtrap → Settings → API Tokens → Add Token, with Admin access. It is only used to create the webhook. It is not the SMTP password: that is the token of your sending domain (Sending Domains → your domain → Integration → SMTP) and goes inMAIL_PASSWORD.
For more insight into what your site sends, open the inbox page at /mailtrap. It lists every outgoing mail with its status, bounces and errors:
MAILTRAP_UI_ENABLED=true MAILTRAP_UI_MIDDLEWARE=web,auth MAILTRAP_UI_LAYOUT=layouts.app
MAILTRAP_UI_ENABLEDregisters the page (on by default).MAILTRAP_UI_MIDDLEWAREruns before theviewMailtrapgate below; withautha guest is sent to your login page.MAILTRAP_UI_LAYOUTis the Blade layout the page renders in, in dot notation:layouts.appisresources/views/layouts/app.blade.php. The default iscomponents.layouts.app.
Who can open the inbox page
Outside the local environment the inbox at /mailtrap answers 403 until your application defines the viewMailtrap gate, the way Laravel Horizon does it. Add this to AppServiceProvider::boot() and adapt the condition to your users:
use App\Models\User; use Illuminate\Support\Facades\Gate; Gate::define('viewMailtrap', fn (?User $user) => $user?->is_admin === true);
MAILTRAP_UI_ENABLED=false switches the page off.
Quick start
After installation every outgoing mail is validated and logged; you do not call the package to send mail.
// routes/web.php use Darvis\Mailtrap\Models\EmailValidation; use Darvis\Mailtrap\Models\MailLog; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Route; use Symfony\Component\Mailer\Exception\TransportException; Route::get('/mail-demo', function () { // Stop all mail to one address (never to the whole domain). EmailValidation::markAsBlocked('complainer@example.com', 'Spam complaint'); try { Mail::raw('Hello', fn ($message) => $message->to('complainer@example.com')->subject('Demo')); } catch (TransportException $e) { // "Email address complainer@example.com is blocked: Spam complaint" } return ['blocked_logs' => MailLog::toRecipient('complainer@example.com')->blocked()->count()]; // 1 });
Check the setup at any time with a real address of your own:
php artisan mailtrap:test you@yourdomain.com
Documentation
Full documentation: https://arviddejong.github.io/mailtrap/
- Installation: the steps and how to check that it works
- Environment variables: every
.envvariable, the two Mailtrap tokens and the webhook secret - Quick start: a complete mailable that is logged and linked to a model
- Sending, blocking and mail logs: what happens on every send, the verdicts, scopes and events
- Email validation: every method of the
EmailValidationmodel - Webhook: signature checking, status codes and
mailtrap:webhook - Inbox page and health check: who can open the inbox, and
mailtrap:test - Testing: tests without DNS lookups or a mail server
- Troubleshooting: error messages with cause and fix
- FAQ
Laravel Boost
The package ships Laravel Boost resources: a guideline and a mailtrap-development skill. Run php artisan boost:install, or php artisan boost:update --discover in a project that already uses Boost.
Testing
composer test # Pest composer lint # Pint, check only composer format # Pint, fixes composer analyse # Larastan
Changelog
See CHANGELOG.md.
Support the package
If darvis/mailtrap saves you time, a star on GitHub or a favourite on Packagist helps other developers find it.
Contributing
See CONTRIBUTING.md.
Security
Please report a security problem privately, see SECURITY.md.
License
MIT, see LICENSE.