Looking to hire Laravel developers? Try LaraJobs
This package is not available.

laravel-mailpit-http maintained by manul-app

Description
Laravel mail transport that delivers messages to Mailpit through its HTTP API instead of SMTP.
Author
Last update
2026/09/08 22:45 (dev-main)
License
Downloads
6

Comments
comments powered by Disqus

Laravel Mailpit HTTP transport

Tests Latest version License

A Laravel mail transport that hands messages to Mailpit over POST /api/v1/send instead of SMTP.

Why

Mailpit is usually reached on port 1025. That works on a laptop, and stops working the moment Mailpit moves to a shared staging box behind Cloudflare or any other reverse proxy: the web UI is happily served over HTTPS with Basic Auth, while port 1025 is not exposed at all.

Mailpit also accepts messages over its HTTP API, on the very same port as the UI. This package points Laravel's mailer at that endpoint, so a staging application can keep sending mail through the same hostname it already uses to read it.

Requirements

  • PHP 8.3+
  • Laravel 12 or 13

Installation

composer require manul-app/laravel-mailpit-http --dev
MAIL_MAILER=mailpit
MAILPIT_URL=https://mailpit-stage.example.com
MAILPIT_USERNAME=user
MAILPIT_PASSWORD=secret

That is the whole setup. The package is auto-discovered, registers the mailpit mailer itself, and has nothing to publish — config/mail.php stays untouched.

Check it works

php artisan tinker
Mail::raw('Hello from the HTTP API', fn ($message) => $message->to('someone@example.com'));

The message shows up in the Mailpit UI right away. A misconfiguration throws instead of failing silently — a wrong password reports HTTP 401 … check MAILPIT_USERNAME / MAILPIT_PASSWORD, and a missing MAILPIT_URL says so in as many words.

Configuration

Variable Required Default Meaning
MAILPIT_URL yes Mailpit base URL, without /api/v1/send. A trailing slash is fine, and so is a sub-path such as https://stage.example.com/mailpit
MAILPIT_USERNAME no null Basic Auth user. No Authorization header is sent when this is empty
MAILPIT_PASSWORD no null Basic Auth password
MAILPIT_TIMEOUT no 10 Request timeout, in seconds

If you would rather spell the mailer out, a mailpit entry in config/mail.php takes precedence over the environment:

'mailpit' => [
    'transport' => 'mailpit',
    'endpoint' => env('MAILPIT_URL'),
    'username' => env('MAILPIT_USERNAME'),
    'password' => env('MAILPIT_PASSWORD'),
    'timeout' => (int) env('MAILPIT_TIMEOUT', 10),
],

The base URL lives under endpoint, not url: Laravel's MailManager reads a url key in a mailer config as a DSN and would replace the transport name with the URL scheme.

What gets sent

Sender, recipients, subject, both body parts, attachments and inline images are mapped onto the Mailpit send request. Two details are worth knowing:

  • Bcc is sent as bare addresses, because that is the only shape Mailpit's API accepts for that field. Display names on Bcc recipients are dropped; every other recipient field keeps its name.
  • Headers that Mailpit builds itself (From, To, Subject, Date, Content-Type, and friends) are stripped from the payload — Mailpit rejects the whole message if you try to set them. Your own X-* headers are passed through.

Scope

This is a one-way transport for local and staging environments. It does not read messages back out of Mailpit, and it is not meant for production: retries, queueing and failover are Laravel's job, not this package's.

Testing

composer test      # Pest
composer lint      # Pint
composer analyse   # PHPStan

License

MIT. See LICENSE.

Unofficial, and not affiliated with the Mailpit project.