Changelog
User-facing changes. Operator-only internals are omitted.
2026-10-20
Pause marketing email
- Pause: a recipient can pause marketing campaigns for 30, 60 or 90 days. The contact stays subscribed, campaigns skip it until the end date, and sending resumes by itself when the date passes. Transactional email is not affected. Only the recipient can set a pause; the dashboard and the API cannot.
- Dashboard: paused contacts show a Paused until badge in Audience, with a Paused filter. The contact API returns a nullable
paused_until. - API: the public portal accepts
pause_days(30, 60 or 90) andresume. SeePOST /api/public/portal.
Preference page
- One page: status, topics, pause and the last emails a recipient received (subject and date only) in one place. Unticking every topic and saving asks for an optional reason and unsubscribes from all marketing email. An unsubscribed recipient comes back with the same button.
- Addresses that cannot receive mail (bounced, complaint, blocked by the sender, not confirmed) see their status and cannot change anything.
- Test sends: the links in a campaign test mail open the real pages in preview mode with a banner. Nothing is recorded, and a gateway that follows the unsubscribe link of a test mail unsubscribes nobody.
- Limits per contact: writes on the page are limited per contact, not per address, so a security gateway that opens every link no longer locks real recipients out.
- Webhook:
unsubscribe.link_unsubscribefires when a recipient unsubscribes through the page. See Webhooks.
Preference page language
- Languages: the preference page and the unsubscribe pages are available in English and German. A page opens in the contact's own language, then the workspace's default communication language (Settings, Legal), then English. The unsubscribe pages no longer mix German and English on one page.
- Setting the language: set
languageon a contact (dashboard contact panel orPATCHon the contact) anddefault_languagefor the workspace (PATCH /api/practices/{id}/compliance). Regional tags such asde-ATare reduced tode. - Default: workspaces start on English, as before. More languages are added once the text is reviewed.
2026-10-18
Service levels without numeric targets
- Service levels: the service levels page describes how the platform is monitored, how incidents are communicated and how to reach support. It no longer states an availability percentage or fixed response times. What is measured stays visible on the status page.
2026-10-17
Checkout and platform admin
- Checkout in the dashboard: Settings, Billing lists the plans with a live checkout and a Choose button. Payment, renewals, invoices and VAT are handled by the merchant of record. A running subscription is changed in the billing portal, never through a second checkout.
- Status page and service levels: live component health, 90 day availability and incident history at
/status, with service levels for monitoring, incidents and support. - Second factor: turn on an authenticator app in Settings. Password and email-code sign-in then ask for the code. See Second factor.
- Single sign-on and SCIM (Compliance plan and higher): connect an OpenID Connect provider after proving your email domains, optionally require it, and provision members and roles with SCIM 2.0. See Single sign-on and SCIM. SAML is available on request.
- Platform admin page: operators get one place for the waitlist, access codes and prize grants, production access approvals, user entitlements, workspaces, abuse reports and the job queue.
2026-10-16
Sandbox, access codes and time-limited plans
- New workspaces start in a sandbox: mail goes only to addresses you verified, and broadcast is locked. After 20 clean deliveries to your own addresses, a complete Impressum and authenticated DNS, you can request production access. A person reviews it. Warm-up starts at day 0 after approval. Existing workspaces are not affected. See Getting started with the sandbox.
- Access codes let invited teams skip the waitlist wait. Admins issue a code with a plan and duration and can provision many addresses at once.
- Time-limited plans end on a set date, with a reminder 14 days before and an automatic return to Starter afterwards. A printable certificate is available under Billing.
- Fixed outdated plan names in the roles message and the volume plans page.
2026-10-15
Plans: six paid tiers with list prices, no free tier
- The public ladder is now six paid tiers with list prices, exclusive of VAT:
- Starter 19 EUR, 10,000 emails / month
- Growth 49 EUR, 50,000 emails / month
- Pro 99 EUR, 250,000 emails / month
- Agency 299 EUR, 750,000 emails / month
- Compliance from 499 EUR, 1,000,000 emails / month
- Enterprise on request
- There is no free plan and no free monthly allowance. Access after the sender review starts on Starter, and a cancelled workspace falls back to Starter unless agreed otherwise.
- Every send counts toward the calendar-month UTC cap. On Starter and Growth, hitting the cap pauses all sending until the next month or a plan change. On Pro and above, hitting the cap pauses marketing while transactional mail keeps sending.
- Enterprise volume, workspaces, and contracts are arranged on request. Custom caps can be agreed in writing.
- Landings, legal pages, SEO / JSON-LD, and the dashboard now use only these tier names. Older tier ids are no longer shown in the UI or in public copy.
2026-09-24
From display name reaches the provider
- The mail platform copies its From field over the raw header. That field now includes
from_name, so the delivered From isName <address>instead of the bare address. - A name of words stays unquoted. Comma, period, and quotes are quoted. Non-ASCII names use a UTF-8 Q encoded-word.
GET /api/practices/{id}/messages/{messageID}expects the Werkmail message UUID. The provider message id returns400bad_id(retryable false).
Sender name, recipient detail, and Domain Connect
GET /api/practices/{id}/reports/recipients/{email}returns the same send rows as the list. An unknown address is200 []. The body is nevernull.GETandPOST /api/practices/{id}/domain-connect/cloudflareboth return the apply URL.- Workspace
from_name(defaultpublic_name) is the From display name. Override it per send withfrom_name.fromstays a bare address (invalid_from, retryable false). - The unsubscribe footer uses that display name.
- System footer links do not add the content-score reason
many links. PATCH /api/practices/{id}/complianceis PATCH only.GET /api/practices/{id}/messagesuses the same filters as/messages/search.
API catalog matches the live router
/api/referenceand/openapi.yamlnow list every shipped route and HTTP method, including campaigns, journeys, contacts, templates, segments, flat suppressions, and operator routes.GET /openapi.jsonreturns JSON.GET /openapi.yamlreturns YAML.GET /api/referenceandGET /api/reference.mdare public on the product origin.GET /api/practices/{id}/reports/recipientsreturns one row per recipient and send. An empty workspace returns[].- DMARC
checks.dmarc.okis true only forp=quarantineorp=reject.p=noneis not ok, including whensp=quarantineis also set. - Team tokens include
audit.viewandconsent.view.GET /api/projects/melistsscopes. A project token on/auditor/consent-audit/exportgets 403forbiddenand a hint that names the missing scope. POST /api/practices/{id}/send-testwithkindrealreturns 422suppressedfor a suppressed address, same asPOST /api/practices/{id}/send.- Agents should branch on
code, retry only whenx-error-codessaysretryable: true, and treat a send as accepted only on 202 withmessage_idandid. scheduled_aton a single send is supported.not_supportedmeans the process cannot serve that call.
2026-08-29
Universal Werkmail attribution footer
- Every outbound message — transactional, broadcast, quality / mail-tester test sends, and API sends — now includes a subtle footer:
- This email was securely sent by Werkmail - European email infrastructure
- The full sentence is one link to the public product origin.
- HTML: 12px,
#888888, Arial/Helvetica, centered, underlined link (visible, not hidden). - Plain text: sentence plus URL on the next line.
- Idempotent via HTML marker
<!-- werkmail-powered-by -->and phrase detection.
Plans: sales contact only (no public list prices)
- Removed euro amounts and self-serve checkout from landings, legal pages, SEO/JSON-LD, and public docs.
- Copy explains that every customer goes through an in-depth sender review for protection and reputation before a plan is assigned.
- Primary CTA: Contact sales (
info@sebastianhochreiter.at). GET /api/public/siteplan catalog returns volume caps only (checkout: falsefor all tiers).- Dashboard Settings → Billing: subscribe buttons replaced with contact sales; existing Creem customer portal remains for active subscriptions.
Fix: blank homepage after deploy
- Missing
SUPPORT_EMAILimport inLanding.tsxcaused a runtimeReferenceErrorand white screen on/. Fixed inf22903d.
2026-08-22
Lettermint brand
- Compare page and drop-in base use Lettermint:
/compare/lettermint,/api/compat/lettermint. /api/compat/lettermindremains a short alias.
Drop-in send APIs
- Native send accepts Postmark and Resend JSON shapes (PascalCase, comma-separated
to, tag objects, header arrays). - Failures include
codeandhinton the send envelope. POST /api/emailssends with the workspace from a team/project token.- Drop-in bases:
/api/compat/resend,/api/compat/postmark,/api/compat/lettermint(/api/compat/euand/api/compat/lettermindare aliases). Docs:/api/compat.
Compare guides (EU transactional)
/compare/ahasend,/compare/eusend,/compare/lettermint, and/compare/eu-transactional(category page for thin EU send APIs).- Docs header search: type to filter titles, descriptions, and headings;
/focuses the box; works on mobile. /regulated— public product thesis: enforced isolation and consent for EU practice / regulated transactional mail; marketing automation stays “good enough”; volume plans named Termin / Praxis / Gruppe.- Audit log CSV:
GET /api/practices/{id}/exports/bi?kind=audit(also on the dashboard Audit tab).
Compare guides
/comparehub plus pages versus Postmark, MailerLite, Resend, Brevo, Sender.net, and a raw outbound sending API.- Honest “they win / we win / stay / switch” — not a feature-for-feature scorecard.
- Some infrastructure brands are omitted on purpose; Frankfurt DIY transport is covered as vs a raw outbound API.
Broadcast cockpit
- Visual block editor (heading, text, button, image, divider, spacer) on campaigns and templates.
- A/B tests send a sample first, then auto-pick or manually pick a winner and queue the rest.
- Segment rule builder in CRM; campaigns can target a segment.
- Conditional content:
{{#if field}}/{{#unless field}}on bulk and campaign sends. - Template library with practice presets (termin, recall, DOI, newsletter, feedback) and compliance check.
- Journeys: contact created, DOI confirmed, or after a message kind (seed: Termin → Recall).
- Deliverability extras: bounce reasons, content-score history, channel performance, BI CSV export.
- Practice kinds, consent channels, and a PVS hub (ICS, inbound hook, community recipes).
Unsubscribe confirm page
- Optional workspace setting: footer unsubscribe opens a Werkmail confirm page, then a reason survey.
- Suppressions shows a reason chart and free-text answers.
- Mail-client one-click unsubscribe is unchanged.
Raw source and branding
- New guide: what View Source shows (Message-ID, Return-Path, List-Unsubscribe, branded DNS) versus the platform DKIM /
Received/Feedback-IDlines that cannot be renamed. - SMTP relay documented as the only way to drop platform signatures entirely.
Privacy document
- The human-readable privacy policy is a standalone HTML document. It is excluded from the docs site,
llms.txt, sitemaps, and crawler allow-lists.
Public documentation site
- Canonical docs host at
docs.+ brand apex, served from the same app as the product. - Server-rendered HTML (no JavaScript required to read a page).
- Raw Markdown at the same path with a
.mdsuffix. /llms.txtand/llms-full.txtfor language-model crawlers.- Docs-specific robots and sitemap.
Discovery (marketing origin)
robots.txtallows major search and AI crawlers.sitemap.xml,/llms.txt,/humans.txt, and/.well-known/security.txt.- Per-path title, description, canonical, Open Graph, and JSON-LD on public pages.
- Favicon, Apple touch icon, and social share image.
2026-08-21
App navigation
- Reloading the dashboard keeps the current page (
/domains,/projects,/emails/messages,/settings, and selected workspace).
Add a sending domain
- Dedicated create form so “Add domain” no longer jumps to another tenant’s DNS records.
- DNS panels scroll into view only when you open them.
Messages and onboarding
- Message search matches stored fields correctly.
- Four-step onboarding no longer hides the create-domain form after a tenant already exists.
DNS and brand records
- Branded DNS targets with a fallback when aliases are not yet live.
- Cloudflare BIND / zone export from the DNS panel.
- DKIM alias harvest so Check DNS accepts both brand aliases and working targets.
Abuse
- Inbound abuse mailbox on the inbound host (never apex MX).
- Operator replies as plain text from Settings → Abuse reports.
- Ticket pipeline: open → investigating → closed, with reporter stage mail.
Earlier 2026
- Team and project API tokens (
wm_team_…,wm_proj_…). - Signed outbound webhooks (
X-Werkmail-Signature). - Inbound send hooks (
X-Werkmail-Hook-Secret). - Batch (500) and templated bulk send.
- Content reputation gate and inbox-risk dry-run.
- List-Unsubscribe on every send when the public origin is HTTPS.
- Scoped suppressions (team / project / route).
- Supporter plan (€5 / 1,000 emails) via Creem checkout.