Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/yugo412/laravel-maily/llms.txt

Use this file to discover all available pages before exploring further.

Once Laravel Maily is configured and MAIL_MAILER=maily is set in your .env, all outgoing mail is automatically routed through the Maily transport. You do not need to change any existing Mailable classes or Mail facade calls — the transport is a drop-in replacement that works transparently beneath Laravel’s standard mail layer.

Raw email

Send a quick plain-text message without creating a Mailable class by passing a string directly to Mail::raw():
use Illuminate\Support\Facades\Mail;

Mail::raw('Hello from Maily!', function ($message) {
    $message
        ->to('user@example.com')
        ->subject('Test Email');
});
This is useful for one-off notifications, smoke tests, or debugging without the overhead of a full Mailable.

Mailable classes

Send any existing Mailable exactly as you would with any other Laravel mail driver:
Mail::to($user)->send(new WelcomeMail());
No modifications to the Mailable class are required. The transport intercepts the compiled message after Laravel renders it and forwards it to the Maily API.

Queued mail

Defer delivery to a background queue job using queue() instead of send():
Mail::to($user)->queue(new WelcomeMail());
Laravel handles serialization and pushes a job onto your configured queue. The Maily transport is invoked only when the queue worker picks up and processes the job, keeping your HTTP request cycle fast. All standard Laravel queue configuration — connections, delays, and priorities — applies normally.

From address formatting

The transport automatically formats sender addresses before sending them to the Maily API. When a display name is present, the address is rendered as Name <email@example.com>; when no name is set, only the bare email address is used. This is handled internally by the formatAddress method in MailyTransport:
private function formatAddress(?Address $address): ?string
{
    if (empty($address)) {
        return null;
    }
    if ($address->getName()) {
        return sprintf('%s <%s>', $address->getName(), $address->getAddress());
    }
    return $address->getAddress();
}
For example, a from address configured as Address('hello@example.com', 'Your App') will be sent to the API as Your App <hello@example.com>.

What the transport sends

On every send, the transport makes a POST /api/v1/emails/send request to the Maily API with the following JSON body:
FieldTypeDescription
fromstring | nullFormatted sender address (e.g., Your App <hello@example.com>).
tostring | nullFormatted recipient address (e.g., User <user@example.com>).
subjectstring | nullThe email subject line.
htmlstring | nullHTML body of the message, if one is set.
textstring | nullPlain-text body of the message, if one is set.
The request is authenticated via an X-API-Key header populated from services.maily.key.
Only a single recipient is supported per send. Passing more than one address to ->to() will throw a MailyException before the API is contacted. To send the same message to multiple recipients, loop over them and call Mail::to($recipient)->send(...) individually.

Build docs developers (and LLMs) love