Back to all articles
Laravel Insights Dec 30, 2025 โˆ™ 1 min read

Integrating Mailgun with Laravel for Reliable Email Delivery

Learn how to configure Mailgun with Laravel to send emails effortlessly, including advanced features like tracking and attachments.

An illustration showing the Laravel and Mailgun logos connected by an email icon, symbolizing a seamless integration for email delivery.

Integrating Mailgun with Laravel for Seamless Email Delivery

Learn how to configure Mailgun with Laravel to send emails effortlessly, including advanced features like tracking and attachments.

Reliable email delivery is a non-negotiable requirement for nearly every web application. From transactional messages like password resets and order confirmations to marketing campaigns, ensuring emails reach the inbox is critical for user engagement and business operations. Laravel's built-in mail capabilities provide an expressive API for sending emails, but pairing it with a robust delivery service like Mailgun elevates its power, guaranteeing deliverability and providing advanced analytics.

Mailgun is a leading email service provider (ESP) designed for developers. It offers a powerful API that simplifies sending, receiving, and tracking emails at scale. By offloading email delivery to Mailgun, you bypass the complexities and pitfalls of managing your own email server, such as IP reputation management and deliverability issues. Integrating Mailgun with Laravel is a straightforward process that unlocks a suite of professional email features.

This guide will provide a comprehensive, step-by-step walkthrough for integrating Mailgun into your Laravel projects. We will cover initial configuration, sending both single and bulk emails, and leveraging advanced features like attachments, webhooks for tracking, and effective error handling.

The Advantages of Using Mailgun with Laravel

While Laravel supports multiple mail drivers, Mailgun offers several distinct advantages that make it a preferred choice for production applications.

  • Superior Deliverability: Mailgun's infrastructure is optimized to ensure your emails avoid spam folders and reach the recipient's inbox. They handle SPF, DKIM, and DMARC records to build a strong sender reputation.
  • Scalability: Whether you're sending ten emails or ten million, Mailgun's platform is built to handle high volumes without compromising performance.
  • Advanced Analytics and Tracking: Gain deep insights into your email performance. Mailgun tracks opens, clicks, bounces, and unsubscribes, providing valuable data to refine your email strategy.
  • Developer-Friendly API: The API is well-documented and designed for ease of use, making it simple to integrate complex email functionality into your application.
  • Simplified SMTP and API Options: Laravel can integrate with Mailgun using either its SMTP credentials or the more efficient API driver, giving you flexibility in your implementation.

Setting Up Mailgun and Laravel: A Step-by-Step Guide

Integrating Mailgun is a quick process that involves configuring your Mailgun account and updating your Laravel application's environment variables.

Step 1: Configure Your Mailgun Account

Before touching any code, you need to get your Mailgun credentials.

  1. Create a Mailgun Account: If you don't have one, sign up at Mailgun's website. They offer a free tier that is perfect for development and testing.
  2. Add and Verify Your Domain: From the Mailgun dashboard, navigate to Sending > Domains and add the domain you intend to send emails from (e.g., mg.yourdomain.com). Mailgun will provide you with several DNS records (TXT, MX, CNAME) that you must add to your domain's DNS provider to verify ownership and authorize Mailgun to send on your behalf.
  3. Get Your API Key: Go to Settings > API Keys to find your Private API key. This key is secret and should be treated like a password.
  4. Note Your Domain and Region: You will need your Mailgun domain name (e.g., mg.yourdomain.com) and your region (US or EU) for the configuration.

For testing purposes, Mailgun provides a sandbox domain. However, sandbox domains can only send emails to authorized recipients that you add manually in the dashboard. For production, a verified custom domain is required.

Step 2: Configure Your Laravel Project

With your Mailgun credentials ready, it's time to configure your Laravel application.

  1. Install the Necessary Package: Laravel uses the Symfony Mailgun Mailer component to communicate with the Mailgun API. Install it via Composer:
  2. composer require symfony/mailgun-mailer symfony/http-client
  3. Update Your .env File: Open your project's .env file and update the mail-related variables. This is the most critical step.
  4. MAIL_MAILER=mailgun
    MAIL_HOST=smtp.mailgun.org
    MAIL_PORT=587
    MAIL_USERNAME=your-smtp-username-from-mailgun
    MAIL_PASSWORD=your-smtp-password-from-mailgun
    MAIL_ENCRYPTION=tls
    MAIL_FROM_ADDRESS="hello@yourdomain.com"
    MAIL_FROM_NAME="${APP_NAME}"
    
    MAILGUN_DOMAIN=your-mailgun-domain.com
    MAILGUN_SECRET=your-private-api-key
    MAILGUN_ENDPOINT=api.mailgun.net
    • Set MAIL_MAILER to mailgun.
    • Fill in MAILGUN_DOMAIN and MAILGUN_SECRET with the values from your Mailgun account.
    • The MAILGUN_ENDPOINT is api.mailgun.net for US accounts and api.eu.mailgun.net for EU accounts.
  5. Configure Services: Open config/services.php and ensure the mailgun configuration is present. Laravel includes this by default, but it is good practice to verify it.
  6. 'mailgun' => [
        'domain' => env('MAILGUN_DOMAIN'),
        'secret' => env('MAILGUN_SECRET'),
        'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
        'scheme' => 'https',
    ],

Your Laravel application is now configured to send all emails through Mailgun's API.

Sending Emails with Mailgun: Real-World Examples

Laravel's Mailable classes provide an elegant and structured way to define emails.

Example 1: Sending a Welcome Email

When a new user registers, sending a welcome email is a standard practice. First, create a Mailable class.

php artisan make:mail WelcomeEmail

This command creates a new file at app/Mail/WelcomeEmail.php. Let's configure it to accept a user and pass their name to a view.

// app/Mail/WelcomeEmail.php

namespace App\Mail;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(public User $user)
    {
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Welcome to Our Application!',
        );
    }

    public function content(): Content
    {
        return new Content(
            markdown: 'emails.welcome', // A Markdown email template
        );
    }
}

The associated Markdown template (resources/views/emails/welcome.blade.php) could look like this:

<x-mail::message>
# Welcome, {{ $user->name }}!

Thank you for joining our platform. We are excited to have you on board.

<x-mail::button :url="route('login')">
Get Started
</x-mail::button>

Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

Now, in your user registration logic (e.g., RegisteredUserController), you can dispatch this email. For better performance, always queue emails.

// app/Http/Controllers/Auth/RegisteredUserController.php

use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;

// Inside the store() method, after the user is created:
Mail::to($user)->queue(new WelcomeEmail($user));

By using queue(), you offload the email sending process to a background worker, ensuring a fast response time for the user.

Example 2: Sending Bulk Emails Efficiently

Sending a newsletter to thousands of users requires a more efficient approach than looping and sending individual emails. This is where Mailgun's batch sending feature shines. While Laravel does not have a native "batch" mail facade, you can leverage Mailgun's SDK directly for this.

A custom service class can handle this logic cleanly.

// app/Services/BulkMailService.php

namespace App\Services;

use Illuminate\Support\Collection;
use Mailgun\Mailgun;

class BulkMailService
{
    protected Mailgun $mailgun;

    public function __construct()
    {
        $this->mailgun = Mailgun::create(config('services.mailgun.secret'));
    }

    public function send(string $subject, string $body, Collection $recipients)
    {
        $domain = config('services.mailgun.domain');

        // Mailgun's batch sending can handle up to 1,000 recipients per API call.
        $recipients->chunk(1000)->each(function ($chunk) use ($domain, $subject, $body) {
            $message = $this->mailgun->messages()->create($domain, [
                'from'    => config('mail.from.address'),
                'to'      => $chunk->pluck('email')->implode(','),
                'subject' => $subject,
                'html'    => $body,
            ]);
        });
    }
}

You can then invoke this service from an Artisan command or a queued job to send your newsletter.

Advanced Features and Best Practices

Handling Attachments

Adding attachments with Laravel is incredibly simple. In your Mailable class, use the attachments() method.

use Illuminate\Mail\Mailables\Attachment;

public function attachments(): array
{
    return [
        Attachment::fromPath('/path/to/invoice.pdf')
            ->as('invoice.pdf')
            ->withMime('application/pdf'),
    ];
}

Tracking Email Events with Webhooks

Mailgun can send HTTP POST requests to your application when email events occur (opens, clicks, bounces). This is configured via Webhooks in the Mailgun dashboard.

  1. Create a dedicated route and controller in Laravel to receive these webhooks.
  2. In your Mailgun dashboard, navigate to Sending > Webhooks and add a new webhook, pointing it to your route.
  3. Always verify the webhook signature to ensure the request is genuinely from Mailgun.

This allows you to update your database in real-time, for example, by marking a user's email as "bounced."

Error Handling and Monitoring

Even with a reliable service like Mailgun, failures can happen.

  • Log Errors: Laravel automatically logs failed mail jobs. Regularly monitor your laravel.log file.
  • Use Queues with Retries: Configure your queue workers to retry failed email jobs. This can resolve temporary network issues.
  • Monitor Mailgun Logs: The Mailgun dashboard provides detailed logs of all sending activity, including failure reasons. Use this as your first point of reference for debugging delivery issues.

Conclusion

Integrating Mailgun with Laravel is an efficient and scalable solution for managing email delivery. It combines Laravel’s expressive syntax for building emails with Mailgun’s robust infrastructure, ensuring your messages are delivered reliably. By following the steps outlined in this guide, you can quickly set up the integration, send various types of emails, and leverage advanced features to create a professional email system. This proven combination allows you to focus on building great application features, confident that your email communication is in expert hands.


Related articles

Continue exploring Laravel insights and practical delivery strategies.

Laravel consulting

Need senior Laravel help for this topic?

Let's adapt these practices to your product and deliver the next milestone.