mailchannels/mailchannels-php package includes a Laravel service provider that registers mailchannels as a
Mail driver.
Laravel’s Mail facade is built on Symfony Mailer under the hood,
and uses the exact same transport as the Symfony integration.
This plugin is optional and lives alongside the rest of the PHP SDK. The plugin itself can only send mail. It
doesn’t implement the full API surface (sub-accounts, keys, webhooks, etc.). For those features, use the SDK’s
Client directly.Prerequisites
Before you send your first message, follow the PHP quickstart prerequisite section. This will walk you through creating an account, generating an API key, and adding the required Domain Lockdown and SPF DNS records.Installation
Configuring Laravel
1
Add a mailchannels mailer
Add a
mailchannels mailer in config/mail.php:config/mail.php
2
Add your API key
Add it to
config/services.php:config/services.php
3
Point Laravel at the new mailer
Set in your environment or
.env file:.env
Sending mail
Once configured, send mail through the standardMail facade. No MailChannels-specific code is required:
Email supports (multiple recipients, reply-to, attachments and so on).
Anything built with a Laravel Mailable (from,
to/cc/bcc, subject, text/html bodies, attachments) can be sent through this transport.
Only one personalization is ever built per message. If you need to send multiple individualized emails in one request,
call the SDK’s
Client directly instead of going through Mail. See
How emails are structured for more information on personalizations.Control headers
A LaravelMailable has no equivalent for some MailChannels-specific features. Reach those instead through custom
headers prefixed with x-mailchannels-. The x-mailchannels-* headers are stripped before the message is sent, so
recipients never see them.
Set these (and any other custom headers) from a Mailable’s headers()
method:
If the same custom header is added twice, only the last value is used.
"true" / "false"; anything else throws
Symfony\Component\Mailer\Exception\TransportException. An empty value is treated as unset (falls back to the default).
Each of these corresponds directly to a field on the send endpoint. See that
reference for full semantics.
Laravel’s own mail queueing (
ShouldQueue mailables, Mail::queue()) is unrelated to the x-mailchannels-send-async
control header:The former controls when your application hands the message to the transport;
the latter controls whether MailChannels processes it synchronously or asynchronously once it arrives.You can use them independently or together.Error handling
Any SDK exception raised while sending (authentication, validation, rate limiting, server errors) is caught and re-thrown asSymfony\Component\Mailer\Exception\TransportException.
Access the original exception via $e->getPrevious() to inspect it:
Limitations
- One personalization per message. No per-recipient template data or per-recipient header overrides through this transport.
- No Mustache templating. This transport has no way to use mailchannels’ mustache template rendering. If you need
to do so, use Laravel’s Blade Template Support, or use the SDK’s
Clientdirectly; see Templates for how. - DKIM only via the MailChannels API, as described above.
Next steps
- Read the webhooks guide to learn how to get real-time notifications about email delivery, bounces, and complaints.
- Explore the API reference to see what else you can do with the API.

