Skip to main content
All configuration is by environment variable. See .env.example for the full set.

Core

SMTP and IMAP

Sending

Security and tracking

Leave TRUST_PROXY_HOPS at 0 unless the service genuinely sits behind that many proxies — trusting more hops than exist lets a client spoof its IP past the tracking rate limit.

Webhooks

Multiple subscriptions live in a webhook_subscriptions table, each with its own URL, HMAC secret, and event filters supporting wildcards ("*", "flow.*", or exact names). Subscriptions can be scoped to a tenant. The legacy environment variables below seed a default subscription on first start.

Delivery headers

Every outbound POST carries:
The signature value is prefixedsha256=abc123…, not the bare hex. Strip the sha256= before comparing, or the comparison always fails.
Compute the HMAC over the raw request body. Re-serialising parsed JSON will not reproduce the same bytes. Events emitted:
  • Transactionalmessage.sent, message.failed, message.bounced, inbox.received
  • Marketing lifecyclecampaign.started, campaign.finished, profile.subscribed, profile.unsubscribed, message.opened, message.clicked, flow.run.started, flow.run.completed
Payloads are enriched with context: inbox.received carries the conversation, mailbox, domain, and tenant plus attachment metadata; bounce events carry the recipient; engagement events carry recipient and campaign.
Webhook targets are SSRF-guarded — validated at create time, re-resolved before each send, with loopback, private, link-local, and metadata addresses refused and redirects disabled.

Inbound adapters

Managed domains and conversations

Observability

Bulk import limits

POST /v1/profiles/bulk (JSON array), POST /v1/profiles/import (CSV body), and POST /v1/lists/:id/members/bulk are each capped at 1000 records per request.

Next steps

Conversations

The triage surface these settings configure.

MCP server

Driving the inbox from an agent.

Overview

What StateSet Mail is, before the variables.
Last modified on August 29, 2026