Send emails with phpList
Point phpList's SMTP settings at PostShiba.
What you'll build
A self-hosted phpList 3 install that sends its campaigns and system messages through PostShiba over SMTP. phpList keeps your lists, campaigns, and unsubscribe links. PostShiba delivers the mail and suppresses addresses that hard bounce or report spam.
Before you start
- A Marketing cluster. Newsletters belong on a bulk cluster, not a transactional one, and the type is locked after create. See Clusters.
- An SMTP username and password. Open your cluster in the dashboard, go to its SMTP credentials, and choose Create SMTP credential. Copy the password right away, because it is shown once. You can also use the SMTP credentials API.
- A verified sending domain. See Add and verify a domain. Each campaign's From Line and phpList's system from address must be on it.
- A cluster that is ready to send (
sending_readyistrue). - Shell or file access to the phpList install, so you can edit
config/config.php. This page is for self-hosted phpList.
Install
Nothing to install. phpList sends through PHPMailer, which has SMTP support built in.
Pick a plan for your largest list
PostShiba caps each cluster per hour and per rolling 24 hours. The 24-hour cap must cover your largest list plus anything else the cluster sends that day.
| Plan | Emails per hour | Emails per 24 hours | phpList MAILQUEUE_BATCH_SIZE |
|---|---|---|---|
| Nano | 100 | 600 | Test sends only |
| Micro | 4,000 | 24,000 | 4000 |
| Small | 40,000 | 240,000 | 36000 |
| Medium | 100,000 | 600,000 | 36000 |
| Large | 200,000 | 1,200,000 | 36000 |
phpList opens a new SMTP connection for every message. PostShiba allows 100 new connections per SMTP username in 10 seconds, so one phpList install sends at most about 36,000 messages an hour. Larger plans still give you a bigger 24-hour cap.
When a cap is full, SMTP answers 451 4.7.0 hourly send limit reached or 451 4.7.0 daily send limit reached and does not keep the message. Select Resize on the cluster page before a campaign that would go over. See What happens at your cap.
Send your first email
- Open
config/config.phpin your phpList install and set these values. Port 587 withtlsupgrades the connection with STARTTLS. The username starts withsmtp_. The names follow phpList'sconfig_extended.php.
config.phpships withdefine('PHPMAILERHOST', '');anddefine('TEST', 1);. Replace those lines rather than adding second copies. WhileTESTis1, phpList sends nothing.- Leave
$message_envelopecommented out. phpList then uses the from address as the envelope sender, which is on your verified domain. - Add the queue settings for your plan to
config.php. Settings fromconfig_extended.phponly apply once you copy them intoconfig.php. Use the batch size from the table above.MAILQUEUE_THROTTLEwaits a tenth of a second between messages, which keeps phpList under 10 new connections a second.
- In phpList, open Config → Settings and set From email address for system messages to an address on your verified domain. phpList sends subscribe confirmations from it.
- Create a campaign and set its From Line to an address on your verified domain.
- Enter your own address next to Send Test and select it. The address must already be a subscriber. The message shows under Events in the PostShiba dashboard.
Every SMTP setting is on Send emails with SMTP.
Bounces, complaints, and unsubscribes
phpList reads bounces from a POP3 mailbox or an mbox file. PostShiba mail never reaches that mailbox, because the return-path points at PostShiba and bounce messages come back to PostShiba. phpList's bounce processing finds nothing to process, so PostShiba stops the mail instead.
| Event | What happens |
|---|---|
| Hard bounce | PostShiba suppresses the address. Later sends to it are refused with 550 suppressed. |
| Spam report | PostShiba suppresses the address the same way. |
| Soft bounce | PostShiba retries delivery. Nothing is suppressed. |
| Unsubscribe | phpList adds its own List-Unsubscribe and List-Unsubscribe-Post headers to campaigns, so PostShiba leaves them alone. phpList blacklists the subscriber. |
Suppressed addresses still look active in phpList. PostShiba refuses them, so they never reach a mailbox, but they stay in your subscriber counts. Copy them into phpList now and then to keep your lists clean.
Copy suppressions into phpList
- Export every suppressed address to
postshiba-suppressions.csv. Follow How do I export my suppression list?. It takes a read-only Support key and one script. The file has one address per line. - Log in to phpList as a super admin and open Subscribers → Manage subscribers → Suppression list.
- Leave Make suppression permanent checked, paste the contents of
postshiba-suppressions.csvinto the box, and select Continue. phpList marks the addresses unconfirmed and adds them to its blacklist, so no campaign goes to them.
Run it again after each large campaign. Pasting an address that is already blacklisted does no harm.
Troubleshooting
| What you see | What to do |
|---|---|
| phpList shows what it would send but nothing goes out | TEST is still 1. Set define('TEST', 0); in config.php. |
| The test send never shows under Events | PHPMAILERHOST is empty, so phpList used PHP mail(). Check that config.php sets it once, to smtp.postshiba.com. |
| Authentication fails | Check $phpmailer_smtpuser and $phpmailer_smtppassword. Use port 587 with PHPMAILER_SECURE set to tls. Port 465 with ssl is not offered. PostShiba accepts AUTH PLAIN only. |
550 unverified domain or 550 from header not aligned with verified domain |
Set the campaign's From Line to an address on your verified domain. If $message_envelope is set, comment it out or set it to an address on that domain. |
550 kyc_required |
Your team is pending production approval. Until then, send only to team members, live inbox addresses, and inbox forward-to addresses. See Does PostShiba require production approval?. |
550 suppressed |
The subscriber hard bounced or reported spam. Copy suppressions into phpList as shown above. |
451 4.7.0 hourly send limit reached or 451 4.7.0 daily send limit reached |
The cluster is at its cap and did not keep the message. Lower MAILQUEUE_BATCH_SIZE, or resize the cluster before the next campaign. |
451 4.4.5 too many sessions, slow down |
phpList opened too many SMTP connections on one username in 10 seconds. Raise MAILQUEUE_THROTTLE, and run only one queue process at a time. |
Next steps
- What happens at your cap
- How to manage suppressions
- How do recipients unsubscribe?
- Send emails with SMTP for every setting and reply.