SDKs and frameworks/Platforms/Laravel Cloud

Markdown

Send email from Laravel Cloud

Updated Oct 24, 2026 · 3 min read

Send your Laravel app's Mailables, notifications and queued mail through Groundmail on Laravel Cloud. Install the Groundmail Laravel package, set two environment variables on the environment, and redeploy. Your Mail::to()->send() calls stay as they are.


Prerequisites

  • A Groundmail account with a verified sending domain. A subdomain such as mail.yourdomain.com works well.
  • An API key (gm_…) from API keys in the dashboard. A scoped key with only emails:send is enough for sending.
  • A Laravel app deployed to a Laravel Cloud environment.

Install the package

On your machine, so composer.json and composer.lock change in the repo you deploy:

Terminal
composer require groundmail/laravel

Add a mailer that uses the groundmail transport to config/mail.php:

PHP
'mailers' => [
    // ...
    'groundmail' => [
        'transport' => 'groundmail',
    ],
],

Commit and push.


Set the environment variables

In Laravel Cloud, open the environment's settings, go to Environment variables, and add:

Terminal
GROUNDMAIL_API_KEY=gm_your_key_here
MAIL_MAILER=groundmail
MAIL_FROM_ADDRESS=no-reply@mail.yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"

MAIL_FROM_ADDRESS must be on a domain you verified in Groundmail. Then redeploy the environment: Laravel Cloud writes the variables to your app's .env at deploy time, so changes only apply to a new deployment.

To share one key across several environments, store it once in Laravel Cloud's Secrets Manager and link the secret to each environment instead.

Your build command can keep php artisan optimize or php artisan config:cache: the variables are in .env during the build, so the cached config has them.


Send

Nothing changes in your code:

PHP
use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Mail;

Mail::to($user)->send(new WelcomeMail($user));

Queued Mailables and notifications (Mail::to($user)->queue(...), ShouldQueue) send from your Laravel Cloud workers or managed queue with the same variables. To make a queued job safe to retry, set an idempotency key header on the Mailable, for example 'welcome-'.$this->user->id. See Tags, idempotency, and schedule.

For batch sends, domains or webhooks, call the API client directly:

PHP
use Groundmail\Laravel\Facades\Groundmail;

Groundmail::client()->emails->send([
    'from' => 'no-reply@mail.yourdomain.com',
    'to' => 'user@example.com',
    'subject' => 'Your receipt',
    'html' => '<p>Thanks for your purchase.</p>',
]);

If the environment already has an Email resource

Laravel Cloud's own Email resource injects its own MAIL_MAILER and MAIL_FROM_* variables. Variables you add yourself take priority over injected ones, so setting MAIL_MAILER=groundmail as above is enough. To stop injecting them at all, detach the Email resource from the environment's canvas, then redeploy.


SMTP instead of the package

If you'd rather not add a package, use Laravel's built-in smtp mailer with the Groundmail SMTP relay. Create an SMTP credential under SMTP in the dashboard, then set:

Terminal
MAIL_MAILER=smtp
MAIL_SCHEME=smtp
MAIL_HOST=smtp.groundmail.dev
MAIL_PORT=587
MAIL_USERNAME=groundmail
MAIL_PASSWORD=gmsmtp_your_credential
MAIL_FROM_ADDRESS=no-reply@mail.yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"

Port 587 upgrades to TLS with STARTTLS. Keep MAIL_SCHEME=smtp (or unset): smtps means implicit TLS on port 465, which Groundmail doesn't offer. On Laravel 10 and earlier, use MAIL_ENCRYPTION=tls instead of MAIL_SCHEME. Port 2525 works the same way if 587 is ever blocked.

The package sends over HTTPS and maps Groundmail tags, idempotency keys and scheduled_at from headers; the relay supports the same headers (see Custom headers). Either way, sends show up under Emails in the dashboard.


Troubleshooting

Problem Fix
Mail still goes to log or another mailer The environment wasn't redeployed after you set MAIL_MAILER, or the config was cached before the change. Redeploy.
Unsupported mail transport [groundmail] groundmail/laravel isn't in the deployed composer.lock. Run composer require groundmail/laravel locally, commit and redeploy.
401 Unauthorized GROUNDMAIL_API_KEY is missing or revoked. Create a new key under API keys and redeploy.
domain is not verified MAIL_FROM_ADDRESS (or the Mailable's from) isn't on a domain you verified under Domains.
SMTP 535 authentication failed The username must be groundmail and the password an SMTP credential (gmsmtp_…), not an API key.

Related: Laravel · PHP SDK · SMTP relay

Was this page helpful?