Laravel + MailKite
Laravel has first-class SMTP support — set two environment variables and
every Mail::to() call goes through MailKite. No plugins, no
wrappers, no vendor lock-in. Same DKIM-signed delivery, same logs.
What you need
- A verified domain with SPF + DKIM published
- Your API key (
mk_live_…) - Laravel 8+ (any version with
MAIL_MAILER=smtp)
Configure .env
Laravel reads mail config from .env. Set these values:
# .env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailkite.dev
MAIL_PORT=587
MAIL_USERNAME=mailkite
MAIL_PASSWORD=mk_live_...
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"
That's it — Mail::to() now routes through MailKite. No code
changes needed.
config/mail.php (optional)
If you want to customize the driver or add MailKite as a named mailer:
// config/mail.php
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailkite.dev'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME', 'mailkite'),
'password' => env('MAIL_PASSWORD'),
'timeout' => 30,
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL'), PHP_URL_HOST)),
], Send email
Use Laravel's standard mail facade — Mailables, notifications, and markdown emails all work:
// routes/web.php or a controller
use Illuminate\Support\Facades\Mail;
use App\Mail\OrderConfirmation;
Route::post('/orders', function () {
$order = Order::create(request()->all());
// Queue the email (recommended)
Mail::to($order->email)
->queue(new OrderConfirmation($order));
// Or send immediately
// Mail::to($order->email)
// ->send(new OrderConfirmation($order));
return response()->json(['id' => $order->id]);
}); // app/Mail/OrderConfirmation.php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class OrderConfirmation extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public $order) {}
public function build()
{
return $this
->subject("Order #{$this->order->id} confirmed")
->view('emails.order-confirmation')
->text('emails.order-confirmation-plain')
->replyTo('support@yourdomain.com');
}
} Test it
# Test the mail config
php artisan tinker --execute="Mail::raw('Test from MailKite', fn($m) => $m->to('you@yourdomain.com')->subject('Laravel test')->send());"
# Or send via a queue worker
php artisan queue:work Receive inbound email
MailKite can POST inbound email to a Laravel route. Add a webhook endpoint:
<?php
// routes/web.php — inbound email webhook handler
Route::post('/webhooks/mailkite', function () {
$payload = request()->all();
// Verify signature
$sig = request()->header('X-MailKite-Signature');
$secret = config('services.mailkite.webhook_secret');
$computed = hash_hmac('sha256', json_encode($payload), $secret);
if (!hash_equals($computed, $sig)) {
return response()->json(['error' => 'invalid signature'], 401);
}
$from = $payload['from'];
$subject = $payload['subject'];
$text = $payload['text'];
// Process: create a support ticket, log, or trigger a job
dispatch(new ProcessInboundEmail($from, $subject, $text));
return response()->json(['ok' => true]);
});
Set your domain's webhook URL to
https://yourapp.com/webhooks/mailkite. The handler verifies
the signature and dispatches a job to process the inbound email.
Laravel queues
Use Mail::queue() instead of Mail::send() for
non-blocking delivery. MailKite's Send API returns
202 Accepted instantly — the queue worker handles retries. For
webhooks, dispatch a job from the controller to keep the response fast.
Troubleshooting
- Connection refused — you're probably on port 25. Set
MAIL_PORT=587in.env. - 535 Authentication failed — the password must be your
mk_live_…API key, not a separate SMTP credential. - Wrong From address — set
MAIL_FROM_ADDRESSin.envto an address on a verified domain. Laravel defaults toAPP_URL's domain which may not pass SPF/DKIM. - Queue not processing — run
php artisan queue:workor set up a supervisor. Queued mail won't send until the worker picks it up.
See the SMTP relay docs for the full connection reference, or Send API for using MailKite's SDK directly.