# Send emails with listmonk

> Point listmonk's SMTP settings at PostShiba.

## What you'll build

A listmonk install that sends its campaigns and opt-in mail through PostShiba over SMTP. listmonk keeps your lists, templates, 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](/docs/dashboard/clusters/introduction).
- 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](/docs/api-reference/smtp-credentials).
- A verified sending domain. See [Add and verify a domain](/docs/add-a-domain). Every campaign's **From address** must be on it.
- A cluster that is ready to send (`sending_ready` is `true`).

## Install

Nothing to install. listmonk 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. listmonk's sliding window holds messages back once a set number has gone out in a period, so set it to your hourly cap.

| Plan | Emails per hour | Emails per 24 hours | listmonk sliding window (Max. messages per `1h`) |
| --- | --- | --- | --- |
| Nano | 100 | 600 | Test sends only |
| Micro | 4,000 | 24,000 | 4,000 |
| Small | 40,000 | 240,000 | 40,000 |
| Medium | 100,000 | 600,000 | 100,000 |
| Large | 200,000 | 1,200,000 | 200,000 |

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](/docs/dashboard/clusters/what-happens-at-your-cap).

## Send your first email

1. In listmonk, open **Settings** → **Settings** → **General** and set **Default `from` email** to an address on your verified domain, such as `hello@mail.example.com`.
2. Open the **SMTP** tab. Edit the enabled server, or choose **Add new**, and enter these values. The username starts with `smtp_`.

```text listmonk-smtp.txt
Host:                   smtp.postshiba.com
Port:                   587
Auth protocol:          PLAIN
Username:               smtp_9
Password:               YOUR_PASSWORD
TLS:                    STARTTLS
Skip TLS verification:  Off
Max. connections:       10
Idle timeout:           15s
```

3. Choose **Save**. Keep **Idle timeout** under `30s`. PostShiba closes a connection that sits idle for 30 seconds.
4. Open the **Performance** tab. Turn on **Enable sliding window limit**, set **Max. messages** to the value for your plan in the table above, and set **Duration** to `1h`. Save again.
5. Back on the **SMTP** tab, choose **Test connection**, re-enter the password, type your own address in **To e-mail**, and choose **Send e-mail**. The message shows under Events in the PostShiba dashboard.

If the test fails, listmonk shows the full SMTP reply under the form. Every SMTP setting is on [Send emails with SMTP](/docs/send-with-smtp).

## Bounces, complaints, and unsubscribes

Bounce emails go to PostShiba, not to listmonk. listmonk's POP3 bounce mailbox never sees them. Its SendGrid bounce webhook checks SendGrid's own signature, which PostShiba webhooks do not carry, so do not point PostShiba webhooks at it. 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 | With **Include `List-Unsubscribe` header** on in **Settings** → **Privacy** (the default), listmonk adds its own `List-Unsubscribe` and `List-Unsubscribe-Post` headers, so PostShiba leaves them alone. listmonk marks the subscriber as unsubscribed. |

Suppressed addresses still look active in listmonk. PostShiba refuses them, so they never reach a mailbox, but they stay in your subscriber counts. Copy them into listmonk now and then to keep your lists clean.

## Copy suppressions into listmonk

1. Export every suppressed address to `postshiba-suppressions.csv`. Follow [How do I export my suppression list?](/docs/knowledge-base/how-do-i-export-my-suppression-list). It takes a read-only Support key and one script.
2. listmonk's importer needs an `email` header row, and the export has none. Add it.

```sh add-header.sh
(echo email; cat postshiba-suppressions.csv) > listmonk-blocklist.csv
```

3. In listmonk, open **Subscribers** → **Import**, set **Mode** to **Blocklist**, upload `listmonk-blocklist.csv`, and choose **Upload**. listmonk marks each address as blocklisted and unsubscribes it from every list. Addresses that are not in listmonk yet are added as blocklisted.

Run it again after each large campaign. Importing an address that is already blocklisted does no harm.

## Troubleshooting

| What you see | What to do |
| --- | --- |
| Authentication fails | Check the username and password. Set **Auth protocol** to `PLAIN` and **TLS** to `STARTTLS` on port `587`. Port 465 with `SSL/TLS` is not offered. |
| The test never shows under Events | listmonk is sending through another server. On the **SMTP** tab, check that the PostShiba server is enabled and the others are off. |
| `550 unverified domain` or `550 from header not aligned with verified domain` | Set **Default `from` email** and the campaign's **From address** to an address on your verified 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?](/docs/knowledge-base/does-capsule-require-production-approval). |
| `550 suppressed` | The subscriber hard bounced or reported spam. Copy suppressions into listmonk 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. listmonk pauses the campaign once errors pass **Maximum error threshold** in **Settings** → **Performance**. Lower the sliding window, or resize the cluster, then resume. |
| `451 4.4.5 too many sessions, slow down` | listmonk opened too many SMTP connections on one username in 10 seconds. Lower **Max. connections** on the **SMTP** tab. |
| `421 4.3.2 ... idle too long` | A pooled connection sat idle for 30 seconds. Set **Idle timeout** below `30s`. See [421 4.3.2 idle too long](/docs/knowledge-base/smtp-421-idle-too-long). |

## Next steps

- [What happens at your cap](/docs/dashboard/clusters/what-happens-at-your-cap)
- [How to manage suppressions](/docs/dashboard/emails/email-suppressions)
- [How do recipients unsubscribe?](/docs/knowledge-base/how-do-recipients-unsubscribe)
- [Send emails with SMTP](/docs/send-with-smtp) for every setting and reply.
