Skip to content

Email

A server sends mail through one email service in tablewalk.json; an App never names a credential or an address to send from.

{ "name": "mail", "kind": "email", "url": "smtps://smtp.example.com:465",
"from": "Compass <[email protected]>",
"auth": { "username": "${SMTP_USER}", "password": "${SMTP_PASSWORD}" } }
url What it does
smtps://host:465 TLS from the first byte.
smtp://host:587 Must offer STARTTLS, or nothing is sent; "insecure": true allows a plain relay on a trusted network.
log: or log:mail.log Sends nothing: each message is one JSON line on stdout, or in the file (beside the config file). For development and tests.

Credentials are ${VARIABLE} references, expanded when the transport opens and never logged. The host resolves through the same network rules as every other connection; link-local addresses are refused unless "allowLinkLocal": true.

  • Notifications a notify rule marks email: true, and its mentions (notifications).
  • A status check’s step-up code and a form’s email proof (commands).
  • Sign-in links: account verification on sign-up, password resets, and a note when an application is added to an account.

A server whose App asks for any of these and names no email service does not start.

A notice’s email is queued in the write’s own transaction, beside the notice (the inbox store’s __tablewalk_inbox_mail), and sent once the write has committed: a rolled-back write queues nothing, and nothing is sent while a transaction is open. The sender checks each message again as its recipient: an address with no account, an account that turned email off and a record its grants cannot read are dropped unsent. A failed send is tried again after a minute, doubling to an hour; after eight tries, or a refusal for good, the row is kept as failed with the reason. A send never fails the write.