Search by

inspectornetwork / mailmanaged

InspectorNetwork

Laravel mail transport for MailManaged: send a website's administrative email to recipients verified on the platform.

v1.0.0 2026-09-19 16:23 UTC

This package is not auto-updated.

Last update: 2026-09-20 14:57:45 UTC


README

A Laravel mail transport for MailManaged. Your application sends the content of an administrative email (a contact-form submission, an alert, an order notice) and MailManaged delivers it to the people your website has verified on the platform.

Recipients live in MailManaged, not in your code. Whatever address a form submits or a bug injects, mail only ever goes to your verified recipients: the transport never sends the To, Cc or Bcc addresses, the sender, or any other header to the platform.

Requires PHP 8.2+ and Laravel 11, 12 or 13.

Install

composer require inspectornetwork/mailmanaged

Create a site token on your website's page in the MailManaged dashboard and add it to .env:

MAILMANAGED_TOKEN=your-site-token

The token is a server-side secret. Never expose it to browser JavaScript.

Send

The package registers a mailer named mailmanaged. Use it for administrative messages:

use Illuminate\Support\Facades\Mail;

Mail::mailer('mailmanaged')->raw('A new enquiry arrived.', function ($message) {
    $message->subject('New enquiry')->replyTo('visitor@example.com');
});

No to() is needed, and any you add is ignored. Mailables and notifications work the same way (->mailer('mailmanaged')). If everything your site sends is administrative, make it the default instead with MAIL_MAILER=mailmanaged.

What is sent: the subject, the text and/or HTML body, and one reply-to address. Attachments are not supported and are refused with an exception rather than dropped silently.

Recipient groups

Messages go to your website's default route unless you pick a group (for example contact, billing, alerts) that you created in the dashboard:

MAILMANAGED_GROUP=contact
$message->getHeaders()->addTextHeader('X-MailManaged-Group', 'billing'); // per message

An unknown or empty group is an error; it never falls back to everyone.

Retries and idempotency

Every request carries an idempotency key. Repeating the same key with the same content within 24 hours returns the original result without sending again or using more of your allowance. The transport generates a key per send, but a retried queued job builds a new message and so gets a new key. For anything you retry, set a stable key yourself:

$message->getHeaders()->addTextHeader('X-MailManaged-Idempotency-Key', 'contact-form-'.$submission->id);

Keys are 8 to 128 characters.

Errors

A message the platform does not accept throws InspectorNetwork\MailManaged\MailManagedException (a Symfony TransportException, so Laravel handles it like any failed send):

try {
    Mail::mailer('mailmanaged')->send(new ContactFormSubmitted($submission));
} catch (MailManagedException $e) {
    $e->status;         // HTTP status, or 0 if the platform could not be reached
    $e->retryAfter;     // seconds to wait, for rate and usage limits
    $e->isRetryable();  // true for 0, 429 and 5xx
}
StatusMeaningRetry?
0Platform unreachable or timed out. The message may have been accepted; retry with the same key.yes
401 / 403Invalid token, website not verified, or a security hold shown in your dashboardno
402No active subscription, or the website is pausedno
409Idempotency key reused with different contentno
422Invalid message, unknown group, or no deliverable recipientsno
429Rate or usage limit; wait retryAfter secondsyes
5xxPlatform erroryes

Configuration

.env is usually enough. To publish the config file:

php artisan vendor:publish --tag=mailmanaged-config
KeyEnvDefault
tokenMAILMANAGED_TOKENnone (required)
endpointMAILMANAGED_ENDPOINThttps://mailmanaged.com/api/v1/messages
groupMAILMANAGED_GROUPthe website's default route
timeoutMAILMANAGED_TIMEOUT15 seconds

The endpoint must be HTTPS (plain HTTP is accepted only for localhost and 127.0.0.1), and redirects are never followed, so the token cannot be forwarded to another host.

One application serving several websites can define extra mailers, each with its own token:

// config/mail.php
'mailers' => [
    'second-site' => ['transport' => 'mailmanaged', 'token' => env('SECOND_SITE_TOKEN'), 'group' => 'alerts'],
],

Development

composer install
composer test
composer lint

Tests use Orchestra Testbench and a mock HTTP client; nothing is sent. Bump MailManagedTransport::VERSION and CHANGELOG.md with each release, then tag it (v1.0.0).

License

MIT.