Send email from Laravel with emailr_
Send transactional email from Laravel with the emailr_ HTTP API: render Mailables, queue sends with jobs and verify signed delivery webhooks.
Laravel's HTTP client is all you need to talk to emailr_. This guide wraps the API in a small service, reuses your existing Mailable views for the HTML, sends from queued jobs and verifies webhooks.
There's no PHP SDK yet, so every example calls the REST API at https://api.emailr.dev directly.
Set up emailr_ with Laravel
- 01
Create an API key
Create a key under API keys in the dashboard. Keys start with
et_live_and are scoped to one domain workspace. Store it asEMAILR_API_KEYin your secret manager or environment, never in client-side code. - 02
Add and verify your sending domain
In the dashboard, open Domains and add the domain you send from. A subdomain such as
mail.yourcompany.comkeeps transactional reputation separate from your corporate mailbox.Emailr generates the DNS records: a DKIM TXT record on the
emailr._domainkeyselector, an SPF TXT record, and an MX + TXT pair on thesendsubdomain used as the MAIL FROM / Return-Path. A DMARC record is optional but recommended.Emailr's DKIM selector and
sendsubdomain don't collide with other providers' records, so you can add them before cutting over and send from both providers during the migration. A domain can only have one SPF record: if one already exists, merge Emailr'sinclude:into it instead of adding a second record. - 03
Add the key to your config
Add
EMAILR_API_KEYandEMAILR_WEBHOOK_SECRETto.env, then expose them throughconfig/services.phpso they're cached with the rest of your config.config/services.phpphp'emailr' => [ 'key' => env('EMAILR_API_KEY'), 'webhook_secret' => env('EMAILR_WEBHOOK_SECRET'), ], - 04
Create a small client
POST /v1/emails/sendtakes JSON withfrom,to,subject,htmland/ortext, plus optionalcc,bcc,reply_to_email,tags,attachments,template_id,template_dataandscheduled_at.->throw()turns 4xx/5xx responses into exceptions so failed jobs retry.app/Services/Emailr.phpphp<?php namespace App\Services; use Illuminate\Support\Facades\Http; class Emailr { public function send(array $payload): array { return Http::withToken(config('services.emailr.key')) ->acceptJson() ->post('https://api.emailr.dev/v1/emails/send', $payload) ->throw() ->json(); } } - 05
Send a Mailable's HTML from a queued job
Keep writing Blade Mailables and call
render()to get the HTML string. Sending from a queued job keeps web requests fast and gives you retries for free.app/Jobs/SendWelcomeEmail.phpphp<?php namespace App\Jobs; use App\Mail\WelcomeMail; use App\Models\User; use App\Services\Emailr; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class SendWelcomeEmail implements ShouldQueue { use Queueable; public function __construct(public User $user) {} public function handle(Emailr $emailr): void { $emailr->send([ 'from' => 'Acme <hello@mail.acme.com>', 'to' => $this->user->email, 'subject' => 'Welcome to Acme', 'html' => (new WelcomeMail($this->user))->render(), 'tags' => ['category' => 'welcome'], ]); } } // SendWelcomeEmail::dispatch($user); - 06
Verify delivery webhooks
Register the route in
routes/api.phpso it skips CSRF protection. Compute the HMAC over the raw body fromgetContent()and compare withhash_equals.routes/api.phpphpuse Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/webhooks/emailr', function (Request $request) { $expected = hash_hmac('sha256', $request->getContent(), config('services.emailr.webhook_secret')); abort_unless(hash_equals($expected, (string) $request->header('X-Emailr-Signature')), 401); $event = $request->input('event'); // e.g. "email.bounced" $data = $request->input('data'); return response()->noContent(); });
Tips
- On Laravel 11 and later, run
php artisan install:apionce if your app doesn't haveroutes/api.phpyet. - Attachments are JSON objects:
['filename' => 'invoice.pdf', 'content' => base64_encode($pdf), 'contentType' => 'application/pdf']. - Use stored emailr_ templates with
template_idandtemplate_dataif you'd rather edit copy in the dashboard than in Blade.
Frequently asked questions
Is there a Laravel mail driver for emailr_?
Not yet. Call the REST API with Laravel's HTTP client as shown here. You can keep using Mailables for rendering by calling render() and sending the HTML.
Can I queue emails in Laravel with emailr_?
Yes. Send from a job that implements ShouldQueue. Because the client calls throw(), failed API calls raise exceptions and the queue retries them.
How do I verify emailr_ webhooks in Laravel?
Compute hash_hmac('sha256', $request->getContent(), $secret) and compare it to the X-Emailr-Signature header with hash_equals. Register the route in routes/api.php to avoid CSRF checks.
Can I send attachments from Laravel?
Yes. Pass an attachments array of objects with filename, base64 content and an optional contentType.
Keep going
Documentation
Related guides
- Send email from RailsSend Action Mailer email from Rails through the emailr_ API with a custom delivery method, deliver_later support and signed webhook verification.
- Send email from FastAPISend transactional email from FastAPI with the async emailr_ Python SDK, run sends as background tasks and verify signed delivery webhooks.
- Send email from AWS LambdaSend transactional email from AWS Lambda with the emailr_ SDK, process SQS batches with partial failure reporting and handle signed webhooks.
Start sending in minutes
Create a free account, verify your domain and send your first email. No credit card required.