Symelo SMTP user guide

For Symelo SMTP version 1.0.0.

This guide explains how to set up Symelo SMTP, what every option does, and how to fix delivery problems yourself. The last section, "For developers", covers wp-config.php constants, hooks and WP-CLI commands.

Need help? Write to [email protected] or visit symelo.com.

What Symelo SMTP does

WordPress sends email (password resets, order confirmations, contact form messages) with PHP's built-in mail() function. Many hosts block it, and spam filters distrust it, so emails go missing.

Symelo SMTP sends every WordPress email through a proper email service instead:

  • SMTP (Simple Mail Transfer Protocol) is the standard way mail servers talk to each other. Almost every email provider offers an SMTP server you can log in to.
  • API mailers send through a provider's web API over normal HTTPS. They are often faster and work on hosts that block SMTP ports.
  • OAuth mailers (Gmail and Microsoft 365) let you sign in with your Google or Microsoft account instead of storing a password.

On top of that, Symelo SMTP:

  • logs every email with its status, so you can see what was sent, what failed and why;
  • tries a backup connection automatically when the main one fails;
  • sends alerts to Slack, Discord, Microsoft Teams or any webhook when an email fails;
  • has a Log only mode for staging sites, so test copies never email real customers;
  • explains common errors in plain language.

Requirements

  • WordPress 6.4 or newer.
  • PHP 7.4 or newer. On older PHP the plugin stays inactive and shows: "Symelo SMTP needs PHP 7.4 or newer."
  • An account with an email provider (or your host's mailbox), and permission for your server to reach it:
    • SMTP needs an open outgoing port (usually 587 or 465). Some hosts block these.
    • API mailers need outgoing HTTPS, which almost every host allows.
  • For Gmail / Google Workspace and Microsoft 365 / Outlook: a Google Cloud or Microsoft Entra app that you create yourself (explained below).
  • Only administrators can see and change the plugin (the manage_options capability). Developers can change this; see For developers.
  • Multisite works. Each site in the network has its own settings, connections and log.

Quick start

This gets you from installation to a working test email in a few minutes.

1. Install and activate

  1. In wp-admin, go to Plugins → Add New → Upload Plugin.
  2. Choose the plugin's .zip file, click Install Now, then Activate.

A new Symelo SMTP menu (envelope icon) appears in the admin sidebar.

2. Add your first connection

A connection is one way of sending email: a mailer (provider) plus its login details and sender address.

  1. Go to Symelo SMTP → Settings. Because there are no connections yet, the screen opens straight on Set up email delivery with the mailer picker.
  2. Under Mailer, click your provider's tile. If your provider isn't listed, choose Other SMTP.
  3. Fill in the provider's fields. Required fields have a red asterisk (*). The Setup guide link next to the mailer's description opens the provider's documentation. See Setting up each provider for where to find each value.
  4. Under Sender, fill in the From email: an address your provider lets you send from (your SMTP login, or an address on a domain you verified with the provider).
  5. Leave Use this address for every email, even when a plugin sets its own From address ticked. This is the safest setting.
  6. Optionally set a From name (for example your shop's name) and a Connection name (only used in the admin and the log).
  7. Click Add connection.

You'll see either "Connection saved." or "Connection saved, but it isn't ready yet:" followed by what's missing. Your first connection automatically becomes the Primary connection.

Gmail and Microsoft 365 only: after saving, you stay on the connection screen. Click Sign in with Google or Sign in with Microsoft in the Authorization box and allow access. See Gmail / Google Workspace or Microsoft 365 / Outlook first, because you need to create an app with the provider before you can sign in.

3. Send a test

  1. Click the Send a Test tab.
  2. Send to is filled in with your own address. Change it if you like.
  3. Leave Connection on Normal routing (primary, then backup).
  4. Click Send test email.

If it worked, you'll see Test email sent: "The provider accepted the email for … Check the inbox (and the spam folder)." If it failed, you'll see The test email failed with the exact error, plain-language hints and the Delivery attempts. See Troubleshooting.

That's it. From now on every email WordPress and your plugins send goes through this connection and appears in the Email Log.


Where to find everything

Symelo SMTP has one menu with two entries:

  • Symelo SMTP → Settings: all settings tabs on one screen. Tabs switch instantly without reloading.
  • Symelo SMTP → Email Log: the log. It shares the same tab bar, so you can also reach it with the Email Log tab.

The Plugins screen also has a Settings link under Symelo SMTP.

TabWhat it's for
ConnectionsAdd, edit and delete connections; choose the primary and backup connection.
Send a TestSend a test email through the normal routing or one specific connection.
Email LogEvery email sent, failed or held back, with details, resend and CSV export.
GeneralReturn path and the delivery mode (Send emails or Log only).
LoggingTurn the log on or off, store message content or not, and how long to keep entries.
AlertsSlack, Discord, Microsoft Teams or webhook alerts when an email fails.
AdvancedEncryption key status, uninstall behaviour, configuring with constants.
GuideThis user guide, inside the plugin, with a contents list and a search box ("Find in this guide").
SupportHelp links, a system information report to send to support, and contact details.

Connections tab

Status summary

The top card tells you how email is sent right now:

  • "Emails are sent through Name." and, if you set one, "If that fails, Name is tried next."
  • A red message after it if the primary connection has a problem (for example a missing password).
  • "No primary connection is selected, so emails are sent through the backup connection, Name, with nothing to fall back on. Choose a primary connection under Routing." when there is a backup but no primary connection. Emails then go through the backup alone.
  • "No primary connection is selected, so emails go out through the server's default mail setup." when there is neither.

The Add connection button opens an empty connection form.

Connections list

ColumnMeaning
NameThe connection name. Click it to edit.
MailerThe provider.
StatusReady, or Needs attention with the first problem found. For Gmail and Microsoft 365, Ready also shows the signed-in account.
RolePrimary or Backup. Empty for connections that aren't used.

Actions per row:

  • Edit (or View for a connection defined in wp-config.php).
  • Send a test: opens the Send a Test tab with this connection already selected.
  • Delete: asks for confirmation, then removes the connection. For Gmail it also revokes the sign-in at Google; for Microsoft the stored sign-in is deleted. If the deleted connection was the primary or backup, that role becomes empty. Without a primary connection, emails go through the backup alone (the status card says so), so pick a new Primary connection under Routing and click Save routing.

Problems the Status column can show:

MessageWhat to do
"… is required."Edit the connection and fill in that field.
"… can no longer be decrypted (the site keys changed). Enter it again."Re-enter the password or key. See The saved value can't be decrypted any more.
"Set the From email: an address this provider lets you send from."Fill in Sender → From email.
"Not authorized yet."Gmail or Microsoft 365: open the connection and click Sign in with ….
"Access was revoked or expired. Sign in again."Gmail or Microsoft 365: sign in again.
"Unknown mailer."The connection uses a mailer that no longer exists (for example from a deactivated add-on).

Routing

The Routing card appears once you have at least one connection.

SettingWhat it doesDefault
Primary connectionThe connection every email is sent through. With None, emails go through the backup connection alone, or through the server's default mail setup if there is no backup either.Your first connection. A connection you add while no primary is selected becomes the primary.
Backup connectionTried automatically when the primary connection fails, so emails still go out during a provider outage.None

Click Save routing after changing either one. The backup can't be the same as the primary.

If a connection is defined in wp-config.php, the primary is fixed to it: "Fixed to the connection defined in wp-config.php (SYMELO_SMTP_MAILER)." You can still choose a backup.

How the backup works: for each email, Symelo SMTP tries the primary connection. Only if that attempt fails does it try the backup. Both attempts are recorded under Delivery attempts in the log. Each connection sends with its own From address, so a backup on a different provider can use an address that provider accepts.

Adding or editing a connection

The connection form has four parts.

1. Mailer. Click a tile to choose the provider. Hover a tile to see a short description. A new connection starts on Other SMTP. Available mailers:

Other SMTP, Gmail / Google Workspace, Microsoft 365 / Outlook, Amazon SES, Brevo, Mailgun, SendGrid, Postmark, SendLayer, Resend, SMTP2GO, SparkPost, Mailjet, PHP mail().

If you change the mailer of an existing connection, the old mailer's saved secrets aren't carried over, and any Gmail or Microsoft sign-in is removed.

2. Provider settings. The fields for the chosen mailer. See Setting up each provider.

  • Passwords, API keys and client secrets are never shown again after saving. The field says "Saved. Leave blank to keep it." Leave it empty to keep the saved value, or type a new one to replace it.
  • For Gmail and Microsoft 365, an Authorized redirect URI box with a Copy button appears. Add this exact address to your OAuth app before signing in.

3. Sender. Providers only deliver email from addresses they trust: your SMTP login, or an address on a domain you verified with them. Other addresses are rejected (for example "You are not allowed to send from this address").

SettingWhat it doesDefault
From emailThe address this connection sends from. Required for most mailers. Optional for Gmail and Microsoft 365 (empty: the signed-in account) and PHP mail() (empty: the address WordPress or the plugin sets).Empty. For Other SMTP, typing an email address as the Username fills this in for you.
Use this address for every email, even when a plugin sets its own From addressReplaces any From address set by WordPress or a plugin with the one above. Recommended: replies still reach the right person because plugins like Contact Form 7 and WooCommerce set a Reply-To address.On
From nameThe sender name recipients see.Empty (the placeholder shows your site title).
Use this name for every emailReplaces names set by plugins with the one above.Off

4. Connection name. "Only shown here and in the email log. Defaults to the mailer's name." For example "Mailgun (main)".

Click Add connection (new) or Save connection (existing). The plugin checks the connection and tells you if something is missing. An invalid From email is not saved: "The From email isn't a valid address."

How the From address is chosen

For each email, the connection that sends it decides the From address:

SituationFrom email used
From email is set and Use this address for every email… is onAlways the connection's From email.
From email is set and the option is offWhatever WordPress or the plugin set. Only WordPress's default wordpress@yourdomain is replaced with the connection's From email. Microsoft 365: always the connection's From email, because Microsoft only sends from addresses the mailbox may use.
From email is emptyOther SMTP: the Username, if it is an email address. Gmail: the signed-in account. Microsoft 365: always the signed-in mailbox, even with the option off. Otherwise the address WordPress or the plugin set.
SituationFrom name used
From name is set and Use this name for every email is onAlways the connection's From name.
From name is set and the option is offThe plugin's own name. Only WordPress's default name "WordPress" is replaced.
In every caseIf the name would still be "WordPress", your site title is used instead.

Microsoft 365 / Outlook: with a From email that isn't the mailbox you signed in with (for example a shared mailbox), the mailbox needs "Send As" or "Send on Behalf" permission for that address. See Microsoft 365 / Outlook. Microsoft may show the mailbox's own display name instead of the From name.

Authorization (Gmail and Microsoft 365)

After you save a Gmail or Microsoft 365 connection, an Authorization box appears below the form.

  • Before signing in: "Save the client ID and secret first, then sign in to allow this site to send email." Click Sign in with Google or Sign in with Microsoft. If a required field is still empty (for example the Microsoft Tenant), you see "Finish the connection settings first:" followed by what's missing.
  • After signing in: a Connected badge and "Signed in as [email protected]." Click Disconnect to remove the sign-in (Google access is revoked at Google; Microsoft has no simple revocation, so the tokens are deleted from your site).

Sign in from the same browser and admin account that started it, and finish within 10 minutes. Otherwise you'll see "The sign-in link expired or was already used. Try again."

Once signed in, the plugin keeps the sign-in alive: a daily background task refreshes sign-ins that haven't been used for 7 days, so the provider doesn't expire them for inactivity.


Send a Test tab

Use this tab to check a connection without waiting for a real email.

FieldWhat it doesDefault
Send toThe recipient.Your own email address.
ConnectionNormal routing (primary, then backup) sends exactly like a real email. Only Name sends through that one connection, with no backup.Normal routing
FormatHTML or Plain text.HTML

Click Send test email. The subject is "Symelo SMTP test from your site name".

The result box shows:

  • Test email sent: the provider accepted the email. Check the inbox and the spam folder. "Accepted" means the provider took it; delivery to the inbox is then up to the provider and the recipient's mail server.
  • Test email logged, not sent: Log only mode is on, so the email was only recorded in the log.
  • The test email failed: the error, up to two hints on how to fix it, and the Delivery attempts.
  • Delivery attempts: one line per connection tried, marked Accepted or Failed. Open Technical details to see the SMTP conversation or the provider's response (passwords and keys are masked).

Notes:

  • In Log only mode, a test with Normal routing is only logged, not sent: "'Log only' mode is on, so the email to … was recorded in the log but not sent. Pick a specific connection to test real delivery." A test through Only Name really sends, even in Log only mode.
  • If the result says "Symelo SMTP didn't handle this email", another plugin is taking over WordPress email. See Another SMTP plugin is active.

Email Log

Go to Symelo SMTP → Email Log.

The list

At the top: Sent in the last 7 days, Failed in the last 7 days, and, if any, Logged only, not sent.

If logging is off, a warning says "Logging is turned off, so new emails aren't recorded." with a link to the Logging settings.

ColumnMeaning
SubjectClick to view the entry. Failed emails show the start of the error below the subject.
ToAll recipients (To, Cc and Bcc).
StatusSent, Failed or Not sent (log only).
Sent byThe plugin or theme that sent the email, or "WordPress".
ConnectionThe connection used last, or "WordPress default" when no connection was set up.
DateIn your site's timezone.

Ways to narrow the list:

  • Status views above the table: All, Sent, Failed, Not sent (log only) (a view only appears when it has entries).
  • Search emails: searches the subject, recipients, From address and error text.
  • Two date fields and Filter: show emails between two dates.
  • Sort by Subject, Status or Date by clicking the column header.
  • Screen Options (top right): entries per page, 20 by default, up to 200.

Row actions: View, Resend (only for emails whose content was stored), Delete. To delete many entries, tick them and choose Delete from the bulk actions.

Export to CSV downloads the entries that match the current filters, with the columns Date (UTC), Status, From, To, Subject, Connection, Mailer, Sent by and Error. Message bodies aren't exported.

One entry

Click a subject to see:

  • The subject and status, and for failed emails the error with hints.
  • Date, From, To, Cc, Bcc, Reply-To, Connection, Sent by, Message ID and Duration.
  • Attachments: file names and sizes. The files themselves are never stored.
  • Message: a safe preview of the HTML email. "Remote images are blocked for your privacy." Click Load them to show images from other sites, Block them to hide them again. A Plain-text version is shown when the email has one.
  • Extra headers: any custom headers the email had.
  • Delivery attempts, with Technical details.

If the body wasn't stored: "The content wasn't stored (Logging → Content is off)."

Resend

Resend sends the logged email again, through the current routing (not necessarily the connection used the first time), to the same recipients with the same subject, body and headers.

  • Attachments aren't stored, so they aren't resent: "Email resent, without its attachments (they aren't stored in the log)."
  • You can only resend emails whose content was stored, so Resend only appears for those, in the list and on the entry.
  • Resending creates a new log entry. In Log only mode the resent email is only logged.

General tab

SettingWhat it doesWhen to change itDefault
Return path → Send bounces to the From addressSets the envelope sender (where bounce messages go) to the From address. Applies to Other SMTP and PHP mail(); API providers handle bounces themselves.Turn on if you want bounce messages to reach your From mailbox and your SMTP server allows it.Off
Mode → Send emails / Log only: record emails but never send themLog only records every email in the log (status Not sent (log only)) but never sends it.Use Log only on staging or development copies of a live site, so customers never get test emails.Send emails

The Sender heading on this tab only reminds you that From email and name are set per connection, with an Edit connections link.

If the mode is set in wp-config.php, the choice is greyed out with "Set by SYMELO_SMTP_DELIVERY in wp-config.php."

Click Save Changes.


Logging tab

SettingWhat it doesDefault
Email log → Keep a log of sent and failed emailsRecords every email. When off, nothing new is logged and the dashboard widget is hidden. Failure notices and alerts still work.On
Content → Store the message body (needed to view and resend emails)Keeps the email's text and HTML. Recipients, subject and status are always logged. Turn this off if emails contain sensitive data. Bodies over 1 MB are cut off.On
Keep entries for … daysOlder entries are deleted once a day. 0 keeps them forever. Maximum 3650.30

Click Save Changes.

Delete all log entries removes every log entry at once (after a confirmation).


Alerts tab

Alerts tell you when an email fails, even if your site can't send email at all, because they go to a chat tool or webhook instead of by email.

Alert channels

Existing channels are listed with their Type and Destination (only the webhook's host name is shown, because the full address is a secret). Actions: Send test alert and Remove.

To add one, under Add a channel:

FieldWhat to enter
TypeSlack, Discord, Microsoft Teams or Webhook (JSON).
Webhook URLA public https:// address. Slack: an incoming webhook. Discord: channel settings → Integrations → Webhooks. Teams: a Workflows "When a Teams webhook request is received" flow.
Signing secretOptional, only for Webhook (JSON). Requests then carry an X-Symelo-Signature: sha256=… header: an HMAC of the request body made with this secret, so your receiver can check the request is genuine.

Click Add channel, then Send test alert to check it. You can add up to 10 channels.

Each alert contains the site name, the email's subject, recipients, the connection, the error and a link to the log entry.

Throttling

SettingWhat it doesDefault
At most one alert every … minutesPrevents a flood of alerts during an outage. The next alert says how many failures were skipped. 0 sends an alert for every failure. Maximum 1440 (one day).60

Click Save Changes.


Advanced tab

Encryption

Passwords, API keys, OAuth tokens and alert webhook addresses are stored encrypted in the database. This card shows which key protects them:

  • Dedicated key: they are encrypted with SYMELO_SMTP_KEY from wp-config.php. This is the strongest option: a copy of the database alone can't reveal them.

  • Site salt: they are encrypted with a key derived from your site's salts (the secret keys in wp-config.php). The card shows a ready-made line with a random key that you can paste into wp-config.php:

    define( 'SYMELO_SMTP_KEY', '…64 random characters…' );
    

    The key must be at least 32 characters long. The ready-made one has 64.

If SYMELO_SMTP_KEY is defined but shorter than 32 characters, it's ignored and the site salts are used. The card then shows a warning ("SYMELO_SMTP_KEY in wp-config.php is ignored because it's shorter than 32 characters…") above a new key to replace it with, and Site Health reports it too.

After adding or changing the key, everything that was encrypted with the old key can no longer be read. The card reminds you of this. You need to:

  1. Re-enter every saved password, API key and client secret (edit each connection).
  2. Sign in again on Gmail and Microsoft 365 connections.
  3. Remove and re-add alert channels that show "Unreadable, add it again".

Uninstall

SettingWhat it doesDefault
Delete all settings and logs when the plugin is deletedWhen you delete the plugin from the Plugins screen, also delete its settings, connections, OAuth sign-ins and the email log.Off

Click Save Changes. See Undoing and uninstalling.

Configure with constants

Agencies and developers can set Symelo SMTP up in wp-config.php instead. The card lists every supported constant. See For developers.


Support tab

  • Get help: links to Send a test email, View failed emails and Check Site Health, and an Email support button ([email protected]).
  • System information: a plain-text report with versions, the delivery mode, connections (mailer types, not secrets), log settings, last week's counts, the last failure, the encryption key type, other active SMTP plugins, and server details. It never includes passwords, API keys or tokens. Click Copy system information and paste it into your support email.
  • About Symelo LTD: a link to symelo.com.

Dashboard widget, notices and Site Health

Dashboard widget

Email delivery on the WordPress dashboard shows "Last 7 days: X sent, Y failed.", the last failure (if any), and links to the Email log and Send a test. It is shown to administrators while logging is on.

Admin notices

These appear on the Dashboard, the Plugins screen and the plugin's own screens (the two "no primary connection" notices only outside the plugin's screens, where the Connections tab already says it):

NoticeMeaning
"Symelo SMTP: emails are not being delivered. 'Log only' mode is on, so emails are logged but never sent."Log only mode is on. Change this opens the General tab.
"Symelo SMTP is active but no connection is set up yet, so emails still go out through the server's default mail setup."No primary or backup connection. Set up a connection opens the Connections tab.
"Symelo SMTP: no primary connection is selected, so emails are sent through the backup connection, Name, with nothing to fall back on."Only a backup connection is selected. Choose a primary connection opens the Connections tab.
"Symelo SMTP: check wp-config.php. SYMELO_SMTP_MAILER is set to "…", which isn't a mailer Symelo SMTP knows…"Shown on the plugin's screens when SYMELO_SMTP_MAILER is misspelled. The notice lists the valid mailer IDs.
"Symelo SMTP: an email failed to send." with the error and a hintAn email failed in the last 24 hours. View failed emails opens the filtered log; Dismiss hides it until the next failure. The notice also clears by itself after the next successful email.

Site Health

Tools → Site Health includes four Symelo SMTP checks:

CheckGood resultOtherwise
Email delivery is set up"Emails are sent through Name""SYMELO_SMTP_MAILER in wp-config.php isn't a known mailer", "Emails are logged but not sent ('Log only' mode)", "No primary email connection is selected" (emails go through the backup alone), "No email connection is set up" (emails go through the server's default mail setup), or "The email connection needs attention" with the problem.
Recent emails were delivered"No emails failed in the last 24 hours""N emails failed in the last 24 hours", with a link to the failed emails.
Only one SMTP plugin is active"Only one SMTP plugin is active""More than one SMTP plugin is active", naming the others.
Email credentials have a dedicated encryption key"Email credentials have a dedicated encryption key""Email credentials could use a dedicated encryption key", or "The Symelo SMTP encryption key is too short" when SYMELO_SMTP_KEY has fewer than 32 characters, with a link to the Advanced tab.

Site Health → Info → Symelo SMTP lists the version, primary and backup mailer, delivery mode, logging and whether a dedicated key is set (or is too short).


Setting up each provider

General tips that apply to every provider:

  • Verify your sending domain (or at least the sender address) with the provider before you start. Unverified From addresses are the most common reason for rejected emails.
  • Use the provider's Setup guide link on the connection form for the provider's own instructions.
  • Provider dashboards change often. If a menu name below doesn't match exactly, look for the closest equivalent.

Other SMTP

Use this for any SMTP server: your host's mailbox, Zoho, Fastmail, or a provider's SMTP relay.

FieldWhat to enterDefault
Fill in settings forPick a provider to fill in the host, port, encryption and (where it's fixed) the username. Shows a short hint for that provider.Choose a provider…
SMTP host (required)The server name, for example smtp.example.com.Empty
EncryptionSTARTTLS (usually port 587), SSL/TLS (usually port 465) or None.STARTTLS
Port (required)Changing the encryption moves the port to that encryption's usual port (587, 465 or 25), unless you typed a custom port.587
Upgrade to TLS when the server offers itOnly shown with encryption None. Switches to an encrypted connection if the server supports it.Enabled
Use authenticationLog in with a username and password. Turn off only for servers that don't need a login.Enabled
Username (required with authentication)Usually your full email address or the provider's SMTP login.Empty
Password (required with authentication)The password, app password or SMTP key.Empty
Verify the server's TLS certificate"Keep this on. Turn it off only for a local test server with a self-signed certificate."Enabled

SMTP connections time out after 20 seconds.

Presets in Fill in settings for:

PresetHostPort / encryptionUsernameHint shown
Gmail / Google Workspace (app password)smtp.gmail.com587 STARTTLS–Use an app password, not your account password. The Gmail mailer (OAuth) is the more secure option.
Microsoft 365 / Outlooksmtp.office365.com587 STARTTLS–Microsoft is retiring password-based SMTP. Prefer the Microsoft 365 / Outlook mailer (OAuth).
Brevosmtp-relay.brevo.com587 STARTTLS–Use the SMTP login and an SMTP key from Brevo → SMTP & API (not the API key).
Mailgun (US)smtp.mailgun.org587 STARTTLS–Use the domain's SMTP credentials, e.g. [email protected].
Mailgun (EU)smtp.eu.mailgun.org587 STARTTLS–Same as Mailgun (US).
SendGridsmtp.sendgrid.net587 STARTTLSapikeyThe username is literally "apikey"; the password is an API key with Mail Send permission.
Postmarksmtp.postmarkapp.com587 STARTTLS–Use your Server API token as both username and password.
SendLayersmtp.sendlayer.net587 STARTTLS–Use the SMTP credentials from SendLayer → Settings → SMTP Credentials.
Resendsmtp.resend.com587 STARTTLSresendThe username is "resend"; the password is your API key.
SMTP2GOmail.smtp2go.com587 STARTTLS–Use an SMTP user from SMTP2GO → Sending → SMTP Users (not the API key).
SparkPost (US)smtp.sparkpostmail.com587 STARTTLSSMTP_InjectionThe password is an API key with "Send via SMTP". EU accounts use smtp.eu.sparkpostmail.com.
Mailjetin-v3.mailjet.com587 STARTTLS–The username is your API key; the password is your Secret key.
Amazon SESemail-smtp.us-east-1.amazonaws.com587 STARTTLS–Replace us-east-1 with your SES region. SES SMTP credentials are different from IAM access keys.
Zoho Mailsmtp.zoho.com465 SSL/TLS–EU accounts use smtp.zoho.eu.
Mailpit / MailHog (local development)localhost1025, no encryption, no login–Catches all email locally. Never use this on a live site.

For most of these providers, the dedicated API mailer below is a better choice than SMTP: it works even when your host blocks SMTP ports.

Gmail / Google Workspace (OAuth)

Sends through the Gmail API with your Google account. No password is stored: you sign in with Google and the plugin stores an encrypted access token. Works with personal Gmail and Google Workspace accounts.

Fields:

FieldWhat to enter
Authorized redirect URIRead-only. Copy it into your Google app (step 4 below).
Client ID (required)Ends in .apps.googleusercontent.com.
Client secret (required)From the same OAuth client.

Permissions (scopes) the plugin asks for:

  • https://www.googleapis.com/auth/gmail.send: send email only. The plugin can't read your mailbox.
  • openid and email: to learn which address you signed in with.

Steps:

  1. Open the Google Cloud Console and create a project (or pick an existing one).
  2. Enable the Gmail API for the project.
  3. Open Google Auth platform and set up the consent screen:
    • Google Workspace: set the audience to Internal. Only people in your organisation can sign in, and access doesn't expire.
    • Personal Gmail: set the audience to External, add yourself as a test user if asked, then Publish app. In "Testing" mode Google expires access after 7 days.
  4. Go to Clients → Create client, choose Web application, and under authorized redirect URIs paste the Authorized redirect URI shown on the connection form. It must match exactly.
  5. Copy the Client ID and Client secret into the connection form, fill in the Sender, and click Add connection (or Save connection).
  6. In the Authorization box, click Sign in with Google, choose the account and allow sending email. Because this is your own app, Google may warn that it hasn't verified the app; you can continue.
  7. You return to the connection: "Connected. Signed in as [email protected]."

From address: leave From email empty to send as the signed-in account. If you set a different address, use one you've added to Gmail as a "Send mail as" alias; Google may otherwise replace it with the account address.

Limits: emails up to 35 MB including attachments. Gmail's own daily sending limits apply. When they are reached: "Gmail's sending limit was reached. It can take several hours to reset."

Microsoft 365 / Outlook (OAuth)

Sends through Microsoft Graph with a Microsoft 365 or Outlook.com mailbox. Sent emails are also saved in the mailbox's Sent Items folder.

Fields:

FieldWhat to enterDefault
Authorized redirect URIRead-only. Copy it into your Microsoft app (step 3 below).–
Application (client) ID (required)From the app's Overview page.Empty
Client secret (required)The secret's Value, not the Secret ID.Empty
Tenant (required)Which accounts may sign in (see the table below). The field's help text says the same.Empty for new connections. Connections defined in wp-config.php without SYMELO_SMTP_TENANT use common.
Your app's "Supported account types"Enter as Tenant
Single tenant only (the default for new registrations; older screens call it "Accounts in this organizational directory only")Your Directory (tenant) ID from the app's Overview page
Multiple Entra ID tenantsorganizations
Any Entra ID tenant + personal Microsoft accountscommon
Personal accounts only (Outlook.com, Hotmail)consumers

If the Tenant is common and signing in fails with AADSTS50194 ("…isn't configured as a multitenant application…"), your app is single tenant: enter its Directory (tenant) ID instead. The error message also says so.

Permissions (scopes) the plugin asks for: Mail.Send and User.Read (delegated Microsoft Graph permissions), plus openid, email and offline_access (so the sign-in keeps working without you). When the connection has a From email and the Tenant isn't consumers, it also asks for Mail.Send.Shared, which Microsoft needs for sending from another address.

Steps:

  1. Open the Microsoft Entra admin center and go to App registrations → New registration.
  2. Give it a name and choose the supported account types.
  3. Add a redirect URI with platform Web and paste the Authorized redirect URI from the connection form.
  4. Under API permissions, add the delegated Microsoft Graph permissions Mail.Send and User.Read, plus Mail.Send.Shared if you'll send from another address (such as a shared mailbox). If your organisation requires it, grant admin consent.
  5. Under Certificates & secrets → New client secret, create a secret and copy its Value right away.
  6. Fill in Application (client) ID, Client secret and Tenant (see the table above), set the Sender (or leave From email empty to send as the mailbox you'll sign in with), then click Add connection (or Save connection).
  7. Click Sign in with Microsoft, choose the mailbox and accept.

Things to know:

  • From address: leave From email empty to send as the signed-in mailbox. To send from another address, such as a shared mailbox, enter it as the From email. The signed-in mailbox then needs "Send As" or "Send on Behalf" permission for it (a Microsoft 365 admin grants this), and you need to sign in again after setting the address, so the sign-in includes Mail.Send.Shared. Personal Outlook.com accounts can only send as themselves.
  • Without that permission, sending fails with ErrorSendAsDenied: "The signed-in mailbox isn't allowed to send from this From email. Either leave the connection's From email empty (or enter the signed-in mailbox), or have a Microsoft 365 admin give the mailbox "Send As" or "Send on Behalf" permission for this address, then open the connection and sign in with Microsoft once more."
  • Microsoft may show the mailbox's own display name instead of the From name. To change the name recipients see, change the mailbox's display name in Microsoft 365.
  • The mailbox needs an Exchange Online licence. Other 403 errors say: "The mailbox may not have an Exchange Online license, or the sign-in is missing a permission. Open the connection and sign in again."
  • Client secrets expire (at most after 24 months). Add a new secret before then and enter it in the connection.
  • Emails are limited to 4 MB including attachments.
  • If your site uses Plain permalinks, the redirect URI contains ?rest_route=, and a warning appears below it. Microsoft doesn't accept redirect URIs with a query string for apps that personal Microsoft accounts sign in to. Choose any other structure under Settings → Permalinks, then copy the new address.

Amazon SES

Low-cost, high-volume sending from AWS, through the SES v2 API.

FieldWhat to enterDefault
Access key ID (required)Create an IAM user allowed only ses:SendEmail and give it an access key. These are not the SES SMTP credentials.Empty
Secret access key (required)The secret of that access key.Empty
RegionThe region where your sending identity (domain or address) is verified.US East (N. Virginia) – us-east-1
Configuration setOptional, for event publishing.Empty

New SES accounts start in the "sandbox" and can only send to verified addresses. Ask AWS for production access before going live.

Limits: 50 recipients per email (To, Cc and Bcc together), 40 MB per email.

Brevo

Formerly Sendinblue.

FieldWhat to enter
API key (required)Brevo → Settings → SMTP & API → API keys.
  • The sender address must be verified in Brevo.
  • Brevo can block API calls from unknown IP addresses. If you get an HTTP 401 error, check the key and authorize your server's IP under Security → Authorized IPs.
  • Brevo accepts a single Reply-To address; only the first one is used.
  • Limit: 20 MB per email.

Mailgun

FieldWhat to enterDefault
API key (required)A domain Sending API key is best: it can only send email for that domain.Empty
Sending domain (required)The domain set up in Mailgun, for example mg.example.com.Empty
RegionUS or EU: the region where the domain was created.US

A wrong region or domain gives an HTTP 401 or 404 error: "Check the API key, the sending domain, and that the region matches where the domain was created." Limit: 25 MB per email.

SendGrid

FieldWhat to enterDefault
API key (required)Settings → API Keys. "Restricted access" with only Mail Send is enough.Empty
RegionGlobal, or EU (regional subusers only).Global

The sender must be a verified Sender Identity. Limit: 30 MB per email.

Postmark

FieldWhat to enterDefault
Server API token (required)Servers → your server → API Tokens. An Account token won't work.Empty
Message stream"outbound" is the default transactional stream.outbound

Limits: 50 recipients per email, 10 MB per email.

SendLayer

FieldWhat to enter
API key (required)SendLayer → Settings → API Keys.

Send from an address on a domain authorized in SendLayer. Limits: 10 "to", 10 "cc" and 5 "bcc" recipients per email, 10 MB per email.

Resend

FieldWhat to enter
API key (required)Resend → API Keys, with "Sending access". Starts with re_.

The sender's domain must be verified in Resend. Limits: 50 "to" recipients per email, 40 MB per email.

SMTP2GO

FieldWhat to enterDefault
API key (required)SMTP2GO → Sending → API Keys, with the "Emails" permission. Starts with api-.Empty
RegionAutomatic (nearest), US, EU or Australia.Automatic (nearest)

Limit: 50 MB per email.

SparkPost

FieldWhat to enterDefault
API key (required)Account → API Keys, with the "Transmissions: Read/Write" permission.Empty
RegionUS (sparkpost.com) or EU (eu.sparkpost.com), matching your account.US

Symelo SMTP sends through SparkPost as transactional email with open and click tracking turned off. Limit: 20 MB per email.

Mailjet

FieldWhat to enter
API key (required)Account settings → REST API → API Key Management.
Secret key (required)From the same page.

The sender address must be validated in Mailjet. Mailjet accepts a single Reply-To address; only the first one is used. Limits: 50 recipients per email, 15 MB per email.

PHP mail()

The server's own mail function. No settings are needed ("No settings needed."), but deliverability is poor and many hosts don't support it. Use it only as a last-resort backup connection. From email is optional for this mailer: left empty, emails keep the From address WordPress or the sending plugin sets.

Limits at a glance

Symelo SMTP checks these limits before sending, so you get a clear error instead of a rejected request.

MailerLargest email (incl. attachments)Recipients per email
Gmail / Google Workspace35 MB–
Microsoft 365 / Outlook4 MB–
Amazon SES40 MB50 in total
Brevo20 MB–
Mailgun25 MB–
SendGrid30 MB–
Postmark10 MB50 in total
SendLayer10 MB10 to, 10 cc, 5 bcc
Resend40 MB50 "to"
SMTP2GO50 MB–
SparkPost20 MB–
Mailjet15 MB50 in total

A dash means Symelo SMTP doesn't check a limit itself; the provider's own limits still apply. API requests time out after 30 seconds.


How-to recipes

Send through Brevo with a backup connection

  1. In Brevo, verify your sending domain or sender address and create an API key (Settings → SMTP & API → API keys).
  2. In WordPress, go to Symelo SMTP → Settings and click Add connection.
  3. Choose Brevo, paste the API key, set From email to your verified address, name the connection "Brevo", and click Add connection.
  4. Click Add connection again and set up the backup, for example Other SMTP with your host's mailbox, or a second provider. Give it its own From email that this provider accepts.
  5. In Routing, set Primary connection to Brevo and Backup connection to the second connection. Click Save routing.
  6. On Send a Test, choose Only backup name and send a test, to make sure the backup works on its own.
  7. Send one more test with Normal routing (primary, then backup).

When Brevo fails, the log entry shows two Delivery attempts: the failed Brevo attempt and the accepted backup attempt.

Keep emails from being sent on a staging site

Option A, in the admin:

  1. On the staging site, go to Symelo SMTP → Settings → General.
  2. Under Mode, choose Log only: record emails but never send them and click Save Changes.

Option B, in wp-config.php (better for agencies, because it survives database copies from the live site):

define( 'SYMELO_SMTP_DELIVERY', 'log_only' );

Add this to the staging site's wp-config.php before you import the live database, so the copy can't send anything in between. The Mode setting is then locked: "Set by SYMELO_SMTP_DELIVERY in wp-config.php."

In both cases:

  • Emails appear in the log as Not sent (log only), and a warning notice reminds you that emails aren't delivered.
  • A test with Normal routing is only logged. A test through Only Name really sends, so use it only with your own address.

Get a Slack message when an email fails

  1. In Slack, create an incoming webhook for the channel you want and copy its URL.
  2. Go to Symelo SMTP → Settings → Alerts.
  3. Under Add a channel, set Type to Slack, paste the Webhook URL and click Add channel.
  4. Click Send test alert. You should see "Symelo SMTP test alert from your site" in Slack.
  5. Adjust At most one alert every … minutes if you want more or fewer alerts during an outage.

Send all emails from your domain and keep replies working

Contact form and shop plugins often set the visitor's or customer's address as the From address. Providers reject that.

  1. Edit your connection.
  2. Set From email to an address on your verified domain, for example [email protected].
  3. Keep Use this address for every email, even when a plugin sets its own From address ticked.
  4. Save.

Replies still reach the right person when the plugin sets a Reply-To address (Contact Form 7 and WooCommerce do).

Store less personal data in the email log

  1. Go to Settings → Logging.
  2. Untick Store the message body to keep only recipients, subject and status. (You then can't view or resend emails.)
  3. Lower Keep entries for to the number of days you really need.
  4. Click Save Changes.
  5. Optionally click Delete all log entries to remove what's already stored.

Set up a client site in wp-config.php

Defining the connection in wp-config.php keeps credentials out of the database and stops site editors from changing them.

define( 'SYMELO_SMTP_MAILER', 'mailgun' );
define( 'SYMELO_SMTP_API_KEY', 'your-key' );
define( 'SYMELO_SMTP_DOMAIN', 'mg.example.com' );
define( 'SYMELO_SMTP_REGION', 'eu' );
define( 'SYMELO_SMTP_FROM_EMAIL', '[email protected]' );
define( 'SYMELO_SMTP_FROM_NAME', 'Example Ltd' );

The connection appears as "Defined in wp-config.php", is always the primary, and can only be viewed in the admin. Settings → Advanced → Configure with constants lists every constant. See For developers.


Troubleshooting

Start here

  1. Send a test from Send a Test. The result shows the exact error and hints.
  2. Or open the failed email in the Email Log. The error, hints and Delivery attempts are at the top.
  3. Open Technical details under the attempt to see the SMTP conversation or the provider's response.

Most problems come down to the From address, the login details or a blocked port.

Common errors

Symelo SMTP recognises these errors and shows the matching hint:

Error looks likeCause and fix
"from address failed", "not allowed to send from", "sender address rejected", "right to send mail on behalf", "5.7.60", "553 5.7.1"The server refused the From address. Edit the connection and set Sender → From email to an address this account may send from (for SMTP usually the username), and keep Use this address for every email on.
"could not authenticate", "535", "authentication failed", "username and password not accepted"The server rejected the username or password. Gmail and Google Workspace need an app password (or use the Gmail mailer). Microsoft 365 needs SMTP AUTH enabled for the mailbox (or use the Microsoft 365 mailer).
"could not connect", "connection refused", "timed out", "network is unreachable"The mail server couldn't be reached. Many hosts block outgoing SMTP ports (25, 465, 587): ask your host to open them, try port 2525 if your provider supports it, or switch to an API mailer, which uses normal HTTPS.
"certificate", "ssl", "tls", "handshake"The secure connection failed. Make sure the encryption matches the port: SSL/TLS for 465, STARTTLS for 587.
"sender identity", "not verified", "domain is not …"Your provider doesn't accept this From address yet. Verify the address or its domain with the provider, then enter it as the connection's From email (edit the connection, under Sender).
"HTTP 401", "unauthorized", "invalid api key", "forbidden"The provider rejected the API key. Check that you copied the whole key and that it has permission to send email.
"HTTP 429", "rate limit", "quota", "daily limit", "credits"A sending limit was reached. Wait a while, or raise the limit with your provider.
"AADSTS50194", "AADSTS90002"Microsoft needs this app's own tenant. Copy the Directory (tenant) ID from the app's Overview page in Microsoft Entra into the connection's Tenant field, save, and sign in again.
"invalid_grant", "revoked", "expired", other "AADSTS…" codesThe OAuth authorization is no longer valid. Open the connection and sign in again. For Microsoft, also check that the client secret hasn't expired.
"Could not instantiate mail function", "mail() has been disabled"This server can't send email with PHP mail(). Add an SMTP or API connection.
"too large", "size limit"The email is too big for this provider, usually because of attachments. Send smaller files or a link instead.
"Could not reach the provider: …"Your server couldn't connect to the provider's API. Check that outgoing HTTPS is allowed, or ask your host.
"Provider rejected the email (HTTP code): …"The provider's own explanation follows the colon.
"The email is too large for Provider (limit …, including attachments)."See Limits at a glance.
"Attachment "…" could not be read."The file the sending plugin attached doesn't exist or isn't readable.
"Unknown mailer "…". Was an add-on deactivated?"The connection uses a mailer from a plugin that's no longer active.

The test says "sent", but the email never arrives

"Accepted" means the provider took the email. If it doesn't arrive:

  • Check the spam folder.
  • Check the provider's own activity log; it shows whether the recipient's server accepted or bounced the email.
  • Make sure the From address's domain is verified with the provider (SPF and DKIM records). Unverified domains often land in spam.
  • Check that the delivery mode isn't Log only (the log status would be Not sent (log only)).

Gmail stops working after 7 days

Your Google Cloud app is in "Testing" mode. Publish it ("In production"), or set its audience to "Internal" if you use Google Workspace. Then open the connection and sign in again.

Microsoft 365 suddenly fails

  • "AADSTS…" errors after months of working usually mean the client secret expired. Create a new secret in Microsoft Entra, enter its Value in the connection and save.
  • ErrorSendAsDenied means the From email is an address the signed-in mailbox may not send as. Leave From email empty, or have the mailbox given "Send As" or "Send on Behalf" permission and sign in again. See Microsoft 365 / Outlook.

Sign-in problems (Gmail and Microsoft 365)

MessageFix
"Save the client ID and client secret first."Fill in both fields and save the connection before signing in.
"Finish the connection settings first: …"A required field is still empty, for example the Microsoft Tenant. Fill it in and save the connection.
"The sign-in link expired or was already used. Try again."Click Sign in with … again and finish within 10 minutes, in the same browser and admin account.
"Sign-in was not completed: …"You cancelled, or the provider refused. The provider's reason follows the colon; often the redirect URI doesn't match. Copy the Authorized redirect URI again and paste it into the app exactly.
"… AADSTS50194: Application … isn't configured as a multitenant application …"Your Microsoft app is single tenant, but the Tenant field says common or organizations. Enter the app's Directory (tenant) ID, save and sign in again. The message ends with this advice too.
"The provider didn't return a refresh token, so the connection would stop working within an hour."Remove this site's access in your Google or Microsoft account security settings, then sign in again.
"Permission to send email wasn't granted."Sign in again and allow sending email on the consent screen.
"The sign-in service refused the request (…)"Usually a wrong client ID, client secret or tenant. A matching hint follows the message when Symelo SMTP recognises the error.

If your site's address changes (new domain, or http to https), the redirect URI changes too. Update it in your Google or Microsoft app and sign in again.

The saved value can't be decrypted any more

You see "The saved value can't be decrypted any more (the site's keys changed). Enter it again." or "… can no longer be decrypted …".

Secrets are encrypted with SYMELO_SMTP_KEY or, without it, with your site's salts. If the key or the salts changed (some security plugins rotate salts, and a site copied to a new server may have different wp-config.php keys), the old values can't be read. Re-enter the passwords and keys, sign in again on OAuth connections, and re-add alert channels marked "Unreadable, add it again". Adding a dedicated SYMELO_SMTP_KEY (and copying it along with the site) prevents this in future.

Another SMTP plugin is active

Only one plugin can be in charge of WordPress email. Site Health reports "More than one SMTP plugin is active" when it finds WP Mail SMTP, WP Mail SMTP Pro, FluentSMTP, Post SMTP, Easy WP SMTP, GoSMTP, SMTP Mailer, WP Offload SES Lite or SureMail. Deactivate the others.

If a test says "Symelo SMTP didn't handle this email. Another plugin may be taking over wp_mail(); deactivate other SMTP plugins.", some other plugin intercepted the email before Symelo SMTP saw it.

Alerts don't arrive

  • Click Send test alert. Errors are shown: "The test alert failed: …" or "The webhook answered with HTTP …".
  • The webhook URL must be a public https:// address. Addresses on your local network are refused.
  • During an outage, only one alert is sent per throttle period (60 minutes by default).

Still stuck?

Go to the Support tab, click Copy system information, and email it with a description of the problem to [email protected].


Privacy and security

What is stored, and where

DataWhereProtection
Settings and connections (provider, host, username, From address)The symelo_smtp_settings option in the WordPress database.Passwords, API keys and client secrets are encrypted.
OAuth sign-ins (Gmail, Microsoft 365)One database option per connection.Encrypted.
Alert webhook addresses and signing secretsIn the settings option.Encrypted. Only the host is shown in the admin.
Email logA database table ({prefix}symelo_smtp_logs) per site.Visible only to administrators.

Encryption uses libsodium with SYMELO_SMTP_KEY from wp-config.php, or a key derived from your site's salts. Secrets are never sent back to the browser: secret fields stay empty after saving.

The email log stores, per email: date, status, From address and name, all recipients (To, Cc, Bcc, Reply-To), subject, custom headers, attachment names and sizes (never the files), the connection and mailer used, the sending plugin, the provider's message ID, any error, and the delivery attempts. With Content on, it also stores the message body (up to 1 MB). Debug output in Technical details never contains the email content (it's replaced with "[message content omitted]"), and passwords, keys and tokens are masked.

Log entries are deleted after the retention period (30 days by default). With Keep entries for set to 0, they are kept until you delete them.

What is sent where

  • Your emails go to the provider of the connection that sends them. API requests identify themselves with a SymeloSMTP/<version> user agent that includes your site's address.
  • Gmail / Microsoft 365 sign-in: your browser goes to Google's or Microsoft's sign-in page. Your site then exchanges the sign-in for tokens directly with Google or Microsoft, learns your account's email address, and later renews the tokens with them. Disconnecting or deleting a Gmail connection also asks Google to revoke the sign-in.
  • Alerts go to the webhook addresses you entered: site name and address, the failed email's subject and recipients, the connection name, the error and a link to the log entry.
  • Nothing is sent anywhere until you add a connection or an alert channel, and the plugin never sends anything to Symelo LTD.

GDPR tools

  • Tools → Export Personal Data includes "Symelo SMTP email log" entries sent to or from the requested address (date, From, recipients, subject and message text).
  • Tools → Erase Personal Data deletes those log entries.
  • Settings → Privacy offers suggested text for your privacy policy, describing the email log. It follows your Keep entries for setting: "Log entries are deleted automatically after 30 days." or, with 0, "Log entries are kept until the site owner deletes them."

Viewing logged emails safely

Logged HTML emails are shown inside a locked-down preview frame that can't run scripts, and remote images are blocked until you click Load them. This protects you from tracking pixels and malicious content in logged emails.

Security notes

  • Every admin action checks that you're an administrator and uses WordPress's nonce protection against forged requests.
  • OAuth uses the authorization code flow with PKCE, and the sign-in is bound to the admin who started it.
  • CSV exports neutralise spreadsheet formulas.

Undoing and uninstalling

  • Stop using a connection: change Routing or delete the connection. If you delete every connection, WordPress's default mail setup takes over again.
  • Stop sending without uninstalling: switch General → Mode to Log only.
  • Deactivate: WordPress immediately goes back to its default way of sending email. Settings, connections and the log stay in the database, so reactivating restores everything. The daily clean-up task stops.
  • Delete (Plugins → Delete):
    • If Advanced → Uninstall → Delete all settings and logs when the plugin is deleted is on: settings, connections, OAuth sign-ins, the email log table and temporary data are removed. On multisite, each site's own setting decides what happens to that site's data.
    • If it's off (the default): settings and the log are kept in the database, so a reinstall picks up where you left off.
    • In both cases, per-user preferences (dismissed notices, entries per page) are removed.

Deleting the plugin doesn't revoke the Google or Microsoft app you created. Click Disconnect on those connections first, or remove the app's access in your account settings.


For developers

wp-config.php constants

Constants override the settings screen and lock the matching fields.

Connection. Defining SYMELO_SMTP_MAILER creates a read-only connection named "Defined in wp-config.php" (ID wp-config) that is always the primary connection.

ConstantUsed byValues
SYMELO_SMTP_MAILER–smtp, gmail, outlook, amazon_ses, brevo, mailgun, sendgrid, postmark, sendlayer, resend, smtp2go, sparkpost, mailjet, php_mail
SYMELO_SMTP_HOSTsmtpHost name
SYMELO_SMTP_ENCRYPTIONsmtptls (STARTTLS), ssl, none
SYMELO_SMTP_PORTsmtpPort number
SYMELO_SMTP_AUTO_TLSsmtptrue / false
SYMELO_SMTP_AUTHsmtptrue / false
SYMELO_SMTP_USERNAMEsmtpUsername
SYMELO_SMTP_PASSWORDsmtpPassword
SYMELO_SMTP_VERIFY_CERTIFICATEsmtptrue / false
SYMELO_SMTP_CLIENT_IDgmail, outlookOAuth client ID
SYMELO_SMTP_CLIENT_SECRETgmail, outlookOAuth client secret
SYMELO_SMTP_TENANToutlookDirectory (tenant) ID, organizations, common or consumers (default common)
SYMELO_SMTP_ACCESS_KEY_IDamazon_sesIAM access key ID
SYMELO_SMTP_SECRET_ACCESS_KEYamazon_sesIAM secret access key
SYMELO_SMTP_REGIONamazon_ses, mailgun, sendgrid, smtp2go, sparkpostSES region code (e.g. eu-west-1); Mailgun us/eu; SendGrid global/eu; SMTP2GO auto/us/eu/au; SparkPost us/eu
SYMELO_SMTP_CONFIGURATION_SETamazon_sesConfiguration set name
SYMELO_SMTP_API_KEYbrevo, mailgun, sendgrid, sendlayer, resend, smtp2go, sparkpost, mailjetAPI key
SYMELO_SMTP_DOMAINmailgunSending domain
SYMELO_SMTP_SERVER_TOKENpostmarkServer API token
SYMELO_SMTP_MESSAGE_STREAMpostmarkMessage stream (default outbound)
SYMELO_SMTP_SECRET_KEYmailjetSecret key
SYMELO_SMTP_FROM_EMAILallFrom email
SYMELO_SMTP_FROM_NAMEallFrom name
SYMELO_SMTP_FORCE_FROM_EMAILalltrue (default) / false
SYMELO_SMTP_FORCE_FROM_NAMEalltrue / false (default)

Fields you don't define use the mailer's defaults. If SYMELO_SMTP_MAILER names an unknown mailer, the constants are ignored, and the plugin's screens and Site Health show a warning with the value and the valid mailer IDs. Gmail and Microsoft connections defined this way still need a one-time Sign in with … from the View screen.

General and encryption:

ConstantValues
SYMELO_SMTP_DELIVERYsend or log_only. Locks General → Mode.
SYMELO_SMTP_KEYAt least 32 random characters (the Advanced tab suggests a random 64-character key). Encryption key for stored secrets. Shorter keys are ignored, with a warning on the Advanced tab and in Site Health.

Actions

ActionArgumentsWhen
symelo_smtp_loadedPlugin $pluginSymelo SMTP has loaded. Add-ons hook in here.
symelo_smtp_register_mailersRegistry $registryRegister a custom mailer with $registry->add( new My_Mailer() ). Mailers implement Symelo\SMTP\Mailers\MailerInterface.
symelo_smtp_mail_sentarray $entryAn email was handed to the provider. Keys: status, mailer, connection, message (a Symelo\SMTP\Mail\Message), message_id, attempts, log_id, and more.
symelo_smtp_mail_failedarray $entryNo connection could deliver an email. Same keys, plus error.

Filters

FilterDefaultPurpose
symelo_smtp_capability'manage_options'Capability needed to see and change settings and logs.
symelo_smtp_log_row–( array $row, array $entry ). Change a log row before it's stored, or return false to skip logging it.
symelo_smtp_smtp_presetsBuilt-in presetsAdd or change SMTP presets: id => [ label, host, port, encryption (tls/ssl/none), username, auth, help ].
symelo_smtp_http_timeout30( int $seconds, string $mailer_id ). Timeout for provider API requests (minimum 5).
symelo_smtp_smtp_timeout20SMTP connection timeout in seconds (minimum 5).
symelo_smtp_more_from_symelo[]Products listed under "More from Symelo LTD" on the Support tab: [ [ 'title' => …, 'description' => …, 'url' => … ] ]. The card only appears when the list isn't empty.

WP-CLI

CommandWhat it does
wp symelo-smtp statusDelivery mode, primary and backup connection (without a primary: whether emails go through the backup or the server's default mail setup), From address, and last 7 days' counts.
wp symelo-smtp connections [--format=<table|json|csv|yaml>]Lists connections with ID, name, mailer, role and status.
wp symelo-smtp test <email> [--connection=<id>]Sends a test email and prints each attempt. --connection sends through one connection only (and really sends, even in Log only mode). In Log only mode without --connection, the email is only logged and the command ends with a warning instead of "Success".
wp symelo-smtp log list [--status=<sent|failed|blocked>] [--limit=<n>] [--format=<format>]Recent log entries (default 20, maximum 200). blocked means "Not sent (log only)".
wp symelo-smtp log purge --older-than=<days>Deletes entries older than that many days.
wp symelo-smtp log purge --all [--yes]Deletes every entry (asks for confirmation unless --yes).

REST API

Symelo SMTP registers one public route, GET /wp-json/symelo-smtp/v1/oauth. It is the OAuth redirect target and only forwards Google's or Microsoft's response into wp-admin, where the signed-in administrator and the sign-in request are verified. There is no REST API for managing settings.

Webhook (JSON) payload

Alert channels of type Webhook (JSON) receive a POST with Content-Type: application/json:

{
  "event": "email_failed",
  "site": "My Site",
  "site_url": "https://example.com/",
  "time": "2026-10-12T09:30:00+00:00",
  "subject": "Your order",
  "recipients": "[email protected]",
  "connection": "Brevo",
  "error": "Brevo rejected the email (HTTP 401): …",
  "log_url": "https://example.com/wp-admin/admin.php?page=symelo-smtp-log&view=123",
  "suppressed": 0
}

event is test for test alerts. suppressed is the number of failures skipped by throttling since the last alert. With a signing secret, the X-Symelo-Signature header is sha256= followed by the hex HMAC-SHA256 of the raw request body.

Scheduled task

symelo_smtp_daily runs once a day: it deletes log entries older than the retention period and refreshes OAuth sign-ins not used for 7 days. It's removed on deactivation.

user-guide.md