Send an email
Being rolled out. The interface described here is the one of the next release: it may still change, and may not be enabled on your tenant yet.
E-mails are sent from templates you declare: no free-form messages.
Your tenant can send transactional e-mails (welcome, notification, confirmation) from its generated APIs and from the console. Three objects of the mail.stackngo.io group describe sending: a provider (the SMTP account), a sender (the From address) and a template (subject and body).
Prerequisites
- A session on your tenant (
sng tenant use acme) and themail:writeright to declare,mail:sendto send (managed policiesreadwriteoradmin). - An SMTP account at your mail host (port 465 or 587, TLS) and its password, stored in a secret of your tenant.
- Access to the DNS zone of the sending domain.
1. Declare the provider, the sender and the template
apiVersion: mail.stackngo.io/v1alpha1
kind: MailProvider
metadata:
name: main
spec:
host: smtp.example.com
port: 587
tls:
mode: starttls
auth:
username: notifications@example.com
passwordSecretRef:
name: smtp-main
---
apiVersion: mail.stackngo.io/v1alpha1
kind: MailUser
metadata:
name: notifications
spec:
address: notifications@example.com
providerRef:
name: main
---
apiVersion: mail.stackngo.io/v1alpha1
kind: MailTemplate
metadata:
name: welcome
spec:
lang: fr
subject: "Bienvenue {{.Prenom}}"
text: "Bonjour {{.Prenom}}, votre compte est prêt."
variables:
- name: Prenom
example: Camille
sng apply mail.yml
You get the same result in the console, E-mails page: Providers, Templates and Senders tabs.
2. Verify the sending domain
A sender only sends once its domain is verified. In the console, open the sender: the page lists the DNS records to publish, with their state.
| Check | What is needed |
|---|---|
| Ownership | A TXT record shown by the console, unless the domain is already in a zone of your tenant |
| SPF | A record that authorizes your provider |
| DMARC | A _dmarc record (the console suggests a value) |
| DKIM | Your provider's selectors, if declared in domainAuth |
Publish them in your zone (see Records), then click Verify. The sender is ready when its Ready condition is True.
3. Send a test e-mail from the console
On a ready sender, Send a test e-mail sends a trial message to an address of your choice. The Latest messages list shows each message's status (queued, sent, failed) and an error code if any. It never shows the message body.
4. Send from a generated API
In the GeneratedAPI, designate the sender and the templates the API may use:
spec:
mail:
senderRef: notifications # name of a MailUser of your tenant
templates: [welcome] # names of MailTemplate objects of your tenant
The API only sends these templates from that sender. While the sender or a template is not ready, the GeneratedAPI stays Synced=False with reason MailNotReady.
A message gives the template, the sender, the recipients and the value of each variable:
{
"template": "welcome",
"from": "notifications",
"to": ["camille@example.com"],
"variables": {"Prenom": "Camille"}
}
The response says the message was accepted (queued). Sending twice with the same Idempotency-Key header produces one message.
Limits
| Limit | Value |
|---|---|
| Recipients per message | 50 |
| Messages per hour to the same address | 10 |
| Provider rate | limits.perMinute (60 by default, 120 at most) |
| Providers per tenant | 5 |
| Size of a variable value | 4 KiB |
Beyond these, sending is refused with a rate_limited or quota_exceeded error and a delay before retrying.
Troubleshooting
| Symptom | Likely cause |
|---|---|
Sending refused, sender_not_ready | The domain is not verified or the provider is not Ready |
Reachable=False, category auth | Username or password refused by the SMTP server |
Reachable=False, category tls | Wrong port/mode pair (465 with implicit, 587 with starttls) or invalid certificate |
template_invalid | A variable is used but not declared, or the reverse: read the template's Valid condition |
forbidden | The mail:send right is missing on the sender or the template |