Leed sends email in two classes. They share one rendering engine, one sender address and one tracking pipeline, but they obey completely different rules about quotas, plan gates and where the send shows up afterwards. Naming which class you are in answers almost every question you will have on the rest of these pages — including the two that come up most often: why did this send cost me allotment? and why can I not find this email anywhere in the CMS?
The two classes
Every email Leed sends on your behalf belongs to a batch, and the batch carries a type that is stamped when the batch is created. That single value decides everything downstream. Two types — manual and campaign — are marketing. The rest are transactional.
| Batch type | What creates it | Class | Counts against the monthly allotment | Shows in Sent Emails |
|---|---|---|---|---|
manual | A blast you compose and send yourself | Marketing | Yes | Yes |
campaign | Nothing today — see the note below | Marketing | Yes | No |
confirmation | A form that has a response email; one batch per form, and a contact is added to it once | Transactional | No | No |
form | Nothing today | Transactional | No | No |
upload | A CSV import. These batches exist so you can filter on “everyone from this import” — they are never sent | Never sent | No | No |
The consequences follow mechanically. A marketing batch is checked against your plan’s marketingEmail feature gate before anything happens, is counted against your monthly allotment, and appears in Sent Emails. A transactional batch skips the gate, skips the meter, and has no listing screen of its own — you see it on the recipient’s contact record, not in an email report.
Marketing email
A marketing email is a blast: one message per recipient, rendered from a layout you wrote, addressed to a saved contact group. You compose it, Leed resolves the group into a recipient list, creates one manual batch, and fans the send out at 100 recipients per queue message. There is one composer, and it is the only screen in Leed that can start a marketing send.
The mechanics — the four fields, the confirmation dialog, what happens at the allotment, and how to read the results afterwards — are covered field by field in sending a marketing email. Recipients come from a contact group, which is the only object Leed will address an email to.
Note that campaign means something else here. Campaigns are an Engage planning surface for coordinating deliverables; they are described in campaigns and deliverables and they do not send email. If the words audience, contact group, campaign and batch are blurring together, the glossary pins each of them to one meaning.
Transactional email
Everything that is not a blast is transactional. It is free on every plan, invisible to the meter, and — this is the part that sends people hunting — it has no send screen. Below is everything Leed can put in somebody’s inbox on your behalf.
Layout-driven transactional email
Two things render one of your layouts without being marketing:
- A form’s response email. When a form has a response layout configured, each submission queues a send against that form’s
confirmationbatch. A contact is added to the batch the first time they submit and is not re-added afterwards, which is also why a repeat submitter does not get a duplicate row. If the form carries a gated download, the asset link is passed into the layout as theassetvariable. See response emails and gated downloads. - The self test-send. The Test button on a layout, and Send a test to yourself in the composer, both mail the rendered layout to your own account address. Test sends are classified transactional deliberately, so that someone on Free can preview a layout without a plan gate in the way.
Both go through the same render-and-send path as a blast, and both are tracked. Neither is metered.
Platform email Leed sends for you
These do not use your layouts, cannot be edited, and are named here only so nobody goes looking for a template that does not exist:
- Sign-in magic links and sign-in one-time codes — the two passwordless routes into the CMS. The code is used when you sign in as part of an OAuth or MCP consent flow; the link is used for ordinary app sign-in.
- Workspace invitations — sent when an administrator invites a team member.
- Page comment notifications — sent when someone comments on a page you are involved with. The behavior belongs to the editor and is described in comments and reactions.
- The Docs MCP reader one-time code — sent to a reader signing in to your documentation site’s MCP endpoint.
- The daily over-limit notice — sent to every active administrator while a meter is at or over its quota, and suppressed for seven days after each notice so a long overage does not become a daily nag.
- Internal form notifications — the “somebody filled in your form” email that goes to a person you nominated. This one is worth knowing about because it comes from a different address than everything else (see below).
| Trigger | Uses one of your layouts | Metered | Minimum plan | Where it is configured | |
|---|---|---|---|---|---|
| Marketing blast | You confirm Send in the composer | Yes | Yes | Starter | The composer |
| Form response email | A visitor submits a form that has a response layout | Yes | No | Free | The form’s settings |
| Layout test send | You press Test, or Send a test to yourself | Yes | No | Free | Not configurable — it always goes to you |
| Internal form notification | A form submission, to the people the form notifies | No | No | Free | The form’s settings |
| Sign-in magic link | Signing in by email | No | No | Free | Not configurable |
| Sign-in one-time code | Signing in during an OAuth or MCP flow | No | No | Free | Not configurable |
| Workspace invitation | An administrator invites a team member | No | No | Free | Settings → Team |
| Page comment notification | A comment on a page | No | No | Free | Not configurable |
| Docs MCP reader code | A reader signs in to your Docs MCP | No | No | Free | Not configurable |
| Over-limit notice | Daily, while a meter is at or over quota | No | No | Free | Not configurable |
The sender address
Every email rendered from one of your layouts — blast, form response or test — is sent from no-reply@ your public site domain, with your site title as the display name. If your site is example.com and its title is Acme Docs, recipients see Acme Docs <no-reply@example.com>.
Platform email is different, and deliberately so: it comes from Leed, not from you. Sign-in codes, invitations and over-limit notices are sent from no-reply@leed.ai, and internal form notifications from forms-noreply@leed.ai. Those addresses are not configurable and are not affected by anything on your domain.
What your own DNS has to do with any of this — SPF, DKIM and DMARC on the domain you send from — is covered in bounces and deliverability.
Who actually receives a send
The number you see in the composer’s Recipient Preview and the number that ends up in the Recipients column of Sent Emails are frequently different, and it is not a bug. Five independent narrowings sit between “contacts who match the group” and “messages that went out”.
- Contacts above your plan’s contact quota are locked. The visible window is the oldest contacts you captured, up to your quota. Locked contacts are excluded from every contact read — they cannot be listed, cannot be opened, and cannot be emailed by any route. Usage and limits explains the window and why the oldest survive.
- Do-not-contact is dropped at the API. Any contact carrying a do-not-contact flag is removed before the send is accepted. If nothing survives, the request is refused with
400 No opted in users in groupand no batch is created. - Opted-out and hard-bounced contacts are dropped at fan-out. A second pass, in the queue, removes anyone whose latest opt record says out and anyone flagged as a hard bounce. This is the pass that most often explains the gap: an opted-out contact still matches the group’s filters and is still counted in the Recipient Preview, and disappears only here.
- The per-recipient guards fire last. A recipient who hard-bounced or opted out between fan-out and delivery is skipped at the moment their individual message is about to be built.
- An already-sent row is never re-sent. Each recipient gets one row per batch, and a row that already carries a sent timestamp refuses a second send. Leed has no resend.
What Leed records
For each recipient of each batch, Leed writes one row and updates it in place. The row carries the moment it was sent plus four booleans — opened, clicked, unsubscribed, bounced — and a per-recipient hash that is what makes tracked links work. Those five values are what Sent Emails rolls up and what a contact’s email history renders.
Alongside them, granular event rows record individual hits: an open, a click on a page link, a click on a file, a click on the unsubscribe link. The booleans are always written; the granular events are best-effort. Do not expect the two to agree to the last unit — tracked links and open tracking explains where each number comes from and which one to trust for what.
The rest of the return path splits three ways, and each has its own page. Opens and clicks come back through the tracking endpoints. Unsubscribes come back through the same mechanism but start a flow of their own, described in unsubscribes and opt-outs. Delivery failures come back as bounce reports to that bouncer+ address, and how Leed classifies them — and what a hard bounce permanently does to a contact — is in bounces and deliverability.
The whole pipeline on one canvas
flowchart TD
A1["Composer<br/>New Email"] --> B1["POST /api/email<br/>marketing · metered · Starter+"]
A2["Form submission<br/>form has a response layout"] --> B2["form-fill event<br/>transactional · unmetered"]
A3["Test button"] --> B3["POST /api/email/test<br/>transactional · unmetered"]
B1 --> C["create-email-batch<br/>resolve group · drop opt-outs · drop hard bounces"]
C --> D["send-email<br/>one message per recipient"]
B2 --> D
D --> E["Render subject and body<br/>Mustache + this recipient's data"]
B3 --> E
E --> F["Rewrite customer-domain links<br/>into per-recipient /e/ URLs"]
F --> G{"Unsubscribe URL present<br/>in the rendered HTML?"}
G -- "no" --> X["Send throws<br/>this recipient is never mailed"]
G -- "yes" --> H["Send · stamp the sent time"]
F -. "a test send skips the check" .-> T["Delivered to your own<br/>account address"]
H --> I["Recipient's inbox"]
I --> J["Pixel and link hits return to /e/…<br/>opened · clicked · unsubscribed"]
I --> K["Delivery failure returns to<br/>bouncer+batch=contact@b.leed.ai<br/>bounced · hard bounce"]
H --> L[("The recipient's row")]
J --> L
K --> L
The branches matter more than the boxes. A form response email and a blast behave differently only until they reach the render step; after that they are the same code, which is why a layout written for one works in the other, and why a form email is tracked exactly as thoroughly as a blast. The one asymmetry worth remembering is the dotted edge: a test send skips the unsubscribe check that a real send enforces, so a layout can pass every test you throw at it and still fail on the first real recipient. That check, and how to satisfy it, is the sharpest edge in email layouts.
Where the composer lives
The composing surface is the Email Marketing screen at /emails, with four tabs: New Email, All Contacts, Groups and Sent Emails. It is not in the six-tab rail — it is reachable only by typing the URL, and it is kept alive until a redesigned tab replaces it. It is one of a handful of URLs that outlived the navigation they belonged to; legacy URLs that still work lists them all. The contact and group management on its middle two tabs is documented as part of Engage, in contacts and importing contacts.