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.

After every successful email send, Laravel Maily dispatches a MailySentEvent. Register a listener to act on the Maily API response — log delivery IDs, track quota, feed analytics pipelines, or notify administrators. Because the event is fired only after the API returns a successful response, you can rely on it as a confirmation that Maily has accepted the message for delivery.

Event properties

MailySentEvent exposes four readonly constructor properties populated directly from the Maily API response:
id
string
required
The unique delivery ID returned by the Maily API. Store this value if you need to correlate log entries or database records with a specific send.
status
string
required
The delivery status returned by the API at the time of acceptance — for example, queued. This reflects the initial state; the message may transition through further states on the Maily side after this point.
message
string
required
A human-readable message from the Maily API response, such as "Email queued for delivery". Useful for logging and debugging.
data
array
The full raw JSON response body returned by the Maily API, decoded as a PHP array. This includes id, status, and message as well as any additional fields the API may return in the future.

Registering a listener

Register your listener against MailySentEvent in App\Providers\EventServiceProvider (Laravel 10 and earlier) or in the withEvents call inside bootstrap/app.php (Laravel 11+):
use Yugo\Maily\Events\MailySentEvent;
use App\Listeners\GetMailyResponse;

// In EventServiceProvider
protected $listen = [
    MailySentEvent::class => [
        GetMailyResponse::class,
    ],
];
Laravel’s event discovery will also pick up listeners automatically if you follow the standard naming conventions and have discovery enabled.

Example listener

The listener below logs the full Maily response at the debug level every time an email is accepted:
<?php

namespace App\Listeners;

use Illuminate\Support\Facades\Log;
use Yugo\Maily\Events\MailySentEvent;

class GetMailyResponse
{
    public function __construct() {}

    public function handle(MailySentEvent $event): void
    {
        Log::debug('Maily response', [
            'id'      => $event->id,
            'status'  => $event->status,
            'message' => $event->message,
            'data'    => $event->data,
        ]);
    }
}
Adapt the handle method to suit your application’s needs — the four event properties give you everything returned by the API.

Common use cases

Persist the $event->data payload (or just the id and status fields) to a database table or cache counter. Because the event fires once per accepted message, incrementing a counter in the listener gives you an accurate running total of sends without polling the Maily API.
public function handle(MailySentEvent $event): void
{
    Cache::increment('maily:sent_count');
}
In local or staging environments, dump the full data array to your log for inspection. This is the fastest way to verify that the API is receiving the fields you expect.
public function handle(MailySentEvent $event): void
{
    if (app()->isLocal()) {
        logger()->debug('Maily raw response', $event->data);
    }
}
Store the delivery id and status in your database alongside the relevant record (for example, an Order or User). You can then surface this information in an admin panel to confirm that transactional emails were dispatched correctly.
public function handle(MailySentEvent $event): void
{
    MailLog::create([
        'maily_id' => $event->id,
        'status'   => $event->status,
        'sent_at'  => now(),
    ]);
}
If your listener implements ShouldQueue, Laravel will process it asynchronously on your queue — meaning the MailySentEvent listener work (logging, database writes, analytics calls) does not add latency to the mail send itself. The transport fires the event and returns immediately; your queue worker handles the rest in the background.

Build docs developers (and LLMs) love