v3.3.0
May 16, 2026
Major
ZeptoMail parity
Closes the feature gap with ZeptoMail and Postmark. Adds email streams, file cache, dedicated IPs, SMTP relay, user management, and 7 new MCP tools.
Added — Email Streams
POST /api/streams · GET · DELETE — Create transactional / marketing / notifications profiles with their own from-address, SES configuration set, and IP pool.
- New
streamId field on POST /api/emails routes the send through the named stream's config.
- Send path auto-stamps
X-InboxOS-Stream header on outbound MIME.
- Per-stream
enabled toggle lets you pause marketing while keeping transactional live.
- MCP tools:
create_stream, list_streams.
Added — File Cache
POST /api/files · GET · DELETE — Upload a file once to R2; reference by fileId in many sends.
- 25 MB max per file, 20 attachments max per email.
- Auto content-type detection from extension (PDF, PNG, JPG, GIF, WebP, SVG, CSV, DOCX, XLSX, ZIP, ...).
- Optional
expiresAt auto-purges via the existing cron.
- SES Raw MIME path now activates automatically whenever attachments are present (inline or by reference).
- New multipart/mixed builder with proper multipart/alternative bodies + RFC 2045 base64 chunking.
- MCP tools:
upload_file, list_files.
Added — Dedicated IPs
POST /api/ips · GET · DELETE · PUT /:id/status — Register and track dedicated SES IPs per tenant.
- 4-state warmup machine:
pending → warming → active → retired with warmupPct tracker.
- Send path auto-routes through the active IP pool's configuration set when no
streamId override is set.
- MCP tool:
register_dedicated_ip.
Added — SMTP Relay
POST /smtp/send — HTTP-based SMTP-compatible endpoint.
- Accepts raw RFC 822 MIME (for sidecar proxies) or a simplified envelope JSON.
- RFC 822 header parser handles folded lines, address brackets, and basic Content-Type detection.
- Routes through the same
send() domain function — full parity with REST sends (suppression, idempotency, tracking, streams).
Added — User Access Management
GET /api/users · POST · DELETE /:id · PUT /:id/role · POST /:id/suspend.
- Four roles:
owner · admin · developer · viewer with owner-protection rules.
POST /api/users/invite — generate 7-day invite tokens.
POST /api/users/accept-invite — public (unauthenticated) endpoint, token-gated, marks user active.
- MCP tools:
invite_user, list_users.
Infrastructure
- D1 migration
0004_zeptomail.sql: 5 new tables (email_streams, file_cache, users, user_invites, dedicated_ips).
- R2 prefix layout extended:
tenants/{tenant_id}/files/{file_id} alongside the existing emails prefix.
- Terraform module
infra/aws/ for one-shot AWS SES + SNS + IAM provisioning, with optional dedicated IP pool toggle.
- One-shot bootstrap script (
infra/aws/bootstrap.sh) that runs Terraform and pipes IAM credentials straight into wrangler secret put.
- Tenant seed script (
scripts/bootstrap-tenant.mjs) generates the first tenant + admin API key with the correct HMAC scheme.
API key scopes — new
streams:read · streams:write
files:read · files:write
users:read · users:write
ips:read · ips:write
Marketing site + Docs
- New
mailgrid.space apex site on Cloudflare Pages (8 pages: home, pricing, customers, changelog, contact, docs landing, privacy, terms).
- Wiki-style documentation at
/docs/ with sticky sidebar, search, right-rail table of contents, breadcrumbs, prev/next pager.
- 29 deep documentation pages covering every concept, API endpoint, guide, and operations runbook.
- Comprehensive feature inventory at
/docs/features.
Breaking changes
- None. All v3.2 calls continue to work unchanged. New fields (
streamId, attachments) are optional.
v3.2.0
May 1, 2026
Major
AI & Superhuman parity
Adds the full Superhuman-class AI layer plus follow-up rules, smart-send, and audit logs. This is when Mailgrid stopped being "just an email API" and became an agent-driven platform.
Added — AI capabilities
POST /api/ai/summarize — Summarize an email body. Returns both a detailed summary and a one-line TL;DR.
POST /api/ai/ask — Natural-language queries over tenant event data + knowledge base. E.g. "Which campaigns had the highest open rate this month?"
POST /api/ai/personalize — Rewrite subject + body for a specific recipient using contact metadata + tone.
- Voice & Tone match — accept 1-3 example emails on
POST /api/templates/generate for style-matched output.
- Smart-send —
computeSmartSendAt() returns the optimal next send time from historical open patterns.
- AI provider chain: Workers AI (Llama 3.1 8B) primary; Anthropic Claude Haiku fallback when
ANTHROPIC_API_KEY is set.
Added — Knowledge base
POST /api/knowledge · GET · DELETE — Store free-form context entries.
- Auto-injected as context for
ai/ask and templates/generate calls.
- Tag-based filtering for selective injection.
Added — Labels & classification
POST /api/labels/rules · GET · DELETE — Define rule-based auto-labeling.
POST /api/labels/email/:id/auto — Run rules + AI fallback against a specific message.
- Rules support
contains and matches conditions on subject/from/body.
Added — Follow-up rules
POST /api/followups — Configure "if not opened/clicked within N days, send follow-up message".
- Cron-evaluated against engagement data.
- Stacked rules supported (3-day reminder → 7-day final).
Added — Audit logs
GET /api/audit-logs — Structured trail of every administrative action.
- Records actor (API key id), action, target resource, before/after state, timestamp.
- Filterable by actor, action, date range.
Infrastructure
- D1 migration
0003_superhuman.sql: knowledge base, label rules, audit logs, follow-up rules tables.
- New cron at
30 4 * * * for daily analytics rollups.
- Workers AI binding added to
wrangler.toml.
API key scopes — new
ai:use · knowledge:read · knowledge:write · labels:read · labels:write · audit:read
v3.1.0
Apr 18, 2026
Major
Production-ready InboxOS
Multi-tenant production-grade platform with contacts, scheduling, tracking, analytics, MCP.
Added — Contacts & lists
POST /api/contacts · CRUD with arbitrary JSON metadata per contact.
- Statuses:
subscribed · unsubscribed · bounced · complained.
POST /api/lists · many-to-many contact ↔ list membership.
- Bulk import endpoint with 10,000 entries per call.
Added — Scheduled emails
POST /api/emails/schedule — D1-backed, hourly cron-flushed.
DELETE /api/emails/schedule/:id — Cancel pending.
- 4-state machine:
pending · sent · cancelled · failed.
Added — Tracking
GET /t/o/:token — 1×1 open pixel with HMAC-signed token (no DB read on hit).
GET /t/c/:token — Click tracking with 302 redirect to destination.
- Per-send
trackOpens + trackClicks toggles on POST /api/emails.
- Long-URL tracking table for click-through redirects on >2 KB URLs.
Added — Analytics
GET /api/analytics?days=30 — 30-day rollup of all event types.
- Daily breakdown for chart-friendly time series.
- Rates computed: delivery, open, click, bounce, complaint.
Added — Unsubscribe (RFC 8058)
List-Unsubscribe + List-Unsubscribe-Post headers stamped on every send.
- Both
mailto: and https:// unsubscribe paths.
- HMAC-signed tokens — no DB lookup on one-click unsubscribe.
- Public UI at
/unsubscribe?token=....
Added — MCP server
POST /api/mcp — Model Context Protocol 2024-11-05 endpoint.
- Initial 11 tools: send_email, send_batch, create_template, get_template, generate_template, verify_domain, get_domain, analyze_deliverability, get_event_log, suppress_email, unsuppress_email.
- Shared Zod schemas across REST + MCP — single source of truth.
- JSON-RPC 2.0 transport over HTTP POST.
Infrastructure
- D1 migration
0002_inboxos.sql: contacts, lists, scheduled_emails, daily_analytics, tracking_links tables.
- Hourly cron at
17 * * * * for idempotency purge + scheduled-email flush.
- OpenAPI 3 spec generation at
GET /openapi.json.
v3.0.0
Apr 1, 2026
Major
Cloudflare-native rewrite
Complete rewrite. AWS Lambda → Cloudflare Workers. DynamoDB → D1. S3 → R2. AWS SDK eliminated. Bundle size dropped from 4.8 MB to 420 KB.
Migrated
- Compute: AWS Lambda → Cloudflare Workers (cold start: 800ms → 17ms).
- Database: DynamoDB → D1 SQLite (relational schema, pay-per-request).
- Storage: S3 → R2 (S3-compatible, no egress fees).
- Cache: ElastiCache Redis → KV (sub-ms reads, no cluster to manage).
- Queues: SQS → Cloudflare Queues + DLQ.
- Rate limit: Lambda concurrency limits → per-tenant Durable Object token bucket.
- AI: Bedrock → Workers AI (Llama 3.1 8B), with Anthropic fallback.
- DNS verification: AWS SDK → Cloudflare DoH (1.1.1.1).
Removed — AWS SDK
- Replaced AWS SDK SES client with hand-written SigV4 signer (
src/lib/sigv4.ts, ~150 lines).
- Replaced AWS SDK S3 client with raw
fetch() + R2 binding.
- Bundle size: 4.8 MB → 419 KB compressed.
- Cold-start time: down 47×.
Architecture
- Hono v4 as HTTP router (10 KB, Worker-native).
- Zod v3 for input validation, generating both runtime checks and TypeScript types.
asyncContext module for thread-local env + waitUntil passing.
- Idempotency layer: 24-hour TTL, payload hashing, in-progress concurrency guard.
- Per-tenant Durable Object for token bucket rate limiting.
v2.x
2025
Archive
The original AWS Lambda + DynamoDB MailBridge prototype. Single-tenant. Manual deployment. No multi-stream or AI. Available in the git history but no longer maintained — v3.0 was a complete rewrite, not an upgrade path.