# Email sending

> Connect Amazon SES, Postmark, SendGrid, Mailgun or Resend so testimonial request emails are sent from your own address. Part of Business.

[Request emails](/docs/testimonials/requests) are sent through your own
email provider. You connect an account you already have with an API
key, and every request email of the site leaves through it: from your
own address, with replies coming to you.

Privatus Analytics never sends a request email from an address of its
own. Until a provider is connected, nothing is sent.

It is under **Testimonials** in the site's sidebar, then **Settings**,
then **Email sending**. It needs the `sites.manage` permission and the
**Business** plan. Sharing a form's link, embedding it, the popup and
the QR code work on every plan and need no email provider.

## What you need

- An account with one of the five providers below, with a sender
  address or a sending domain that the provider has verified.
- An API key of that account. Each provider's section says where to
  find it and which permissions it needs.
- A postal address. It is shown in the footer of every email, because
  email laws such as CAN-SPAM ask a sender to give one.

## Connect a provider

**Connect a provider** opens one form.

| Field | What it does |
|---|---|
| Email provider | Amazon SES, Postmark, SendGrid, Mailgun or Resend. Only the fields of the one you choose are shown |
| The key fields | The API key, and for Amazon SES an access key ID and a secret access key. See your provider below |
| From name | The name people see. A request can use its own sender name with the same address |
| From address | The address every request email is sent from. It must be verified with your provider |
| Replies go to (optional) | One address for every reply. Left empty, replies go to the team member chosen on each request |
| Postal address | Up to 6 lines, shown in the footer of every email. Required |

**Check and connect** asks your provider whether the key works and, where
the provider can tell us, whether the From address is verified. No email
is sent for this. If the provider refuses the key, the page says what it
said and nothing is stored.

The key is stored encrypted. It is never shown again: the page shows
its last four characters only. To change it, choose **Edit** and paste
a new one. Leaving the key field empty keeps the stored key.

Connecting is done in the web app only. There is no API operation and
no MCP tool for it, and an API token cannot connect, change, test or
disconnect a provider.

## The page

| Part | What it shows |
|---|---|
| Badge | **Active**, **Paused** or **Not used** (the plan does not include email sending) |
| Sender | The provider, the last four characters of the key, the From name and address, where replies go and the postal address |
| Last email sent | When the last email left through this connection |
| Bounces | When bounces were last checked, or that this key cannot read them |
| This month | How many request emails the site has sent this month, against its monthly limit |
| Bounces and complaints found | The last ones, with the address and the request |

- **Send a test** sends one short email through your provider to your
  own address, and to nobody else. It shows the From, the reply address
  and the footer as every request email will have them.
- **Check again** asks the provider whether the connection works.
- **Edit** changes the sender details or the key.
- **Disconnect** deletes the stored key for good. Request emails that
  are queued or scheduled wait until a provider is connected again.
  Nobody is dropped.

## What is sent and what is read

| | |
|---|---|
| Sent to your provider | Each request email: the recipient's address, your From name and address, the reply address, the subject, the text and the unsubscribe headers. A test email goes to your own address |
| Read from your provider | Recent bounces and spam complaints, to find the ones about request emails sent from here |
| Stored | Your key (encrypted), the sender details and the postal address. For each email sent, the provider's id of the message, with no address |
| Never stored | Anything in your provider account that is not about a request email sent from here. A bounce of other mail is ignored the moment it is read |

Your email provider works for you, under your own agreement with it. It
is not a subprocessor of Privatus Analytics.

Open and click tracking of the provider is switched off for these
emails where the provider lets a sender do so (Postmark, SendGrid,
Mailgun). Opens are counted by our own small image, which records no IP
address and no device. See
[what the open counter records](/docs/testimonials/requests#what-the-open-counter-records).

## The monthly limit

Each site can send **10,000 request emails a month** through its
provider. Every request email counts, first emails and follow-ups. A
test does not.

At the limit, sending for the site waits until the 1st of the next
month and then continues by itself. Nobody is dropped. The Requests tab
and this page say so, with the date.

The limit is set by us for each site, and you can see it on this page.
To raise it, write to hello@privatusanalytics.com.

Your provider has limits of its own. When it says an email cannot be
taken right now (a rate limit, a daily quota), that email is tried again
later.

## Bounces and spam complaints

We ask your provider for recent hard bounces and spam complaints about
every 15 minutes, with the same key, and only while the site has sent
request emails lately.

A bounce or complaint about a request email does what it has always
done: the person is marked Bounced and gets no further email, and after
a hard bounce or a complaint the address goes on the opt-out list for
every workspace. See
[Bounces](/docs/testimonials/requests#bounces).

A key that can send and cannot read bounces still works. The page then
says "This key cannot read bounces", and a bounce is not seen here. Use
a key with the permissions listed for your provider to avoid that.

## When the connection stops working

A connection is **paused** when your provider says that nothing will get
through until someone acts:

- the key is refused (deleted, replaced or not active),
- the key is no longer allowed to send,
- the From address or its domain is no longer verified,
- the provider closed or suspended the account, or has not approved it.

While it is paused, nothing is attempted through it. The site's request
emails wait. They are not sent from another address, and nobody is
dropped. The member who connected the provider and the workspace's
owner get an email saying which site, which provider and why.

Fix it with your provider, or paste a new key under **Edit**, then
press **Check again**. The emails that waited go out, within the monthly
limit.

These do not pause a connection: a rate limit, a provider outage, and
one address the provider will not send to. The first two are tried
again later. The last is recorded on that one email.

## Amazon SES

Use an IAM user made for this, in the AWS region you send from.

| Field | Where to find it |
|---|---|
| Access key ID, Secret access key | AWS console, IAM, your user, **Security credentials**, **Create access key** |
| Region | The region where your sender address or domain is verified |

The policy the user needs. These are the actions used, and no other:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ses:SendEmail",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ses:GetAccount",
        "ses:GetEmailIdentity",
        "ses:ListSuppressedDestinations"
      ],
      "Resource": "*"
    }
  ]
}
```

- `ses:SendEmail` sends. AWS documents it together with
  `ses:SendRawEmail` without saying whether this kind of email needs
  both. If AWS refuses to send with this policy, add `ses:SendRawEmail`
  to the first statement.
- `ses:GetAccount` and `ses:GetEmailIdentity` are how the key and the
  From address are checked without sending.
- `ses:ListSuppressedDestinations` reads bounces and complaints. Without
  it emails are still sent, and bounces are not seen.

Amazon SES has no list of bounces. We read your **account-level
suppression list**, which holds the addresses that hard bounced or
complained. It must be enabled: in the SES console, under
**Configuration**, **Suppression list**, **Account-level settings**,
with both reasons ticked. Accounts opened after November 25, 2019 have
it on by default. Gmail does not report spam complaints to Amazon SES,
so those are not seen.

An account still in the SES sandbox can only send to verified
addresses. Such a recipient is recorded as not sent, and the connection
keeps working.

## Postmark

| Field | Where to find it |
|---|---|
| Server API token | Postmark, your server, the **API Tokens** tab |
| Message stream (optional) | The ID of the stream to send on. Empty uses the default transactional stream, `outbound` |

Postmark has one kind of server token, which sends and reads bounces.
There is no send-only token. Use a server of its own for request emails
if you want to keep them apart from your other mail.

The From address must be a confirmed Sender Signature, or at a domain
you verified in Postmark.

## SendGrid

| Field | Where to find it |
|---|---|
| API key | SendGrid, **Settings**, **API Keys**, **Create API Key**. The key is shown once |
| Region | Global, or EU for a key of an EU regional subuser |

Choose **Custom Access** and switch on:

- **Mail Send** (the scope `mail.send`), to send,
- **Suppressions** (the scopes `suppression.bounces.read`,
  `suppression.blocks.read` and `suppression.spam_reports.read`), to
  read bounces and complaints.

A key with only Mail Send works, and bounces are then not seen.

The From address must match a verified Sender Identity or an
authenticated domain.

## Mailgun

| Field | Where to find it |
|---|---|
| API key | Mailgun, **Account Settings**, **API Keys** |
| Region | US or EU: the region the sending domain was created in |
| Sending domain | The domain you send from, such as `mg.example.com` |

Use an account API key, or on plans with roles a key with the
**Developer** role. A **Domain Sending Key** does not work here: it can
only send, so it cannot be checked when you connect and cannot read
bounces.

The From address should be at the sending domain, and the domain must
be active in Mailgun.

## Resend

| Field | Where to find it |
|---|---|
| API key | Resend, the **API keys** page, **Create API Key**. The key is shown once |

Choose **Full access** so bounces and complaints can be read. A key with
**Sending access** works, and bounces are then not seen.

The From address must be at a domain you verified in Resend.

## Good to know

- One provider per site. Another site of the workspace has its own
  connection and its own monthly limit.
- On a plan without email sending a connection is kept and not used.
  Request emails wait, and the page says so.
- The unsubscribe link and the opt-out list are ours and work the same
  with every provider. An address on the opt-out list is never sent to,
  through any provider.
- A purchase connection asks buyers with request emails, so it needs a
  provider connected here too.
