Werkmail Docs
Contents

Platform

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) and resume. See POST /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_unsubscribe fires 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 language on a contact (dashboard contact panel or PATCH on the contact) and default_language for the workspace (PATCH /api/practices/{id}/compliance). Regional tags such as de-AT are reduced to de.
  • 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 is Name <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 returns 400 bad_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 is 200 []. The body is never null.
  • GET and POST /api/practices/{id}/domain-connect/cloudflare both return the apply URL.
  • Workspace from_name (default public_name) is the From display name. Override it per send with from_name. from stays 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}/compliance is PATCH only.
  • GET /api/practices/{id}/messages uses the same filters as /messages/search.

API catalog matches the live router

  • /api/reference and /openapi.yaml now list every shipped route and HTTP method, including campaigns, journeys, contacts, templates, segments, flat suppressions, and operator routes.
  • GET /openapi.json returns JSON. GET /openapi.yaml returns YAML.
  • GET /api/reference and GET /api/reference.md are public on the product origin.
  • GET /api/practices/{id}/reports/recipients returns one row per recipient and send. An empty workspace returns [].
  • DMARC checks.dmarc.ok is true only for p=quarantine or p=reject. p=none is not ok, including when sp=quarantine is also set.
  • Team tokens include audit.view and consent.view. GET /api/projects/me lists scopes. A project token on /audit or /consent-audit/export gets 403 forbidden and a hint that names the missing scope.
  • POST /api/practices/{id}/send-test with kind real returns 422 suppressed for a suppressed address, same as POST /api/practices/{id}/send.
  • Agents should branch on code, retry only when x-error-codes says retryable: true, and treat a send as accepted only on 202 with message_id and id.
  • scheduled_at on a single send is supported. not_supported means the process cannot serve that call.

2026-08-29

  • 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/site plan catalog returns volume caps only (checkout: false for 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_EMAIL import in Landing.tsx caused a runtime ReferenceError and white screen on /. Fixed in f22903d.

2026-08-22

Lettermint brand

  • Compare page and drop-in base use Lettermint: /compare/lettermint, /api/compat/lettermint.
  • /api/compat/lettermind remains 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 code and hint on the send envelope.
  • POST /api/emails sends with the workspace from a team/project token.
  • Drop-in bases: /api/compat/resend, /api/compat/postmark, /api/compat/lettermint (/api/compat/eu and /api/compat/lettermind are 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

  • /compare hub 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-ID lines 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 .md suffix.
  • /llms.txt and /llms-full.txt for language-model crawlers.
  • Docs-specific robots and sitemap.

Discovery (marketing origin)

  • robots.txt allows 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.

View this page as Markdown · llms.txt · full corpus