Ir al contenido principal

Email Setup

Configure email delivery so your Event Schedule instance can send ticket confirmations, newsletters, account emails and owner notifications.

Overview

Mail is configured once for the whole install, in your .env file. Every schedule on the instance sends through that one mail transport. Without a working mail configuration these features do nothing:

Ticket and booking confirmations

The confirmation a buyer receives after checkout, with the ticket details and QR code, plus appointment confirmations, reminders and reschedule notices, and gift card deliveries.

Newsletters

Newsletters that a schedule owner writes and sends to their followers. Following is an opt-in to be emailed by the schedule; there is no automatic email when a new event is added.

Guest notifications

Waitlist openings when a spot frees up, post-event feedback requests, and carpool messages between attendees.

Account and owner emails

Password resets, email verification for accounts and for a schedule's contact address, team member invitations, the daily digest of pending booking requests, opt-in alerts when a ticket sells, and the scheduled event graphic emails an owner sends to their own recipient list.

The default is not a real mail transport

Out of the box MAIL_MAILER=log. Event Schedule treats log and array as "no mail transport", so ticket and pass confirmations, appointment emails, gift card emails, sale alerts, feedback requests, carpool messages and poll suggestion notices are skipped entirely rather than delivered. Mail that is not gated this way, such as password resets, verification emails, team invitations, waitlist openings and newsletters, is written into storage/logs/laravel.log instead of being sent. Configure a real driver before you take a single booking.

Install-wide, and never plan-gated

A selfhosted install resolves to the Enterprise feature set, so no email feature here is held back by a plan. Note the difference from the hosted service: the per-schedule Email Settings tab, found in a schedule's Settings under Integrations, is only rendered when the app runs in hosted mode, and the monthly newsletter allowance, which on the hosted service counts individual recipients rather than newsletters, does not apply to a selfhosted install at all. Your schedules send unlimited newsletters to unlimited recipients through the mail transport you configure below.

SMTP Setup

SMTP is the recommended setup for a selfhosted install: it works with every provider and needs no extra packages. You can point it at your hosting provider's mail server, a mailbox at Gmail or Microsoft 365, or a transactional email service such as Amazon SES, Mailgun or Postmark.

Configure it in four steps

  1. Get SMTP credentials from your provider. A host name, a port, a username and a password. Transactional services issue SMTP credentials that are separate from their API keys.
  2. Add the variables to .env. Use the block below as a starting point and replace every value.
  3. Clear the config cache. Run php artisan config:clear, otherwise the old values keep being used.
  4. Send yourself a test message. See Testing below.

Environment Variables

Add these to your .env file:

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your-email@example.com
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"

Variable Reference

Variable Description Example
MAIL_MAILER Mail driver to use smtp
MAIL_HOST SMTP server hostname smtp.gmail.com
MAIL_PORT SMTP port number 587 (TLS) or 465 (SSL)
MAIL_USERNAME SMTP authentication username Your email address or API username
MAIL_PASSWORD SMTP authentication password Your password or app-specific password
MAIL_ENCRYPTION Encryption protocol tls or ssl
MAIL_FROM_ADDRESS Default sender email address hello@yourdomain.com
MAIL_FROM_NAME Default sender name ${APP_NAME} (uses your app name)
MAIL_URL Optional. A full SMTP connection string that stands in for the host, port, username and password values above. Useful when a provider hands you a single DSN smtp://user:pass@smtp.example.com:587
MAIL_EHLO_DOMAIN Optional. The domain announced in the SMTP handshake. Defaults to the host in your APP_URL, which is usually correct; set it only if your provider requires a specific EHLO name yourdomain.com

Popular SMTP Providers

Here are the settings for commonly used SMTP services:

Gmail / Google Workspace

Host: smtp.gmail.com | Port: 587 | Encryption: tls

Requires an App Password if 2FA is enabled. Personal mailboxes also apply a daily sending cap, so this suits a small instance rather than a busy one.

Outlook / Microsoft 365

Host: smtp.office365.com | Port: 587 | Encryption: tls

SMTP authentication has to be enabled for the mailbox in the Microsoft 365 admin center; many tenants have it off by default.

Amazon SES

Host: email-smtp.us-east-1.amazonaws.com (region-specific) | Port: 587 | Encryption: tls

Use your SES SMTP credentials (not your AWS access keys). SES also has a dedicated driver, see Other Mail Drivers.

Mailgun

Host: smtp.mailgun.org | Port: 587 | Encryption: tls

Username is usually postmaster@yourdomain.com. Mailgun is supported through SMTP; there is no mailgun API driver in Event Schedule.

Other Mail Drivers

Besides SMTP, Event Schedule ships with the mailers listed below. Set the one you want as MAIL_MAILER. Anything not in this table has to be added to config/mail.php yourself, and the app will fail with "Mailer is not defined" until it is.

Driver MAIL_MAILER Value Notes
SMTP smtp Works with any SMTP server. Recommended for most installs
Amazon SES ses Ready to use. Set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION; the AWS SDK is already bundled
Sendmail sendmail Uses the server's local sendmail binary. Override the path with MAIL_SENDMAIL_PATH
Failover failover Tries smtp first and falls back to log, so a delivery outage is recorded instead of throwing
Round robin roundrobin Alternates between ses and postmark. Only worth using once both of those are set up
Postmark postmark Set POSTMARK_TOKEN, and install the transport with composer require symfony/postmark-mailer. Postmark's SMTP endpoint needs no extra package
Resend resend Set RESEND_KEY, and install the transport with composer require resend/resend-php
Log log The default. Writes to storage/logs/laravel.log and suppresses transactional email. Development only
Array array Keeps messages in memory and sends nothing. Used by the test suite
Mailgun

There is no mailgun mailer in config/mail.php, so MAIL_MAILER=mailgun will not boot, and MAILGUN_DOMAIN and MAILGUN_SECRET are not read anywhere. Use Mailgun through SMTP instead, which is the same infrastructure and needs no extra package.

Recommendation

For production selfhosted instances, we recommend SMTP pointed at a transactional email service such as Mailgun, Amazon SES or Postmark. These services are built for application-generated email, they let you authenticate your sending domain, and they give you far better deliverability than a personal mailbox.

Sender Configuration

The MAIL_FROM_ADDRESS and MAIL_FROM_NAME determine who emails appear to come from. A fresh install ships with MAIL_FROM_ADDRESS="hello@example.com", a reserved example domain that no receiving server will trust, so change it to an address on a domain you control before you send anything.

.env
MAIL_FROM_ADDRESS=events@yourdomain.com
MAIL_FROM_NAME="My Event Schedule"

One sender for every schedule

On a selfhosted install this is the From identity for all outgoing mail, whichever schedule triggered it. There is no per-schedule sender to configure: the Email Settings tab that lets an owner supply their own SMTP credentials is part of the hosted service and is not rendered when the app runs selfhosted. Pick an address that reads sensibly for every schedule on the instance, and one you can actually receive replies at.

DNS Records

To improve email deliverability and avoid spam filters, set up these DNS records for your sending domain:

  • SPF - Authorizes your mail server to send on behalf of your domain
  • DKIM - Adds a digital signature to verify email authenticity
  • DMARC - Tells receiving servers how to handle authentication failures

Your email provider will give you the specific DNS records to add. Check their documentation for setup instructions.

Testing

After configuring your email settings, verify that mail is really being sent. The Send Test Email button in the admin portal belongs to the hosted per-schedule email settings, so on a selfhosted install you test from the command line.

1. Clear the config cache

Laravel caches .env values, so do this first or you will be testing the old configuration:

bash
php artisan config:clear

2. Send a test message

Use Laravel's built-in Artisan command to send a test email:

bash
php artisan tinker --execute="Mail::raw('Test email from Event Schedule', function(\$m) { \$m->to('your@email.com')->subject('Test'); });"

Send it to a real mailbox you can open. Addresses on the reserved test domains (example.com, example.org, example.net, test.com, test.org, test.net) and anything at @localhost are deliberately never emailed by the app's own notifications.

3. Confirm queued mail is being processed

Ticket confirmations, sale alerts and newsletter batches are dispatched as background jobs rather than sent inline. Which means:

  • With the default QUEUE_CONNECTION=sync they run immediately, in the same request. Nothing extra is needed.
  • With database or redis they wait for a worker. Event Schedule's scheduler runs queue:work --stop-when-empty every minute and retries failed jobs every five minutes, so the schedule:run cron job from the installation guide is what actually drains the mail queue. No cron, no email.
  • Scheduled newsletters are also released by that same cron, once a minute.

A real end-to-end check is a free RSVP or a test ticket purchase on one of your own schedules: it exercises the queue, the mailable and the sender address together.

Troubleshooting

Emails not sending

  • Verify MAIL_MAILER is not still log or array (log is the default)
  • Run php artisan config:clear after changing .env
  • Check storage/logs/laravel.log for error messages
  • If QUEUE_CONNECTION is not sync, confirm the schedule:run cron job is installed. It is what runs the queue worker; check storage/logs/scheduler.log and the failed_jobs table

Nothing arrives and nothing is logged

  • With MAIL_MAILER=log the app treats itself as having no mail transport and skips ticket, appointment, gift card, sale-alert and feedback emails outright, so there is no error to find. Configure a real driver
  • Confirmation emails are also skipped for addresses on the reserved test domains listed under Testing. Buy a test ticket with a real address

"Mailer [mailgun] is not defined"

  • MAIL_MAILER names a mailer that does not exist in config/mail.php. mailgun is the usual culprit; use smtp instead
  • A "class not found" error from a valid value such as postmark or resend means the transport package is missing. See Other Mail Drivers

Connection refused or timeout

  • Verify your server's firewall allows outbound connections on port 587 (or 465)
  • Some hosting providers block outbound SMTP. Check with your host.
  • Try using port 465 with MAIL_ENCRYPTION=ssl if port 587 is blocked

Authentication errors

  • Double-check your MAIL_USERNAME and MAIL_PASSWORD
  • For Gmail, use an App Password instead of your regular password
  • Make sure special characters in your password are properly quoted in the .env file (wrap in double quotes)

Emails going to spam

  • Set up SPF, DKIM, and DMARC DNS records for your domain
  • Use a MAIL_FROM_ADDRESS on a domain you own, not a free email provider and not the shipped hello@example.com
  • Consider using a dedicated transactional email service (Mailgun, SES, Postmark)