SapixDBSapixDB/Docs
Home
Add-on

Mail Add-on

Send transactional email from any agent with a single API call. Self-hosted SMTP delivery. Every message is a signed strand record — full audit trail, no cloud intermediary.

✉ One env var to activate: SAPIX_MAIL_ENABLED=true
Works without SMTP configured — messages are stored as queued for local testing.

Enable

Environment variables
SAPIX_MAIL_ENABLED=true

# SMTP delivery (optional — without this, messages are stored as "queued")
SAPIX_MAIL_SMTP_HOST=smtp.example.com
SAPIX_MAIL_SMTP_PORT=587                # default 587 (STARTTLS)
[email protected]
SAPIX_MAIL_SMTP_PASS=your-smtp-password

# Sender identity
[email protected]
SAPIX_MAIL_FROM_NAME="Your Application"  # default: SapixDB

Sending Email

TypeScript — from an agent or backend
const res = await fetch("http://localhost:7475/v1/mail/send", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${apiKey}`,
  },
  body: JSON.stringify({
    to: ["[email protected]"],
    subject: "Your session is complete",
    body: "The DBA Agent has finished the daily health check.",
    html_body: "<p>The DBA Agent has finished the <strong>daily health check</strong>.</p>",
    // from: "[email protected]",  // optional — uses SAPIX_MAIL_FROM_ADDRESS by default
  }),
});
const { id, status } = await res.json();
// status: "sent" | "failed" | "queued"
console.log(`Message ${id}: ${status}`);
Python — from a monitoring agent
import httpx

async with httpx.AsyncClient() as client:
    r = await client.post(
        "http://localhost:7475/v1/mail/send",
        headers={"Authorization": f"Bearer {api_key}"},
        json={
            "to": ["[email protected]"],
            "subject": "⚠ Table bloat alert — users table at 78%",
            "body": (
                "The DBA Agent detected critical table bloat on the users table.\n"
                "Auto-VACUUM has been scheduled for the next maintenance window."
            ),
        },
    )
    print(r.json())  # {"id": "msg_...", "status": "sent"}

Every call stores the message in the agent's graph meta before attempting delivery. If SMTP is unreachable, the status is set to failed but the message is retained and can be inspected via the API.

Integration with the Auth Add-on

When both SAPIX_AUTH_ENABLED=true and SAPIX_MAIL_ENABLED=true, magic link emails are sent automatically when a user requests POST /v1/auth/magic-link/send. No additional configuration required.

SMTP Configuration

The mail add-on uses STARTTLS (port 587). TLS certificates are verified against the system certificate store. Common SMTP providers:

ProviderSAPIX_MAIL_SMTP_HOSTPortNotes
Gmailsmtp.gmail.com587Use App Password, not account password
Mailgunsmtp.mailgun.org587Use SMTP credentials from Mailgun dashboard
Postmarksmtp.postmarkapp.com587Use API token as password
self-hosted Postfixyour-host.com587Ensure STARTTLS is configured
local test (MailHog)localhost1025No auth, no TLS — dev only
Deliverability: For production, configure SPF and DKIM records for your sending domain. Without DKIM, email from your domain may be classified as spam by major providers (Gmail, Outlook). SapixDB handles the software layer — DNS records are your responsibility.

HTTP API Reference

MethodPathDescription
POST/v1/mail/sendSend an email
GET/v1/mail/messages?limit=50List sent messages, newest first
GET/v1/mail/messages/:idGet a single message by ID

POST /v1/mail/send — Request body

FieldTypeRequiredDescription
tostring[]YesRecipient email addresses
subjectstringYesEmail subject line
bodystringYesPlain-text body
fromstringNoOverride from address
html_bodystringNoHTML body (multipart/alternative if provided)

Message status values

StatusMeaning
sentSMTP server accepted the message
failedSMTP server rejected or connection failed
queuedSMTP not configured — message stored, not delivered

Strand audit records

Payload typeTrigger
mail/sentEvery send_email() call (recorded before SMTP attempt)

PHI / HIPAA Note

Message bodies are stored in plain text in the agent's GraphIndex meta column family. If email bodies may contain PHI (patient names, diagnoses, identifiers), ensure:

  • Access to the agent is restricted with SAPIX_ROOT_KEY and scoped API keys.
  • The HIPAA add-on is enabled for blob and record encryption.
  • Where possible, send a link to a protected record rather than embedding PHI in the email body directly.

Configuration

Environment variableDefaultDescription
SAPIX_MAIL_ENABLEDfalseEnable the mail add-on
SAPIX_MAIL_SMTP_HOSTSMTP server hostname
SAPIX_MAIL_SMTP_PORT587SMTP port (STARTTLS)
SAPIX_MAIL_SMTP_USERSMTP authentication username
SAPIX_MAIL_SMTP_PASSSMTP authentication password
SAPIX_MAIL_FROM_ADDRESS[email protected]Default sender address
SAPIX_MAIL_FROM_NAMESapixDBDefault sender display name

Known Limitations

  • No retry. Failed sends are recorded as status: "failed" but not retried automatically. Re-send manually via the API.
  • No inbound email. Outbound only. Inbound SMTP is a planned future add-on.
  • No attachments. Plain-text and HTML bodies only. Reference a blob hash to link files.
  • STARTTLS only. Implicit TLS (port 465) is not yet supported.
  • No DKIM. Configure DKIM at your MTA or DNS layer.
  • Message storage is unbounded. Use the Policy Engine retention rules to clean up old messages.
→ Auth Add-on→ Chat Add-on→ HIPAA Package