laravel maintained by mailtarn
mailtarn/laravel
Mailtarn for Laravel 12 (PHP 8.2+).
- A
mailtarnmail driver: your app's mail goes into a Mailtarn inbox over HTTP instead of SMTP. Mailtarn never delivers anything; messages land in the inbox and stay there. - Test helpers: wait for the email your test just triggered, then use its links and codes.
composer require mailtarn/laravel --dev # or without --dev to send through it on staging
Create an API token in Mailtarn (Developer → API tokens) and add to .env:
MAILTARN_TOKEN=mtk_… # messages:send to send; messages:read for tests
MAILTARN_INBOX=<inbox id>
# MAILTARN_URL=https://app.mailtarn.com
Send through Mailtarn
In config/mail.php, add a mailer:
'mailers' => [
// …
'mailtarn' => ['transport' => 'mailtarn'],
],
and set MAIL_MAILER=mailtarn in the environment that should be captured (staging, CI). Every
Mail::to(...)->send(...) then lands in the inbox, with To, Cc, BCC (kept in the envelope),
custom headers and attachments.
Prefer SMTP? That works too: use the inbox's SMTP settings from Mailtarn and keep
MAIL_MAILER=smtp. The test helpers below work either way.
Wait for an email in a test
use Mailtarn\Laravel\Facades\Mailtarn;
$since = now();
$this->post('/register', ['email' => 'priya@example.com', /* … */]);
$email = Mailtarn::waitFor(['to' => 'priya@example.com', 'since' => $since]);
$this->assertSame('Verify your email', $email['subject']);
$this->get($email['links'][0]['url']); // or use $email['codes'][0]
waitFor returns the first matching message received after since (without since, the newest
match or the next to arrive). Filters: to, from, subject, q, hasAttachments. It waits up
to MAILTARN_WAIT_TIMEOUT seconds (default 30) and throws MailtarnException with
errorCode wait_timeout if nothing arrives.
Also: Mailtarn::messages(), message($id), raw($id), delete($id), clear() (empty the
inbox before a test; needs messages:delete), inboxes(), send([...]).
Licence
MIT. Copyright (c) 2026 Mailtarn (mailtarn.com).