Email

An app's email goes out as the app — through your own mail server, in the app's branding, logged in the app.

When your app sends email (an invoice reminder from a handler, a sign-in code to one of its users), it goes out as the app:

  • from your own mail server, through an email connection your organization set up, on your domain's reputation rather than Authoric's;
  • in the app's look: its name, logo, colors and footer. Nothing of Authoric's appears in an app's mail;
  • into the app's own email log, where you can preview every message exactly as it was sent, with secrets masked.

The pieces fit together like this:

PieceWhereWhat it is
Email connectionIntegrations › Email (your organization)One of your mail servers (SMTP), tested, with the addresses it may send as
GrantApp integrations › Email (the app)Lets one app send through a connection, under an alias its handlers write
BrandingApp settings › Branding (the app)How the app's email looks
Email logApp logs › Email (the app)Every message the app sent, as sent

An app sends nothing until it is granted a connection. That is deliberate: deny by default.

1. Connect a mail server

Any provider that offers SMTP works: Postmark, SendGrid, Mailgun, Amazon SES, Google Workspace, Microsoft 365, or your own server. Under Integrations › Email, choose Connect a mail server and give it:

FieldNotes
NameFor you: "Postmark (transactional)".
Mail server and portAn SMTP submission port: 587, 465, 25 or 2525. A host that resolves to a private or reserved address is refused (EMAIL_HOST_BLOCKED).
SecuritySTARTTLS (port 587, the usual choice) or TLS (port 465). Unencrypted connections are for development mail catchers only.
Username, Password or API keyEncrypted when stored, and never shown again.
SendersThe addresses this connection may send as: an address (hello@example.com) or a whole domain (@example.com).
Default senderOne of the senders, used when a handler names none.
Reply-toOptional. Where replies go when nothing else says.

Test and connect logs in to the server before anything is stored; a server that refuses is reported with its reason (EMAIL_CONNECTION_FAILED). Test again can also send a short test message to an address you give.

Editing where or how a connection connects returns it to untested. Apps keep their grant, but nothing sends through it (EMAIL_CONNECTION_UNVERIFIED) until you test it again. Removing a connection stops every app it was granted to from sending through it.

Connecting and granting mail servers is the Email connections permission; removing one, or an app's grant, is Disconnect email connections. Your organization's owner holds both; give them to others in Access › Policies.

2. Grant it to an app

Open the app, go to App integrations › Email, and choose Add a sender. Pick the mail server and an alias: the name the app's handlers will write.

await sdk.sendEmail("billing", { to: invoice.billing_email, subject: "Your invoice", body: ["…"] });
  • An alias is lowercase letters, digits and underscores, starting with a letter, and unique in the app (EMAIL_ALIAS_IN_USE). Revoke it to point it at another connection.
  • One grant is the app's default. The first grant an app gets becomes it; Make default moves it. sdk.sendEmail(message) with no alias uses the default, and so do the app's own sign-in, password-reset and invitation emails (see Branding and the app's own email).
  • A handler may name the connection by its uid instead of an alias. The page shows both.
  • Revoke removes a grant. If it was the default, the oldest remaining grant becomes the default.
  • Only a tested connection can be granted.

Because handlers write the alias, not the connection, you can move the app to another provider by granting the new connection under the same alias. No code changes.

3. Send

From a handler, sdk.sendEmail. It needs the sdk:external_email capability, which is deny by default, so the handler's author (and its approver) must hold it. Everything about the message, placeholders and duplicates is in Sending email.

The email log

App logs › Email lists every message the app sent through its own connection: who it was to, the subject, its status (sending, sent or failed, with the server's reason), when, which handler or job sent it, and each message's organization. Opening a message shows it exactly as its recipient got it, in a sandboxed preview, with its plain-text part and details.

  • Values written as {{secret}} placeholders appear as ••• in the log. Everything else is kept as sent. See placeholders.
  • The log row is written outside the handler's transaction. A handler that sends and then rolls back has still sent, and the log says so.
  • Reading the log is its own permission (Read sent email), separate from reading request logs, because message bodies are your customers' personal data.
  • Messages are kept for your plan's data-retention window, then deleted, bodies and envelope together.

Errors

CodeStatusWhen
EMAIL_NOT_GRANTED403The app has no grant by that alias, or no default.
EMAIL_CONNECTION_UNVERIFIED409The connection changed and has not been tested since.
EMAIL_FROM_NOT_ALLOWED403from is not one of the connection's senders.
EMAIL_CONNECTION_INVALID400The server settings are not usable (host, port, security).
EMAIL_SENDER_INVALID400A sender is not an address or a domain, or the default sender is not one of them.
EMAIL_HOST_BLOCKED400The mail host resolves to a private or reserved address.
EMAIL_CONNECTION_FAILED502The server could not be reached, refused the login, or failed the secure connection.
EMAIL_ALIAS_IN_USE409The alias already names another connection in this app.

Sending has its own errors; see Sending email.

Next

On this page