7/7/2025
Brevo SMTP in Laravel — free transactional email up to 300 emails/day
TL;DR: Brevo (formerly Sendinblue) has a Free plan with 300 emails per day and SMTP. In Laravel: MAIL_MAILER=smtp, 5 .env variables, done. Zero mail server configuration.
Transactional email — order confirmations, password resets, notifications — is one of those things that seem simple but end up in the spam folder with naive implementation. Running your own SMTP on a VPS or dedicated server is a trap for small projects. Brevo solves the problem for free.
Why Brevo instead of your own SMTP
Setting up your own mail server sounds simple — Postfix, a few lines of config, done. In practice: ISP hosting and many VPS providers block port 25 (default SMTP) at the network level. Even if the port is open, your IP is new and has no reputation — the first emails end up in spam.
Building IP reputation takes weeks of gradual “warming up” — you send small volumes, monitor bounce rates, configure SPF, DKIM, and DMARC correctly (which itself is hours of work and DNS knowledge). Brevo has dedicated IPs with established reputation and ready SPF/DKIM configuration for your domain after DNS verification.
Laravel .env configuration
After creating an account at Brevo (brevo.com), go to SMTP & API → Generate SMTP credentials. You get a login (your email) and an API key that serves as your SMTP password.
MAIL_MAILER=smtp
MAIL_HOST=smtp-relay.brevo.com
MAIL_PORT=587
MAIL_USERNAME=your@email.com
MAIL_PASSWORD=xsmtpsib-your-api-key-from-brevo
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"
One important detail: MAIL_FROM_ADDRESS must be a domain you’ve verified in Brevo (Senders tab). Brevo requires sender domain verification — you get a DNS record to add, and after adding it, verification takes a few minutes.
Mailables in Laravel
Create a Mailable:
php artisan make:mail OrderConfirmation
// app/Mail/OrderConfirmation.php
class OrderConfirmation extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Order $order) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Order Confirmation #' . $this->order->id,
);
}
public function content(): Content
{
return new Content(
view: 'mail.order-confirmation',
);
}
}
Blade template in resources/views/mail/order-confirmation.blade.php:
<x-mail::message>
# Order Confirmation
Thank you for your order #{{ $order->id }}.
<x-mail::table>
| Product | Qty | Price |
| :------ | :---: | ---: |
@foreach ($order->items as $item)
| {{ $item->name }} | {{ $item->qty }} | {{ $item->price }} |
@endforeach
</x-mail::table>
Best regards,<br>
{{ config('app.name') }}
</x-mail::message>
Sending synchronously or via queue:
// Synchronously
Mail::to($user->email)->send(new OrderConfirmation($order));
// Via queue (recommended in production)
Mail::to($user->email)->queue(new OrderConfirmation($order));
Queue requires a running php artisan queue:work or Horizon.
Testing
Quick test via Tinker:
php artisan tinker
Mail::raw('Test from Brevo SMTP', function($m) {
$m->to('test@example.com')->subject('Test Brevo');
});
After sending, check the Brevo panel: Transactional → Logs. You’ll see delivery status, timestamps, and any errors. This is a killer feature compared to running your own SMTP — full visibility into what happens with each email.
Limits and scaling
Free plan: 300 emails/day, no monthly limit. For a bootstrapped project or MVP this is more than enough — 300 emails per day is 9,000 per month.
Comparison of paid plans (approximate 2025 pricing):
- Brevo Starter: ~$25/month = 20,000 emails/day
- Mailgun: ~$15/month = 10,000 emails/month (not per day — a total pool)
- Postmark: ~$15/month = 10,000 emails/month
Brevo offers the best price-to-volume ratio at low and medium volumes. Postmark has a better deliverability reputation for transactional email at high volumes, but is more expensive.
Summary
Brevo SMTP with Laravel is a 15-minute setup: account, sender domain verification, 5 lines in .env. Free 300 emails/day is sufficient for an early-stage project. Full logs in the Brevo panel save time when debugging deliverability issues — much more pleasant than hunting through Postfix logs.