1.1.0 - 2026-05-15
Full landing redesign and developer-experience polish. No API breaking
changes; everything in /v1/* and @mailsink/mcp continues to work as
documented in 1.0.
Changed
- Dark Inngest-anchored theme replaces the light theme across all 11
static routes (
/,/app,/try,/docs,/blog,/changelog,/security,/status,/privacy,/terms, plus blog post template). Yellow accent and brand mark retained from v1.0; primary surface now stone-950 with a single yellow signature stripe. - Header trimmed from 13 to 8 visible items. Primary CTA unified to
Try freeacross nav, hero, pricing, and CTA banner. - VS table gains an Ours column highlight (yellow tint, "Ours" pill tag) plus row hover. Each cell now follows a single icon-or-detail pattern instead of mixed text/symbol shapes.
- Pricing Pro tier accent unified to yellow (was tan border + yellow
pill, two yellow tones). Pro/Team CTAs renamed
Subscribe→Get Pro →/Get Team →to match the OAuth-first signup flow. - FAQ marker upgraded from
+/-text to an SVG chevron with spring rotation; active question and chevron shift to the yellow accent.
Added
- Anonymous
/tryendpoint — try a 10-minute disposable inbox without signing in. Auto-creates on?go=1, with cookie-session and per-IP rate limiting. - AI-discoverable infrastructure (
/aio-ship) —/llms.txt, markdown twins on/blog/,/docs/,/changelog/, JSON-LD on every blog post and the docs index. Cloudflare Block-AI-bots disabled; ClaudeBot, GPTBot, Google-Extended, Bytespider, CCBot, Amazonbot all allowed via cleanrobots.txt. - Six new blog posts including Claude Code: receive email in three lines, Test Stripe checkout email verification, and a complete vs-MailSlurp / vs-Mailtrap / vs-AgentMail series.
- Quickstart code tabs —
curl,Node,Python,Claude MCPall working; each tab ships a copy-to-clipboard button. - Tools row "Works with your stack" now uses real SVG logos for Playwright, Cypress, Puppeteer, Anthropic, Cursor, Stripe, Resend, Auth0, Clerk with reveal-on-scroll stagger and per-logo tooltips.
- EDGE-NATIVE section redesigned as two product-screenshot cards (Resend pattern): a mock event log showing real-MX delivery, and a mock HTTP trace showing REST + MCP returning the same JSON shape.
- Reveal-on-scroll stagger via a single IntersectionObserver +
--icustom property across hero, features, edge, compare, pricing, FAQ, and CTA banner.prefers-reduced-motionrespected everywhere. - Universal copy-button pattern (
[data-copy-target]for static IDs,[data-copy-tabbed]for tabbed code blocks) covering Install MCP in hero, Quickstart tabs, and the curl snippet in CTA banner. - First paying customer milestone outreach pipeline:
mailsink.devis now a verified Resend sending domain (DKIM + SPF + MX onsend.mailsink.devsubdomain; root MX/SPF for Cloudflare Email Routing inbound stays untouched). Founder reach-outs ship from[email protected].
Fixed
- Astro
{ }escape inside<pre>code blocks. JSON-shaped samples (e.g.{ "code": "847291" }) trigger Astro's expression parser even in<pre>and<code>elements; literals now use{/}. - VS table em-dashes replaced with en-dashes via styled
<span class="cmp-icon-na">–</span>(lighter visual weight, matches brand rule against em-dashes). - FAQ #2 "authorised" → "authorized" for American-English consistency across all copy.
- Purple shade unified —
.dx-method-postwas using#c084fcwhile--purpleis#a78bfa. Now both point at the variable. - Cloudflare Email-Address Obfuscation on the footer
mailto:link is now properly wrapped in<!--email_off-->;__cf_email__placeholders no longer leak into the markup.
Performance
index.astroshrank from 2,229 to 1,761 lines (−21%) after deleting ~466 lines of dead architecture-diagram CSS that survived three redesign iterations.- Type scale collapsed from 25 to 18 unique font sizes; half-pixel sizes rounded to the next integer.
- Border-radius scale standardized to five CSS variables
(
--r-xs/sm/md/lg/xl) plus the pill 999px and a single deliberate 2px detail on the hero inbox card.
1.0.0 - 2026-04-21
First stable public release. Public API is now commitment-grade.
Added
- Light theme across landing and dashboard, monochrome ink with yellow marker highlights. New brand mark, favicon set, and 1200×630 OG image.
- MCP server for Claude Desktop, Claude Code, and Cursor. Published at
@mailsink/mcp. - Wait-for-code / wait-for-link long-poll endpoints for CI and agent flows (up to 60 s block).
- Per-plan email size enforcement on both the Email Routing worker and the SMTP-ingest endpoint. Free accepts up to 256 KB; Pro 1 MB; Team 5 MB.
- Article and BreadcrumbList JSON-LD on every blog post; SoftwareApplication + FAQPage JSON-LD on the home page.
- Two launch blog posts: MCP email server for Claude, Cursor, and Claude Code agents and MailSink vs Mailtrap.
Changed
- Stripe webhook signature verification is now constant-time (matches Stripe SDK behaviour).
- Unknown-price webhook events no longer silently promote accounts to "pro"; they surface a 500 so Stripe retries with correct data.
- OAuth initiation (
/auth/github) is rate-limited per-IP (10/min) to protect the KV write quota. - Pricing: MCP access is listed on every plan tier, not gated (it was never server-side gated; marketing now matches the product).
- Dashboard UX: returning users land on their dashboard directly; sign-in CTA swaps to "Dashboard →" when a session is present.
Fixed
- Astro scoped-CSS bug on the dashboard: JS-injected key-list rows lost
all styling because
[data-astro-cid-*]scoping does not reach dynamic nodes. Rules wrapped in:global()now apply correctly. - Prod API URL now resolves from
landing/.env.production; previously the production build fell back tolocalhost:8787. - Dashboard XSS hardening: user-supplied API key labels are rendered via
textContentinstead ofinnerHTML.
Security
- Pre-launch audit completed. Zero CRITICAL, four HIGH (all fixed), four MEDIUM (two fixed, two acceptable-for-launch under known trade-offs).
- R2 lifecycle rule
expire-all-30dadded as a backstop for the hourly cleanup cron.
Observability
- Sentry (
@sentry/cloudflare) on both workers. - Umami self-host for landing pageviews and seven CTA events.
- Better Stack uptime probes on
/v1/healthandmailsink.dev.
0.3.2 - 2026-04-20
Added
- API keys in the dashboard. List existing keys with prefix, label, and last-used time. Generate a new key in one click (revealed once, stored by you). Revoke any key except the last one.
Fixed
- New API keys are no longer minted on every sign-in. Returning users go straight to their dashboard; key creation now only happens on first sign-up or explicitly via the dashboard button.
0.3.1 - 2026-04-20
Changed
- Billing is live. Pro ($15/mo) and Team ($49/mo) subscriptions now take real payments. Promotion codes (including any launch coupons) can be applied at checkout.
0.3.0 - 2026-04-20
Added
- Dashboard at
/app. Signed-in users see their plan, current-month usage, rate limit, and inbox TTL at a glance. Upgrade, open the Stripe Customer Portal, or sign out from the same page. - Sessions. Sign in once with GitHub; stay signed in across visits with a
30-day session cookie. Programmatic API clients continue to use
Authorization: Bearer msk_…exactly as before. GET /v1/me— returns the current account, plan, this-month usage, and concrete limits (inboxes/month, rate limit, TTL, email size, MCP access). Powers the dashboard and on-landing pricing cards.POST /auth/logout— signs out of the dashboard.- Pricing cards react to your session. When logged in, the landing page shows your current plan and swaps CTAs to "Upgrade" or "Go to dashboard".
Changed
- Billing endpoints moved under
/v1/billing/*and require authentication. Programmatic access to checkout/portal now goes through a standard API key or session cookie.
0.2.1 - 2026-04-20
Added
/changelog,/security, and/statuspages. Security page documents the transport/storage/auth model and subprocessors. Status page runs live checks against the API from your browser.
0.2.0 - 2026-04-20
Added
GET /v1/inboxes/:id/wait-for-code— long-poll up to 60 seconds for the next OTP. Accepts?timeout=30(default 30s, max 60s). Returns the same shape as/latest-codeon success, or{ code: null, timeout: true }on timeout.GET /v1/inboxes/:id/wait-for-link— same pattern for magic links.
Fixed
- Code samples in the docs and landing page referenced
/wait-for-codebefore it was implemented. The endpoints now exist and match the docs.
0.1.0 - 2026-04-20
First public preview.
Added
- Disposable inboxes on shared domains (
codenotify.net,letterhub.net,mailkite.net). Create, list, burn. - Smart extraction — OTPs and verification links are pulled out of
incoming mail automatically, available at
/latest-codeand/latest-link. - REST API for inboxes, messages, raw
.emldownload, and API-key management. Rate limits vary by plan (60/600/3000 requests per minute on Free/Pro/Team) and are surfaced inX-RateLimit-*response headers. - GitHub sign-in with a one-time API-key reveal.
- Stripe Checkout for Pro and Team subscriptions.
- Hourly cleanup — inboxes and messages expire per plan TTL.