plunk

GitHub

The Open-Source Email Platform

5,316 stars TypeScript
RAW Doc

CHANGELOG

Changelog

0.13.0 (2026-08-09)


Features

* add email body cleanup job to remove old email content after 90 days (cef8ce0)
* api: insert steps mid-transition and validate connections (6343ef5)
* classify emails and build headers based on email type (8f23d8a), closes #411
* hide signup link from login when DISABLE_SIGNUPS is set (21ea0b8)
* i18n: add Swedish (sv) translations (1fbaccc)
* i18n: add Swedish (sv) translations (bdd5ab7)
* implement idempotency for POST /v1/track and POST /v1/send with cleanup job (94c85ac)
* insert, disconnect and reconnect steps in the workflow editor (aa4b011)
* One post click unsubscribe links for Plunk hosted emails (64b51df)
* web: insert, disconnect and reconnect steps in the workflow editor (68cd243)
* web: scope email editor 'Preview as' to the campaign's segment (abef349)
* web: scope email editor 'Preview as' to the campaign's segment (184f019)


Bug Fixes

* api: close SSRF bypass via IPv6 transition addresses in webhooks (a60ce6b)
* api: close SSRF bypass via IPv6 transition addresses in webhooks (e71c747)
* events: reject cross-tenant contact and email IDs on event tracking (7aad5de)
* events: reject cross-tenant contact and email IDs on event tracking (6ff7ad0)
* refine date filtering logic for activity feeds and pagination (3b86873)


Documentation

* Update OpenAPI spec to reflect implementation (ff609f8)

0.12.0 (2026-06-21)


Features

* add composite index on campaignId and status for efficient campaign completion checks (4b752a5), closes #400
* add disabledReason field to projects for better tracking of disable reasons (94ceadb)
* api: allow API key authentication for domain endpoints (d2496bc)
* bulk delete for workflows and campaigns (a05034e)
* Contacts: add subscription status filter and enhance query capabilities (8564016)
* contacts: make email cell a link to the contact detail page (6759bff)
* contacts: make email cell a link to the contact detail page (6d98d51)
* EmailService: add worker concurrency settings and improve email queue prioritization (80beb2b)
* extend table view to workflows and campaigns list pages (e932b2d)
* i18n: add Japanese (ja) translations (e399d0c)
* i18n: add Japanese (ja) translations (f34c0e1)
* implement deterministic avatar gradient generation for user accounts (e0e79cc)
* introduce DataTableFilter and FacetedFilterMenu for unified filtering experience (44e4e45)
* make detectCustomHtmlPatterns aware of TipTap's actual capabilities (9797aed)
* make detectCustomHtmlPatterns aware of TipTap's actual capabilities (ba3813e)
* normalize email addresses for contacts to handle case-variants and whitespace (05c8041), closes #403
* refactor DashboardLayout to use DropdownMenu for project and user menus (9cbd5c0)
* render template variables in WEBHOOK step url, headers and body (bfecf04)
* render template variables in WEBHOOK step url, headers and body (c484da8)
* SecurityService: enhance phishing detection by verifying sender domains and institutional TLDs (6ab4d77)
* SecurityService: enhance phishing detection by verifying sender domains and institutional TLDs (edfc399)
* table view with sorting, faceted filters, and bulk delete for templates, workflows, and campaigns (4ccb3d2)
* tanstack table view with sorting, faceted filter, and bulk delete for templates (55a0c4f)
* tests: enhance test database setup and cleanup for improved isolation and performance (32dd7bb)


Bug Fixes

* coerce boolean and numeric values in custom CSV columns (4a145f3)
* dashboard: table empty-state recovery, bulk button sizing, workflow status+steps, header casing (157ff34)
* filters: land templates/workflows/campaigns search inputs at 32px to match filter buttons (283f402)
* make email templates, campaigns and workflow search inputs same height as the rest of the app (8b3657d)
* safeguard JSON data handling in contacts migration to ensure proper object types (55a5e4d)


Code Refactoring

* database: increase Prisma connection pool limits for improved test performance (71e2277)
* SecurityService: update absolute count ceilings for new projects to improve spam detection (4de40f4)


Documentation

* add env-var sync rule to CLAUDE.md (a348d37)
* add new recipe pages for waitlist and sync unsubscribes (01ec34a)
* correct PHISHING_CONFIDENCE_THRESHOLD default in CLAUDE.md (5c16679)
* env: add wiki-documented vars to apps/api/.env.example (81315ea)
* env: sync .env.self-host.example with missing variables (1c1c95d)
* env: sync env example files, fix CLAUDE.md drift, add process rule (6ebbb50)
* wiki: document MAIL_FROM_SUBDOMAIN and NGINX_PORT env vars (971b98a)

0.11.0 (2026-05-13)


Features

* Ability to change subscription status in workflows (fadc19d)
* add 'notTriggeredWithin' operator to segment filters for enhanced event tracking (0f00ca1)
* add external link to edit email templates in SendEmailStepDialog and WorkflowBuilder (4ba43dd)
* add Markdown cut link to footer and page for improved accessibility (ccd516e)
* add project switching functionality to command palette (5724ab9)
* add sanitize-html for improved email content sanitization (735acff)
* add search functionality to campaigns list with debounce effect (d114950)
* add segment membership operators and enhance segment filter functionality (a3cc622)
* add SwitchOffer component to promote switching from competitors for enhanced user engagement (6195b39)
* add workflow duplication functionality with API endpoint and UI button (c6340a1)
* enhance campaign scheduling and audience settings UI for better clarity and usability (7658a59)
* implement bulk contact action selector for improved flexibility in bulk operations (de6335e)
* implement caching for recent activity count to optimize performance and reduce database load (f22da4a)
* implement early fraud warning handling in webhooks (48425d1)
* make MAIL FROM subdomain configurable via MAIL_FROM_SUBDOMAIN env (463301b)
* make MAIL FROM subdomain configurable via MAIL_FROM_SUBDOMAIN env var (e0bf0f6)
* refactor template editing layout for improved usability and clarity (aaf5ac6)


Bug Fixes

* enhance campaign finalization process to handle pending emails and ensure accurate status updates (2529c9b)
* enhance email content parsing and logging for better debugging (4587e9d)
* enhance project name validation to exclude invisible and decorative characters (29883ff)
* enhance Quick Start card layout for improved responsiveness and usability (649bbf6)
* handle undefined path in footer component for improved stability (715961c)
* implement mergeContactData method for efficient contact data updates (a27d564)
* improve iframe height adjustment logic in EmailEditor component (9e4aa94)
* pass DISABLE_SIGNUPS and EMAIL_RATE_LIMIT_PER_SECOND through compose; trim .env.self-host.example (8a26d60)
* pass missing env variables from .env.self-host.example to plunk service (f178c59)
* replace font loading method with utility function for improved performance (ba23a1c)
* update activity item colors and backgrounds for improved visual distinction (e43f70d)
* update middleware matcher to exclude webmanifest files (cbb3bff)
* update not found handling in GET route to return 404 response (7615b62)
* update segment filter logic to retain value and unit, enhance activity name mapping (d1f357c)
* update segment filter logic to retain value and unit, enhance activity name mapping (a126563)
* update TemplateSearchPicker to maintain selected template name on change (2ea1802)


Code Refactoring

* convert forwardRef components to function components for consistency (361ec0b)
* implement step dialog components for workflow editing (ed9027b)
* remove unused .png files (2d05c3f)


Documentation

* expand documentation with new sections on importing contacts, unsubscribe pages, and API key management (4ddafdc)
* update README to clarify self-hosted alternative and add inbound emails feature (80ef65e)

0.10.0 (2026-05-01)


Features

* add className prop to EmptyState component for custom styling (c278a0f)
* add configurable attachment limits for email service (2eb4079), closes #358
* add middleware support for .md file rewrites (0b3aa28)
* add updateActiveProject function for in-place project updates (6f31fa2)
* enhance contact addition with bulk email lookup and subscription options (bb72911)
* enhance contact data handling by filtering empty strings and allowing null to delete fields (1094651)
* Enhance ease of use of workflow editor (c910d20)
* implement CommandPalette for enhanced navigation and recent pages tracking (1c89ed0)
* implement meter event processing with queue for Stripe billing (e048fc1)
* implement phishing detection using OpenRouter API with configurable sampling rate (2da8b06)


Bug Fixes

* Add in-memory cache for lower-confidence phishing checks (208c809)
* add new configuration options for phishing detection thresholds (c0e0ad8)
* add project name and sender email parameters to phishing content check (1637d54)
* add project name and sender email parameters to phishing content check (15294a4)
* Consistency across buttons and labels (c1bcd35)
* Consistency across cards (517753c)
* Content negotiation for xml and txt (c8190b9)
* Harmonize rings and hover states (f40cc86)
* improve layout and accessibility of workflow header and buttons (ab3edd7)
* log message for projects passing phishing checks (8628754)
* prevent unnecessary state updates in search input effect (98f1e80)
* reconcile totalRecipients in CampaignService to prevent stuck campaigns (4322de9), closes #348
* ses: emit List-Unsubscribe inside the header section, not the body (11c428d)
* standardize step type labels and update visual styles in workflow components (bdc9b30)
* Sync display name in TemplateSearchPicker when initialName changes (3649392)
* Sync display name in TemplateSearchPicker when initialName changes (cbde3cc)
* turn warning into success log (b7eb254)
* update phishing confidence threshold to 95% (bb78c86)
* update project disabled messages for clarity and consistency (d7eb85f)
* update project icon colors for improved visibility and consistency (5f741c6)
* update response format for phishing analysis and improve JSON parsing comment (91d0d2d)

0.9.0 (2026-04-20)


Features

* Add accept/markdown to apps/landing (df76be1)
* Add emailId field to webhook events for better correlation with send requests (ae64c2d), closes #344
* Add headless template type (fb5aa87)
* Add onboarding flow (bd5a085)
* Add type to campaign (d24259e)
* Block domain changes for disabled projects with appropriate error handling (44c8657)
* Disable projects on failed payment (3343e89)
* Enhance email processing to include parsed HTML body content in inbound email records (e339508), closes #342
* Enhance login forms with last used authentication method (f2ebce0)
* Enhance security metrics handling with new thresholds and improved messaging (c0b2aba)
* implement AWS SNS signature verification in SecurityService (b79d416)
* integrate DOMPurify for sanitizing HTML content (bf12392)
* Update new project bounce thresholds for stricter email handling (5e62f51)


Bug Fixes

* Enhance email processing to support campaign types and improve unsubscribe logic (9e2400c)
* Hint custom event names in combobox when no matches are found (3214f6c)
* Implement content negotiation for markdown and html in middleware (37ed1e4)
* Implement SSRF protection in webhook handling with safeFetch method (2c5a715)
* Refactor date filtering logic for pagination in ActivityFeed and ActivityService (52cb2b6)
* Update language validation regex to support locale variants (7834b9e)


Documentation

* Add content negotiation to apps/wiki (545d733)

0.8.0 (2026-03-31)


Features

* Add multi-branch workflow conditions (switch/case) (92949b7)
* i18n: add Chinese translations (zh-TW, zh-HK, zh-CN) (33df563)
* i18n: add Italian translation (7b6872c)


Bug Fixes

* Adapt SNS Webhook validation regex pattern to also support AWS eusc partition (7b6540a)
* add alt text to email badge image (3b39d84)
* broken links to next-wiki.useplunk.com (e3ea5fb)
* Connect branches smoothly to original node (2c3e897)
* Enhance email step configuration validation and recipient handling (b50b5af)
* Enhance email step configuration validation and recipient handling (a99cde8)
* normalize field references and handle undefined values in JSON (b9d692c)
* Prevent switching if nodes are attached to multi-branch (c32b54f)
* update old references to next.useplunk.com (44987d2)
* visual editor preview (4451e92)


Documentation

* Fix broken links on api overview page (dc2ce02)
* Improve self-hosting env variable documentation (f0ef346)

0.7.1 (2026-03-10)


Bug Fixes

* Align preview and actual email for templates and campaigns (cc7fcdb)


Documentation

* Add inbound to docs (6c4cc29)
* Improve webhook documentation (f6a32ce)

0.7.0 (2026-03-05)


Features

* api: support inline images in emails using Content-ID (9b15b93)
* Sort projects alphabetically in the dashboard and fix layout (64bd094)
* Static segments (4b51e38)


Bug Fixes

* Add support for STATIC segment type in CampaignService (7bd098b)
* correct cookie domain for .local TLD hostnames (59aa784)
* Correctly set domain status on manual verify (21af8fe)
* Do not unsubscribe existing contacts (2c4d95e)
* Support any locale on creation (ec1f4c9)
* Verify SNS URL before sending fetch request (b8f1ad9)


Documentation

* Static segments (e8a247f)

0.6.0 (2026-02-19)


Features

* Ability to change workflow trigger (eec37ec)
* Add billing for inbound (3330d83)
* Add billing for inbound (de7ed84)
* Add dedicated received type (f947ee6)
* i18n: Add Spanish language (9c69c7a)


Bug Fixes

* Enhance email bounce notification with latest bounce details (e639c72)


Documentation

* Add receiving emails functionality and update DNS records documentation (b426986)

0.5.0 (2026-02-17)


Features

* Ability to disable signups and disable email verification for self-hosters (9316564)
* add "olderThan" segment filter operator (b5fa21a)
* Add additional checks for website, NS records and personal emails (0a67a82)
* Add advanced DNS configuration (7964563)
* Add bounce and complaint filter to activity feed (c85df75)
* add documentation link and redirect to WIKI_URI (4c81d9e)
* Add inbound handling (d050b55)
* Add initial handling in webhook for inbound (e01dc40)
* Add initial handling in webhook for inbound (c286f49)
* add minimum thresholds for bounce and complaint rates (d55dda3)
* Add support for custom email recipients in workflow steps (78d3d22)
* i18n: Add Bulgarian translations (663bc2b)
* i18n: add Czech locale translations (14c471e)
* i18n: add Polish locale translations (7a6df77)
* i18n: add Polish locale translations (d2d779c), closes #246
* i18n: Add Portuguese translations (c2afb2d)
* Integrate NuqsAdapter for improved state management and query handling (0cf0a26)
* Remove domain from AWS if no longer in use by other projects (e6baace)


Bug Fixes

* added missing services:down script, added "win32" to supportedArchitectures for yarn package installation, added missing required WIKI_URI to .env.example of api (ddbe523)
* Center "Add Step" nodes below parent nodes and update positions on drag (e4e334c)
* Enhance email activity filtering by adding date range checks (ad0c17d)
* Ensure template type is loaded before rendering Select (8a38766)
* Implement merging for activity updates to preserve component state (0d4b694)
* Improve bounce handling logic to differentiate between permanent and transient bounces (7df43d8)
* Improve email verification logic by prioritizing MX record checks and clarifying domain existence validation (26800a8)
* Refactor Redis keys to prevent multiple messages on concurrent requests (4db1ccc)
* Remove 'Optional' label from MAIL FROM Domain and Inbound Email headings (f9b1354)
* Update contact subscription logic for upsert operations (a928666)
* Update URL replacement logic to handle runtime paths and add warnings for missing files (c07816c)


Code Refactoring

* remove unnecessary logging for segment processing (42ceb6e)


Documentation

* add webhooks documentation for real-time event handling (5bce1d7)
* update contacts documentation to include subscription state and email delivery rules (b4404f6)

0.4.0 (2026-01-08)


Features

* Add cooldown to resend verification email (457c829)
* Add email verification on signup (fb02051)
* Add forwarding domains as verification check (e732c76)
* Add id as reserved field in templates, campaigns and workflows (7386441)
* Add platform emails for domain verification and expiration (19554e6)


Bug Fixes

* Add better validation for sender email (e75e07f)
* Catch unknown content-type headers (a5c5754)
* Check email volume for 7-day window (492beb0)
* Copy types build files (49824af)
* Enhance CORS handling to allow requests with rejection logging (718251c)
* Migrate over to new pagination format in dashboard (8790c45)
* Reentry into segment not working after exit (4dce71a)
* Refactor CORS handling to allow unrestricted access for public API endpoints (940c893)
* Update sentCount on campaign sent for correct overview stats (ee00eb3)
* Update template fetching to use Template type and simplify body access (b6c5471)
* Update templates data fetching to use PaginatedResponse type (fa22b82)


Documentation

* Add more details about personalisation (940a4d2)

0.3.0 (2025-12-29)


Features

* Ability to overwrite locale on contact level with locale key on data (7615523)
* Add additional banner and information about security metrics (bc8611a)
* Add bulk actions to contact overview (726f667)
* Add email verification and password reset (1a5607f)
* Add email verification endpoint at /v1/verify (6a9f6aa)
* Add plus address check to /v1/verify (afc405e)
* Add project-scoped language for unsubscribe footer and contact-facing pages (e1f8263)
* Allow to pick currency when starting subscription (8a136dd)
* Email preview in contact and activity feed (72dffe1)
* i18n: add German translations and update supported languages (a6bd2e7)
* i18n: add Hindi translations for contact-facing pages (ddc14ae), closes #246


Bug Fixes

* Add styling for visual editor emails in preview (5993b84)
* Correctly reserve fields from being set on contact (61cea95)
* Date filtering not working properly for custom contact data (97ab0a2)
* Do not check verification if platform emails are not enabled (9567144)
* Import no longer case-sensitive about email column (451dd03)
* Pass through email verification if auth type is apiKey (d7b5d3f)
* Persistence of subscription state for existing contacts (007a908)
* Properly tag events in SegmentFilterBuilder.tsx (8f725c7)
* Redirect verification link to dashboard instead of landing (35f5275)
* Set auth type before disable check (862babb)
* Variable substitution in transactional emails (8c03042)


Documentation

* Add locale overwrite to project documentation (1fc1e23)
* Add plus address check to /v1/verify (0d54b1a)
* Improve docs with core-concept and guides (2ddfcec)
* Update openapi.json to match actual API outputs (dc9b88d)

0.2.0 (2025-12-16)


Features

* ability to create new campaigns based on templates or previous campaigns (6b25bbe)
* Add improved html editor using CodeMirror (672f1e6)
* Add security center and warning for exceeding bounce/complaint rates (fbd3038)
* Added platform emails for billing limits and disabled projects (2485d2f)
* Automatically detect rate limit from AWS with ability to override in .env (3225c50)
* Improved createdAt and updatedAt visualisation (1019ba0)


Bug Fixes

* ability to clear reply-to and from name from templates and campaigns (badb035)
* Add additional checks for disabled projects (863e784)
* Add additional checks for disabled projects (780741e)
* add additional indexes on event model (1cd89d1)
* Allow changing audience type after creation of campaign (85b9d7a)
* Better highlight warnings in SecurityWarningBanner.tsx (91eb0f3)
* Clear notification cache keys when changing billing limits (e50c33a)
* Correctly show recipient count during creation and edit (d0191be)
* custom relative time to shorten strings for better UI fit (5e4adb7)
* display email progress instead of scheduling progress for campaigns (07f875c)
* Hide upsell banner if billing is not configured (433e796)
* Increase z-index of color picker (769e374)
* Move react and react-dom to dependencies instead of peerDependency for API (a555a12)
* Move react and react-dom to dependencies instead of peerDependency for API (f37bfcc)
* Only check free tier limits if billing is enabled (1713b23)
* Only fetch project members if project Id is defined (5a0a41c)
* Overflow of inputs in email editor (3336fa1)
* Prevent manual tracking of internal events that are automatically tracked (f34052e)
* prevent scheduling of campaign if billing limit reached (a3bbb1e)
* show correct default value for placeholder (04275e3)
* Unauthenticated users are redirected to login on subscribe/unsubscribe/manage pages (11ef47b)
* Update recipient count on create/update of campaign (ff5c79c)
* Verify if sending without tracking is possible in SESService (68f9979)

0.1.1 (2025-12-08)


Bug Fixes

* Add additional verification in Oauth controllers (53ecda9)
* add clear cache button on full-screen loader (60804c1)
* Dedicated token name for next version (fc535a5)
* only mark releases as latest (9d8b4a5)


Documentation

* dynamic link to Docker Compose for self-hosting (90f8170)
* Update AWS setup docs (f7ac25f)

0.1.0 (2025-12-08)


Features

* Added ability to overwrite sender mail and name for templates and campaigns (f1d4d50)
* basic health-checks (2e69173)
* dashboard: add status filter for contacts (45697cf)
* Email attachment support (0e718d4)
* Increase pagination limits to improve data display and update version to 1.2.1 (4fe90ad)
* Optimize data retrieval and add new indexes for performance improvements (51b40cc)


Bug Fixes

* Add fixed yarn version (daa8285)
* Add fixed yarn version to Docker build (ff5c6af)
* Add ref (4c25a28)
* Add target (8ca5aea)
* Added Migration (e2d0d0e)
* Added try/catch to CRON (c96a007)
* Check if APP_URI has https (bad18ae)
* clear Redis key on event deletion (0ef39ce)
* Correctly duplicate from (111e054)
* Force node-20 (0b79bef)
* incorrect domain verification records (4bb38b9)
* incorrect schema in dashboard (d69a57d)
* move updating the contact to contacts controller (7c8d3bb)
* Proper reset of contact (7879e66)
* refetch contact after awaiting triggers (7202606)
* refetch contact after awaiting triggers (3f70be9)
* Remove openssl install (605a5a0)
* return updated contact info (115ac5f)
* server crash in self-hosted instances (ccb832d)
* Show project from and name as backup (d4bdcbf)
* Unlink domain properly executes (f58149a)
* Update yarn.lock (ee1651e)
* Version (5ca4567)
* Version (3a5d05a)
* Version (42e865c)
* Version (b742ab1)


Code Refactoring

* remove recipients from campaign data structure (c40189e)

---

CONTRIBUTING

Contributing

You can greatly support Plunk by contributing to this repository.

Support can be asked in the #contributions channel of the Plunk Discord server

1. Requirements

- Docker needs to be installed on your system.

2. Install dependencies

- Run yarn install to install the dependencies.

3. Set your environment variables

- Copy the .env.example files in the api, dashboard and prisma folder to .env in their respective folders.
- Set AWS credentials in the api .env file.

4. Start resources

- Run yarn services:up to start a local database and a local redis server.
- Run yarn migrate to apply the migrations to the database.
- Run yarn build:shared to build the shared package.


- Run yarn dev:api to start the API server.
- Run yarn dev:dashboard to start the dashboard server.

---

README

<h1 align="center">Plunk</h1>

<p align="center">
The Open-Source Email Platform
</p>

<p align="center">
<img src="https://img.shields.io/github/contributors/useplunk/plunk"/>
<img src="https://img.shields.io/github/actions/workflow/status/driaug/plunk-whitelabel/docker-build-prod.yml"/>
<img src="https://img.shields.io/docker/pulls/driaug/plunk"/>
<img src="https://img.shields.io/github/license/useplunk/plunk"/>
<img src="https://img.shields.io/github/stars/useplunk/plunk"/>
</p>

Introduction

Plunk is an open-source email platform built on top of AWS SES. It allows you to easily send emails from your
applications.
It can be considered as a self-hosted alternative to services
like SendGrid, Resend or Mailgun.

Features

- Transactional Emails: Send emails straight from your API
- Automations: Create automations based on user actions
- Broadcasts: Send newsletters and product updates to big audiences

Sponsors


Plunk is made possible by the support of our sponsors. If you self-host Plunk, consider supporting via GitHub Sponsors.

<div align="center">
<table>
<tr>
<td align="center" width="120">
<img src="https://avatars.githubusercontent.com/u/206509599?s=200&v=4" style="width:80px; height:80px; object-fit:contain;"/><br/>
<a href="https://every.news/?ref=useplunk.com">Everynews</a>
</td>
</tr>
</table>
</div>

Self-hosting Plunk

The easiest way to self-host Plunk is by using the driaug/plunk Docker image.
You can pull the latest image from Docker Hub.

A complete guide on how to deploy Plunk can be found in
the documentation.

Contributing

You are welcome to contribute to Plunk. You can find a guide on how to contribute in CONTRIBUTING.md.

<a href="https://github.com/useplunk/plunk/graphs/contributors">
<img src="https://contrib.rocks/image?repo=useplunk/plunk" />
</a>

---