How to check if email delivery was successful with Mailgun in Laravel 5?

I have set up Laravel 5 with Mailgun as my email service provider and I’m successfully sending emails using the built-in mail functionality.

\Mail::send('templates.alert', $info, function($msg) use ($info)
{
  $msg->to('[email protected]', 'John Smith')->subject('Your notification title');
});

The emails are working fine and recipients are getting them without any issues. However, I need to implement some kind of confirmation system to verify that Mailgun actually delivered the message successfully.

I want to capture the delivery status or response from Mailgun so I can log it in my database or take appropriate action if something goes wrong. What’s the best approach to get this delivery confirmation data from Mailgun when using Laravel’s mail system?

I ran into this exact scenario about six months ago when building a notification system for our app. The challenge with Laravel’s standard Mail facade is that it doesn’t return Mailgun’s response data directly since it’s designed to be provider-agnostic. What worked best for me was implementing Mailgun’s webhooks alongside the regular mail sending. After your mail is sent through Laravel, Mailgun will POST delivery events to a webhook endpoint you configure in your Mailgun dashboard. You can set up a route in Laravel to handle these webhooks and capture events like ‘delivered’, ‘failed’, or ‘bounced’. In my webhook controller, I validate the webhook signature using Mailgun’s timestamp and token, then parse the event data and update my database records accordingly. This approach gives you reliable delivery tracking without having to modify your existing mail sending code. Just make sure to include a unique identifier in your email headers so you can match webhook events back to your original mail records.

Another option that might be simpler depending on your needs is using Mailgun’s HTTP API directly instead of Laravel’s Mail facade for critical emails where you need immediate delivery confirmation. When you send via Mailgun’s API, you get an immediate response with a message ID and queue status. I’ve used this approach for transactional emails like password resets where I need to know right away if the send failed. You can use Guzzle to make the API call and then check the response status code - a 200 response means Mailgun accepted the message for delivery. The downside is you lose Laravel’s convenient mail templates and configuration, but for important notifications it gives you instant feedback. You could even create a hybrid approach where regular emails go through Laravel’s mail system while critical ones use the direct API method. Just remember that even a successful API response only means Mailgun accepted the message, not that it was actually delivered to the recipient’s inbox.