ronald2wing / laravel-mailtrap
Laravel mail transport for the Mailtrap Email Sending API
Fund package maintenance!
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7.0
- illuminate/mail: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.25
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.5|^11.5|^12.0
This package is auto-updated.
Last update: 2026-04-27 15:07:02 UTC
README
A Laravel mail transport for the Mailtrap Email Sending API. Use Laravel's native Mail facade to send emails through Mailtrap — with full support for attachments, categories, CC/BCC, custom headers, templates, and more.
Requirements
- PHP 8.3+
- Laravel 10.x, 11.x, 12.x, or 13.x
- GuzzleHTTP 7.0+
- PHP extensions: curl, json, mbstring
Installation
composer require ronald2wing/laravel-mailtrap
The service provider registers automatically via Laravel package discovery.
Configuration
Environment
MAILTRAP_TOKEN=your_api_token
config/services.php
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), // Optional overrides: // 'endpoint' => 'https://send.api.mailtrap.io', // 'inbox_id' => 42, // 'http' => ['timeout' => 30, 'connect_timeout' => 10], ],
config/mail.php
'default' => env('MAIL_MAILER', 'mailtrap'), 'mailers' => [ 'mailtrap' => [ 'transport' => 'mailtrap', ], ],
Usage
Send mail using Laravel's Mail facade — exactly as you would with any other driver.
use Illuminate\Support\Facades\Mail; Mail::to('user@example.com')->send(new WelcomeEmail());
Categories
Add an X-Mailtrap-Category header to segment email analytics in Mailtrap:
class WelcomeEmail extends Mailable { public function build() { return $this->view('emails.welcome') ->header('X-Mailtrap-Category', 'onboarding'); } }
Multiple categories are comma-separated:
$message->header('X-Mailtrap-Category', 'newsletter,marketing,weekly');
Templates
Send emails using Mailtrap templates via custom headers:
class WelcomeEmail extends Mailable { public function build() { return $this->view('emails.welcome') ->header('X-Mailtrap-Template-Uuid', 'abc-123-def') ->header('X-Mailtrap-Template-Variables', json_encode([ 'name' => 'John', 'company' => 'Acme', ])) ->header('X-Mailtrap-Custom-Variables', json_encode([ 'plan' => 'pro', ])); } }
Attachments
class InvoiceEmail extends Mailable { public function build() { return $this->view('emails.invoice') ->attach('/path/to/invoice.pdf', ['as' => 'invoice.pdf', 'mime' => 'application/pdf']) ->attach('/path/to/terms.pdf'); } }
Inline attachments (embedded images) are supported via ->embed():
$this->view('emails.newsletter') ->embed('/path/to/logo.png', 'logo', 'image/png');
CC, BCC, Reply-To
Mail::send('emails.announcement', $data, function ($message) { $message->to('team@example.com') ->cc(['manager@example.com', 'lead@example.com']) ->bcc('archive@example.com') ->replyTo('noreply@example.com', 'No Reply') ->subject('Announcement'); });
Multiple Reply-To addresses are joined with , per RFC 5322.
Custom Headers
Mail::send('emails.order', $data, function ($message) { $message->to('customer@example.com') ->header('X-Priority', '1') ->header('X-Order-ID', 'ORD-12345') ->subject('Order Confirmation'); });
HTML and Plain Text
class WelcomeEmail extends Mailable { public function build() { return $this->subject('Welcome') ->view('emails.welcome') // HTML ->text('emails.welcome-text'); // plain-text fallback } }
Advanced Configuration
Sandbox
For Mailtrap Email Testing inboxes, set the sandbox endpoint and inbox ID:
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), 'endpoint' => 'https://sandbox.api.mailtrap.io', 'inbox_id' => env('MAILTRAP_INBOX_ID'), ],
Or use the constant:
use Ronald2Wing\LaravelMailtrap\MailtrapConfig; 'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), 'endpoint' => MailtrapConfig::ENDPOINT_SANDBOX, 'inbox_id' => 42, ],
Bulk Sending
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), 'endpoint' => MailtrapConfig::ENDPOINT_BULK, ],
Custom API Endpoint
Override the default endpoint for proxy or custom environments:
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), 'endpoint' => 'https://custom.api.example.com', ],
HTTP Options
Any Guzzle request option can be set under the http key. Defaults are connect_timeout: 10 and timeout: 30.
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN'), 'http' => [ 'timeout' => 30, 'connect_timeout' => 10, 'verify' => false, // disable SSL verification (dev only) 'proxy' => 'http://proxy:8080', ], ],
Multiple Accounts
Define multiple Mailtrap configurations and reference them in your mailers:
// config/services.php 'mailtrap' => [ 'transactions' => [ 'token' => env('MAILTRAP_TOKEN_TRANSACTIONS'), ], 'marketing' => [ 'token' => env('MAILTRAP_TOKEN_MARKETING'), 'http' => ['timeout' => 60], ], ],
// config/mail.php 'mailers' => [ 'mailtrap_transactions' => [ 'transport' => 'mailtrap', 'config' => 'services.mailtrap.transactions', ], 'mailtrap_marketing' => [ 'transport' => 'mailtrap', 'config' => 'services.mailtrap.marketing', ], ],
Testing Your Application
Use Mail::fake() as usual — no transport swap needed during testing.
Mail::fake(); // ... exercise your application ... Mail::assertSent(WelcomeEmail::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasHeader('X-Mailtrap-Category', 'onboarding'); });
Troubleshooting
| Error | Solution |
|---|---|
Mailtrap API token cannot be empty |
Ensure MAILTRAP_TOKEN is set in .env and referenced in config/services.php. |
cURL error 60: SSL certificate problem |
Update CA certificates or set http.verify to a CA bundle path. |
Connection timed out |
Increase http.timeout and http.connect_timeout in the http config key. |
Mailtrap API returned HTTP 4xx/5xx |
Verify your API token and endpoint URL. |
For debugging, switch your mailer to log to inspect the raw payload in the Laravel log.
Contributing
git clone https://github.com/ronald2wing/laravel-mailtrap.git
cd laravel-mailtrap
composer install
Quality Checks
| Command | Purpose |
|---|---|
composer run test |
Run PHPUnit (includes Clover + HTML coverage → coverage/) |
composer run lint |
Check formatting with Pint (read-only) |
composer run format |
Apply formatting with Pint |
composer run analyse |
Run PHPStan (level 8) |
composer run check |
Run lint → analyse → test (read-only) |
Security
- Never commit API tokens to version control.
- Enable SSL verification in production (do not use
http.verify => false). - Validate file types and sizes before attaching user-supplied content.
License
MIT. See LICENSE for details.