v1.6.0
Backward compatible with 1.5.0 on the wire — nothing in this release removes an
operation, field, or enum value, and every addition is opt-in or additive.
Four behavior changes are deliberate and called out under "Behavior changes"
below; read that section before upgrading. One migration, a metadata-only
ALTER TABLE with a constant default — see "Upgrading".
Behavior changes
Each of these changes an outcome that 1.5.0 produced.
-
Invalid UTF-8 is rejected with
400 invalid_requestacross the/v1
surface. Previously malformed byte sequences were accepted in some fields and
surfaced as a500in others — the same class of fix as 1.5.0's NUL-byte
rejection. If you relay third-party content, validate or re-encode it as UTF-8
before sending. -
Re-registering a domain you already own is idempotent and no longer counts
against the domain cap (#819). Previously a repeatedPOST /v1/domainsfor
an already-owned domain could consume quota; it now returns the existing
registration. -
agent_countis now populated correctly in domain reads where it was
previously wrong or empty (#817, #806). Clients that special-cased the empty
value can drop the workaround. -
send_atsurvives a review hold (#838). A scheduled send that a
protection policy holds for review keeps its schedule when approved: it fires
at the originalsend_at(or immediately if that time has passed) instead of
silently converting to an immediate send. Self-sends withsend_atare
guarded consistently.
API
-
reply_toaccepts a list of addresses (#831) — everywhere a single
reply-to was accepted: send, reply, and forward, across the API (oneOf
widening, verified backward-compatible), both SDKs, the CLI (--reply-tois
repeatable), and MCP. Single-address requests are unchanged. -
Operator-configured outbound footer (#839) — a new optional
outbound_footerconfig block appends an operator-supplied footer (text +
HTML, RFC 3676 signature delimiter) to outbound mail at composition time,
gated per account via a newaccount_limits.outbound_footer_enabledcolumn
plus a row-less default. Fully inert unless configured: self-hosted
deployments see zero change. Useful for AI-disclosure footers or hosted
branding. The footer is applied inside the DKIM-signed body, is excluded for
self-send loopback delivery and non-standard account classes, and resolves at
approval time for review-held mail (including TTL auto-approval). -
/mcpserves a landing page and the docs shipllms-full.txt(#807) —
a browser hitting the MCP endpoint gets oriented instead of a protocol error. -
405responses carry anAllowheader listing the methods the resource
supports.
Dashboard
Message-view and settings fixes (#834, #820, #810, #808) and design-token
cleanup — no functional surface changes.
Observability
- Queue-dwell metrics exclude scheduled sends waiting for their fire time
(#818) — backlog alerts no longer count mail that is supposed to be
waiting.
Publishing
- The CLI now publishes on its own
cli-v*tag (#796), removing the
npm-ordering race between@e2a/cliand@e2a/sdkon release day.
Upgrading
- One migration,
095_account_limits_outbound_footer.sql: adds a boolean
column with a constant default toaccount_limits— metadata-only, no table
rewrite, noCONCURRENTLYindex builds, safe at any size. Auto-applied on
startup as usual. - The
outbound_footerconfig block is optional and defaults off; no config
changes are required. - SDKs/CLI: new releases of
@e2a/sdk,e2a(PyPI), and@e2a/cliaccompany
this release for thereply_tolist support; existing versions continue to
work unchanged.