Laravel

camelmailer/camelmailer-laravel adds a native mail transport, so your existing Mailables and Notifications go through CamelMailer with a one-line config change. It also ships a facade for the full PHP SDK.

Install

terminal
composer require camelmailer/camelmailer-laravel

Requires PHP 8.1+ and Laravel 10, 11 or 12.

Configure the transport

Set the mailer in .env:

.env
MAIL_MAILER=camelmailer
CAMELMAILER_API_KEY=cm_xxxxxxxx

# Self-hosted? Point at your instance (defaults to the cloud):
# CAMELMAILER_BASE_URL=https://mail.example.com

…and register it in config/mail.php:

config/mail.php
'mailers' => [
    // ...
    'camelmailer' => [
        'transport' => 'camelmailer',
    ],
],

Send a Mailable

Nothing else changes. Your existing Mailables and Notifications now deliver through CamelMailer:

quickstart.php
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;

Mail::to('ada@example.com')->send(new OrderShipped($order));

Attachments, CC/BCC, reply-to and headers all map to the API. Two special headers reach CamelMailer features per message:

headers.php
$message->getHeaders()->addTextHeader('X-CamelMailer-Tag', 'order-shipped');
$message->getHeaders()->addTextHeader('X-CamelMailer-Stream', 'transactional');

Use the SDK via the facade

The facade exposes every messaging resource of the PHP SDK, including stored templates:

facade.php
use CamelMailer\Laravel\Facades\CamelMailer;

CamelMailer::emails()->sendWithTemplate([
    'from' => 'hello@acme.com',
    'to' => ['ada@example.com'],
    'template' => 'welcome',
    'template_model' => ['name' => 'Ada'],
]);

CamelMailer::stats()->get();
CamelMailer::dmarc()->summary();

Error handling

errors.php
use CamelMailer\Exceptions\ErrorException;

try {
    Mail::to('ada@example.com')->send(new OrderShipped($order));
} catch (ErrorException $e) {
    $e->code; // 'ValidationError', 'Unauthorized', 'NotFound', ...
}
Self-hosted? Just set CAMELMAILER_BASE_URL in .env. The underlying client is the PHP SDK.

GitHub repository · Packagist package