Get your API key
All integrations Laravel

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
# .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
// 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
// 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
// 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

terminal
# 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:

routes/web.php
<?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=587 in .env.
  • 535 Authentication failed — the password must be your mk_live_… API key, not a separate SMTP credential.
  • Wrong From address — set MAIL_FROM_ADDRESS in .env to an address on a verified domain. Laravel defaults to APP_URL's domain which may not pass SPF/DKIM.
  • Queue not processing — run php artisan queue:work or 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.