Mailroom
A complete newsletter, running inside your Grav site
Mailroom is a newsletter that runs inside your own Grav site. People sign up with a form on your pages, you write campaigns in Admin Next, and they go out through the Email plugin you already use. Every subscriber, list, campaign, open and click sits in a database you own, on your server, and backs up with the rest of your site. There's no per-subscriber pricing, so a bigger list never means a bigger bill from us, and when you change mail providers your history stays right where it is. Mailroom keeps a real consent record for every person: what they agreed to, when, and from where, plus every change after that. People choose the lists they want, leave one without leaving them all, and look after all of it themselves from a preference center on your site.
Mailroom is built for Grav 2 (2.1 or newer) and requires the free API and Email plugins, with Admin Next for the admin screens. It is not compatible with Grav 1.7.
Everything you need. Nothing you don’t.
Over 62 distinct features and integrations, out of the box.
Campaigns
Several lists, one email each
Campaigns are written in Markdown, with a live preview beside the editor drawn through the real email layout and a sample subscriber. Send one to a single list, check more lists under Also send to, or pick All lists, with a segment to mail everybody on any list who matches. Somebody on two of those lists still gets one email. And the count under the pickers tells you how many people that is before you press anything.
{{ subscriber.first_name }}, {{ site.name }} and {{ site.url }}, a live preview through the real layout, and a plain-text part on every email.
List-Unsubscribe with one-click unsubscribe (RFC 8058), so the unsubscribe button in people's mail apps just works.
Subscribers & Consent
Who agreed to what, and when
Every person has a page with where they stand on each list, their tags, and a consent history: every signup, confirmation, admin add, unsubscribe and return, with the date, the list, how it happened and where it came from. Change their lists and tags right there. Nothing is ever written over, because each change to somebody's consent is a new row.
email column needs no mapping at all.
Signup Forms & the Preference Center
A signup box anywhere on your site
Put {{ mailroom_form() }} in a template or a page and you have a signup box, drawn by your theme. Offer more than one list and they become checkboxes, so people choose what they want instead of getting everything. Every email carries a link to the preference center, where they can change their name, pick lists or leave just one.
mailroom_form() with options for the heading, intro, button text, a name field, tags, your own note of where people came from, a consent sentence per form, and the lists to offer.
mailroom action when you'd rather build the signup form yourself.
POST /newsletter/subscribe takes JSON, so a form on another site or an app can add people too. The answer never says whether an address was already known.
/newsletter unless you choose another route.
Segments
Ask a question of your list
A segment is a saved question, like people who came to a webinar but aren't early adopters. Build it from conditions in three groups, All of these, Any of these and None of these, and the editor shows how many people match right now, with the first ten by name. Then use it to narrow a campaign or decide who enters an automation.
segments:count and segments:preview for the same answers on the command line.
Automations
A welcome series that runs itself
Automations send a series of emails when something happens to a person: they sign up, they confirm, or a tag is added. Each step is an email, a wait, a tag change, a list add, or a branch on whether they opened or clicked the last email. The automation's page shows every step with its own numbers, and everybody who has been through it with where they are now.
Tracking & Reports
The numbers stay yours
Opens and clicks are timestamps against a send row in your own database. Mailroom stores no IP address, browser or location for them, and when you move to another mail provider the history stays. Seven reports read those rows over the last 7, 30 or 90 days, this year, all time or your own dates, and every one of them downloads as CSV.
Deliverability & Provider Webhooks
Know before the spam folder does
The Health tab checks what the companies receiving your mail will check: your domain's SPF, DKIM and DMARC records, your From address, the plain-text part, your unsubscribe headers, your bounce and complaint rates, your sending speed, your provider webhooks and the queue worker. Any check that needs attention says what it found and what to do about it, in plain words.
deliverability:check.
webhook:replay to run a stored provider event through again, and see what it would do first.
Privacy & Your Data
Everything you hold about someone
When you run the list, you hold the data, and Mailroom makes it easy to answer for it. A person's page shows when they agreed, from which address, and when they confirmed. Export their data downloads everything Mailroom holds about them as one JSON file. An erasure removes them completely while remembering, as a hash, never to mail that address again.
user-data://mailroom/mailroom.sqlite by default, or in MySQL or PostgreSQL if you'd rather.
bin/plugin mailroom erase or the API removes a person with their lists, tags, sends, consent history and mail log. The suppression on their address stays as a hash, so somebody who asked never to be mailed stays unmailed.
X-Forwarded-For from a proxy you listed.
For Developers & AI Agents
Every Mailroom screen in Admin Next is built on Mailroom's own API, so anything you can do there, a script or an AI agent can do too.
/api/v1/mailroom/ on the Grav API plugin, with the same permissions as the admin.
mailroom.view to read, mailroom.manage to change things, and mailroom.send to start a campaign, kept apart because a sent campaign can't be taken back.
bin/plugin mailroom seed fills an empty Mailroom with three months of a small project's newsletter, and seed --purge removes exactly what it added.
Everything that needs looking at, in one place
Mailroom opens on an overview: who's subscribed, who's still waiting to confirm, who left, and who will never be mailed again. Under that sits your last campaign, hour by hour, and charts of your recent campaigns and new subscribers. When something is wrong (mail can't leave, a campaign stopped itself, the bounce rate is climbing) it says so right here.
Test two subjects, send the winner
Check Test two subjects and write the other one. Choose how much of the list takes part and how long to wait, and the editor tells you how many people get a subject now and when the rest get the winner. The winner is the subject more people opened (or clicked, on a campaign that isn't counting opens), and the campaign report says which one won.
Every campaign, measured
Each campaign has its own report: how many it went to, how many were delivered, opened and clicked, what bounced and what failed. The first 48 hours are drawn hour by hour, so you can see how fast people read it, and every link shows its clicks. With a provider webhook set up, delivered and bounced are what your provider reported, not a guess.
Email in your colors
Every campaign, confirmation and automation email is wrapped in one layout with your logo, accent, background and text colors, a footer line and your postal address. The footer always carries Unsubscribe, Choose what you hear about and View in your browser, and every message has a plain-text part with the same links.
People look after their own lists
The preference center is a page on your site, drawn by your theme, where people change their name and choose the lists they want, each with its own description. Nobody needs an account or a password: the link in every email is all it takes. Each change goes into their consent history, just like a signup.
Add people the honest way
Paste in addresses, with names if you like, and Mailroom asks how they're joining: send them an invite to confirm, or add them as subscribed with a note saying where they agreed. Suppressed addresses are never added, and nobody who left the list by their own hand is put back on it.
Your newsletter, on your own site
I wanted the newsletter to live where the rest of the site lives. No second dashboard, no list sitting on someone else's servers, and no bill that goes up every time a few hundred people sign up. Mailroom runs on the same host as your Grav site, backs up with it and moves with it. You write in the Admin Next you already use, your subscribers deal with your site and your email address, and the numbers belong to you.
Up and running
- Install Mailroom along with the free API and Email plugins, and make sure the Email plugin can send.
- Open Mailroom from the Admin Next sidebar. Over HTTPS, that first visit fills in the Site URL every email link starts with, unless you've already set one.
- Set a From address on the Sending tab, or leave it empty to send as the Email plugin does.
- Put
{{ mailroom_form() }}in a template or a page for a signup box. - Add the Grav scheduler to your crontab, and check everything with
bin/plugin mailroom status.
Want to look around before you have a list? Run bin/plugin mailroom seed for three months of demo data, and bin/plugin mailroom seed --purge when you're done.
A CLI for the operational side
bin/plugin mailroom status # database, worker and sending health
bin/plugin mailroom work # run the queue now
bin/plugin mailroom migrate # set up a MySQL or PostgreSQL database
bin/plugin mailroom import:csv <file> # import a list (export:csv to get one out)
bin/plugin mailroom segments:count # count a segment (segments:preview to see who)
bin/plugin mailroom deliverability:check # run the Health checks
bin/plugin mailroom webhook:replay # run a stored provider event again
bin/plugin mailroom erase <email> # forget one address
Full setup and configuration documentation lives on the Learn site.
Screenshots & Examples
A peek at sites running Mailroom.
Frequently Asked Questions
The most commonly asked questions about the Mailroom plugin
Is this a one-time purchase or a subscription?
Mailroom is a one-time purchase. You get all future updates and new features for free as long as your license stays active. There's no per-subscriber pricing and no cap on how many people or lists you have, so your newsletter doesn't get more expensive as it grows. Your mail provider still charges for sending, the same as it does today.
Does Mailroom work on Grav 1.7?
No. Mailroom is built for Grav 2 (2.1 or newer) and Admin Next, and it needs the API plugin for its admin screens. If you are still on 1.7, take a look at the Migration chapter on the Learn site.
Do I need a database server?
No. Mailroom stores everything in one SQLite file at user-data://mailroom/mailroom.sqlite, created and migrated the first time it's needed. It backs up and moves with your site like the rest of user/.
If you'd rather keep it in a server database, MySQL and PostgreSQL work too. Choose one on the Advanced tab of the plugin settings and run bin/plugin mailroom migrate.
Which mail services does it work with?
Mailroom sends through the Grav Email plugin, so anything the Email plugin can send through works, from plain SMTP to the transport plugins for the big providers.
Delivery reports, bounces and complaints come back by webhook from Mailgun, Postmark, SendGrid, Amazon SES, SMTP2GO, MailerSend and Resend. Without a webhook everything still sends, you just won't see what the provider did with each message.
Can I bring my list over from another service?
Yes. Export a CSV from where your list lives now and import it on the Subscribers screen, or with bin/plugin mailroom import:csv. Before anything is written, the preview tells you how many people would be new, already here, skipped or suppressed, and why. Say where these people agreed and it's kept in each person's consent history, and nobody who already left is put back.
Do I need cron?
You should add the Grav scheduler to your crontab, because it runs the worker that sends campaigns, moves automations along and retries anything that failed. Confirmation emails go out straight after the signup either way. bin/plugin mailroom status tells you when the worker hasn't run for a while, and prints the exact crontab line for your site.
Do my subscribers need an account?
No. Signing up, confirming, changing preferences and unsubscribing all work from the links in Mailroom's emails. Nobody gets a Grav account, and nobody needs a password.
How does it look with my theme?
The confirm, unsubscribe, preferences and browser view pages extend your theme's base template, so they carry your header, footer and fonts. Mailroom adds a small stylesheet you can switch off, and any of its templates can be overridden from your theme by keeping your own copy under the same name. The signup box works the same way.
What does Mailroom need to run?
Grav 2.1 or newer, PHP 8.3 with pdo_sqlite (or PDO MySQL or PostgreSQL for a server database), and these free plugins:
- API 1.0.31 or later, for the admin screens, the REST API and MCP
- Email 5.1.0 or later, configured and sending
The Form plugin is optional, for a signup on a form of your own.
Can I use Mailroom on multiple sites?
Per the Grav Premium License, you need a license for each site. Development and staging copies of the same site are covered by the same license. Get in touch if you need bulk pricing.