emails.sh vs Loops
Loops is lifecycle email for SaaS with a transactional endpoint attached. emails.sh does both jobs on one API, priced separately so you buy one or both.
Marketing and lifecycle email · Loops claims checked July 2026
What Loops is
Loops is a modern marketing and lifecycle tool aimed squarely at SaaS companies. You store contacts with properties, build loops and campaigns off events, and write email in a clean editor rather than in code. Pricing is per contact rather than per email, with sending included, and there is a free tier for a small list. It also exposes a transactional endpoint so your product emails can go out through the same account, which is how many teams end up using it for both.
Where Loops is the better choice
Buy Loops if the person writing the email is not the person writing the code. Their editor, their contact properties, and their workflow builder are made for a marketer working alone, and ours are not: our merge syntax has no conditionals, there is no drag-and-drop layout tool, and there is no A/B testing at all. If a growth team needs to ship a re-engagement sequence on a Thursday without a developer, that is Loops, and it is not close.
Where emails.sh differs
Two things. First, the pricing is split the way the work is: transactional mail is per email sent and counts no contacts, so you do not pay a monthly storage fee for a hundred thousand users who get a receipt once. Marketing is per contact and you buy it only if you mail a list. Second, the lifecycle side here is a text file. An automation is YAML that you can pull, diff in a pull request, and push from CI, and the canvas in the dashboard is a second view of that same document.
Two prices, so you do not pay for both
Transactional is per email sent and counts no contacts. Marketing is per contact stored and carries no per-email charge. A product with 200,000 users and a 4,000-person announcement list pays for 4,000 contacts here, where a single contact-priced account would charge for all 200,000 because they are in the database.
Sequences live in your repository
An automation is a YAML document: a trigger, a when filter, and a list of steps that each do, wait, or branch. GET it, commit it, review the diff, PUT it back from CI. A push is stored as the exact bytes you sent, so the next pull is not a spurious diff, and every write is a version you can read and restore.
Transactional mail kept apart from campaigns
Campaigns generate complaints, and complaints move reputation. We separate pools by send type so a promotion cannot push your verification links into spam. If both kinds of mail go out of one marketing account on one reputation, that risk is real.
A developer surface, including inbound
Nine language clients, signed webhooks for delivered, bounced, and complained, per-message status at GET /v1/emails/:id, and inbound MX with parsed, threaded replies. A marketing tool has a transactional endpoint; this is a transactional product.
Side by side
Every row is a claim we could defend with their documentation open beside it. Where they are ahead, the row says so.
- Pricing shape
- emails.sh Two prices, bought separately. Transactional is per email sent and counts no contacts. Marketing is per contact stored, in tiers from 5,000, with no per-email charge on sends to your own audiences. Neither plan requires the other, so a product that sends receipts to 200,000 users and mails a 4,000-person list pays for 4,000 contacts.
- Loops Per contact stored, with sending included. Check their pricing page for current bands.
- Free tier
- emails.sh Two free tiers that do not require each other: 3,000 transactional emails a month, and 1,000 contacts with unsubscribe handling and broadcast sending included.
- Loops A free tier for a small contact list, with a send allowance and their footer on messages.
- Sending domains
- emails.sh One screen: add the domain, copy SPF, DKIM, and return-path records, watch them go green. Unlimited domains on every plan.
- Loops Domain authentication with DKIM, set up once for the account.
- Deliverability posture
- emails.sh Transactional mail never shares a pool with a campaign, because a receipt landing in spam behind a promotion is the failure that costs you.
- Loops Good, and shaped around marketing sending patterns.
- Receiving mail
- emails.sh Inbound MX, parsed MIME, and In-Reply-To threading, so a reply arrives as part of a conversation you can query rather than as a raw webhook body.
- Loops Not a receiving product.
- Logs and retention
- emails.sh Every message searchable in the dashboard and readable at GET /v1/emails/:id, with its delivery, bounce, and complaint events attached.
- Loops Campaign and contact-level reporting rather than a per-message developer log.
- Templates
- emails.sh Hosted templates with immutable versions, published separately from saving, referenced by slug from a send, a broadcast, or an automation step. Merge syntax is {{ variable }} with no conditionals or loops, and there is no drag-and-drop editor. If a non-developer needs to lay out an email without touching HTML, that is a real reason to pick the other product.
- Loops A strong visual editor. This is a large part of what you are buying.
- SDKs and frameworks
- emails.sh Nine clients (node and typescript, python, php, ruby, go, rust, java, .net, elixir) plus curl, and framework guides from Next.js to Laravel, Rails, and Django.
- Loops A JavaScript client and a REST API, with a narrower language range.
- Marketing and lifecycle
- emails.sh Audiences with double opt-in, flat-rule segments, scheduled broadcasts, and automations built on a canvas that is also a YAML file you can review in a pull request. No A/B testing, no visual builder, no signup forms.
- Loops Contacts, mailing lists, and audience segments, plus Campaigns and Workflows with timers, filters, and branch nodes. This is the product rather than a side of it.
- Webhooks
- emails.sh email.delivered, email.bounced, and email.complained, each signed with x-emailssh-signature so you can verify the body before you act on it.
- Loops Event webhooks aimed at syncing contact and campaign state.
- Path for a coding agent
- emails.sh Every page served as markdown at the same path plus .md, an /llms.txt index of the whole site, and a Cursor and Claude Code skill you install once.
- Loops Human documentation. No installable assistant skill.
- Support
- emails.sh Email support on every plan including the free one, answered by the people who wrote the API. We are small, and that cuts both ways.
- Loops Responsive, with a small and well-regarded team behind it.
Running both, or moving the transactional half
Most teams should not choose. Keep Loops for lifecycle and campaigns, and move the mail your code sends here.
- 01
Split the traffic by who writes it
If a human writes it in an editor and it goes to a segment, it belongs in Loops. If your code triggers it for one person at a moment they are waiting, it belongs here. That line is cleaner than any feature comparison.
- 02
Use a separate subdomain for each
Send campaigns from news.yourdomain.com and transactional from mail.yourdomain.com. Each publishes its own DKIM records, and a complaint on the campaign subdomain cannot follow your receipts. This is worth doing even if you never move a message.
- 03
Port the transactional templates
Loops transactional templates are edited in their UI. Bring the HTML into your repo, or store it as a template here and reference it by id. Keep the variable names identical so the calling code changes by one function name.
- 04
Point the webhooks at your own handler
Subscribe to email.delivered, email.bounced, and email.complained, verify x-emailssh-signature, and write bounces back onto the user record. Suppression on the transactional side is now yours to see rather than a list inside a marketing tool.
Questions
Can Loops send transactional email?
Yes. It has a transactional endpoint and plenty of teams use it for both. The question is whether you want your receipts priced against your contact count and sharing a sending reputation with your campaigns. Here those are two prices and two pools, and the pool separation is enforced in code: a broadcast refuses to send if it would share an IP pool with transactional mail.
Can emails.sh replace Loops?
For a developer-run lifecycle programme, increasingly yes: there are audiences, segments, scheduled broadcasts, and automations with waits and branches, and the automation is a file you can review. For a marketer-run one, no. There is no A/B testing, no drag-and-drop editor, no signup forms, and no per-recipient send-time optimisation, and those absences are the difference between the two products.
Which is cheaper?
It depends on how much of your audience you actually mail. Transactional volume costs nothing per contact here, so a large user base that receives receipts is structurally cheaper. A list you genuinely mail is priced per contact on both, so compare the tiers directly. Count your contacts and your sends separately before you decide, because they are billed separately.
How do I keep both from hurting deliverability?
Send from different subdomains. Campaigns from one, transactional from another, each with its own DKIM records. Complaints then attach to the subdomain that earned them, which is the whole point of the separation.
Looking for a Loops alternative?
These products lead with the list and add a send endpoint. We came the other way: the transactional API is the product, and audiences, broadcasts, and automations were built on top of it, so both kinds of mail share your domains, your suppression list, and one delivery log while being kept off each other's sending reputation. Where they are still ahead is the editor, the split testing, and everything a marketer needs to work without a developer.
The free tier is 3,000 emails a month, 100 a day, no card, sending from your own verified domain, with delivery logs, webhooks, and inbound included. Enough to run real traffic through it before you decide.
More Marketing and lifecycle email