URL: /plays/cold-email · Id: `play:cold-email`

# Cold email

> Writes first to people at companies that showed two fresh public reasons to talk, three short emails at most, and answers every reply by kind.

Writes first to people at companies that showed two fresh public reasons to talk, three short emails at most, and answers every reply by kind.

```text title="Set it up · Ask"
Be our SDR: write to property managers with 50 to 500 units when two fresh public reasons show up, one of them announced. Three short emails at most, plain text, no tracking, and I review the first 20 myself. Companies over 1,000 units go from my Mailbox, and I approve each one. Show me what’s missing; don’t send.
```

```text title="Run one · Ask"
Hand today’s first Prospect to the SDR agent and show me what it chose and why. Don’t send.
```

```ts title="Run one · SDK"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Opening.published", "Company.filed", "Review.published", "Company.funded", "Monitor.checked", "Visit.recorded", "Conversation.answered")', limit: 1 })   // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' })   // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` })   // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` })   // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
```

```json title="Run one · Response · sample"
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_617",
    "$type": "Decision",
    "choice": "cold-email-thread",
    "reason": "Cedar Hollow Rentals filed a rental registration for 64 new units on Oct 14 and posted a leasing coordinator opening on Oct 16: two fresh Events, one announced",
    "stakes": "low",
    "options": [
      "cold-email-thread",
      "cold-email-thread-founder",
      "no-angle",
      "market-hold"
    ],
    "by": "worker_2",
    "on": "prospect_212",
    "expected": "an Interested reply within 10d",
    "reopensWhen": "no Conversation.answered from prospect_212 within 10d; the thread then parks for 30d"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Contact.enrich",
      "checks": [
        {
          "check": "customer-collision",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Prospect.engage",
      "checks": []
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingTime",
      "mode": "try",
      "by": "worker_2",
      "verb": "Message.schedule",
      "checks": [
        {
          "check": "owned-by-a-person",
          "status": "pass"
        },
        {
          "check": "mailbox-warm",
          "status": "pass"
        },
        {
          "check": "customer-collision",
          "status": "pass"
        },
        {
          "check": "fingerprint",
          "status": "pass"
        },
        {
          "check": "market-hold",
          "status": "pass"
        }
      ]
    }
  ]
}
```

`action_3` is the first email of the thread, held for its 1-hour window, which you can stop (Who runs it). The second email follows in 3 days only if Maya has not replied.

`3.3 Interested replies per 100 delivered · no halves on the leaf · n 152 · path → arr`

| Try another: the Prospect | Choice | Reason |
| --- | --- | --- |
| Cedar Hollow Rentals: a 64-unit rental registration, then a leasing coordinator opening | `cold-email-thread` | two fresh Events, one announced |
| Oakridge Management: 1,100 units, a new regional office announced | `cold-email-thread-founder` | over 1,000 units: it sends from your Mailbox once you approve it |
| Pinecrest Homes: one hiring post, nothing announced | `no-angle` | one fresh Event and none announced: NO_ANGLE, nothing sends |
| A Prospect in a Market with no verified row | `market-hold` | the draft holds; it never retries another way |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$160 ARR a month at 105 delivered | 45 min week 1 (20 drafts by hand), then 15 min a week | $0.05 per draft, ~$5 a month at 105 | Day 18: first Interested reply | 500+ companies that fit, under 5 inbound a month | 5+ inbound a month: `instant-response` · no Domain set up: warm one Mailbox (<Op verb="Mailbox.warm" />) |

**Where it sits:** **Stranger** → Lead → Trialing → Activated → At risk → Churned → Won back · Positive reply rate → New Leads → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +3.4 Interested replies per 100 delivered (Other Startups’ results; the leaf has no held-back half) × 105 delivered a month × 0.55 replies to Meetings × 0.25 Meetings to paid × $348 first order ARR ≈ +$163. Under First signal: The leaf reads at 300 delivered, about 12 weeks at 105 a month; the held-back companies read Meetings 60 days after the first send.

`sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Company.filed · first draft in review 2 h 40 min after the mint run · 9 keys Not live yet`

**Also runs as:** [Moment outreach](/plays/moment-outreach).

## Start it this week
```bash
npx startup-builder add play cold-email   # 1 · writes plays/cold-email.mdx (Not live yet, gaps #5)

# 2 · dry run; below, its 422 on 2026-08-24
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"cold-email"}'

# 3 · keep it, at You approve each one
curl -X POST https://api.sb/leaseline.app/campaigns \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"cold-email"}'

# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/cold-email \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":null}'

# off: no new email; replies still come to you
curl -X PATCH https://api.sb/leaseline.app/campaigns/cold-email \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "cold-email can’t start yet: 2 checks fail and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "2,140 companies fit; 3 inbound a month",
      "doc": "/plays/cold-email#check-use-when",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "no cold email sent in 90 days",
      "doc": "/plays/cold-email#check-baseline",
      "fix": "The leaf starts at your first send; the 10 % held-back companies read Meetings.",
      "then": "Metric.query"
    },
    {
      "check": "domain-authenticated",
      "status": "pass",
      "observed": "leaseline.app: 3 of 3 records resolve",
      "doc": "/plays/cold-email#check-domain-authenticated",
      "then": "Domain.authenticate"
    },
    {
      "check": "mailbox-warm",
      "status": "fail",
      "observed": "0 of 14 days",
      "doc": "/plays/cold-email#check-mailbox-warm",
      "fix": "Start the warm-up today; the first email sends on day 15.",
      "then": "Mailbox.warm"
    },
    {
      "check": "approved-pages",
      "status": "fail",
      "doc": "/plays/cold-email#check-approved-pages",
      "fix": "Publish your pricing Page; every email states only what your pages say.",
      "then": "Site.publish"
    },
    {
      "check": "role-unstaffed",
      "status": "pass",
      "roles": [],
      "owned": 31,
      "doc": "/plays/cold-email#check-role-unstaffed",
      "then": "Role.staff"
    }
  ]
}
```

| Check | Fix (one call) | Your time | Wait |
| --- | --- | --- | --- |
| <a id="check-use-when"></a>`use-when` · <a id="check-baseline"></a>`baseline` · pass: 2,140 companies fit, 3 inbound a month · warn: no history (gaps #8) | <Op verb="Metric.query" /> on `positive-reply-rate`; the held-back companies fill Before | 1 min | none |
| <a id="check-domain-authenticated"></a>`domain-authenticated` · <a id="check-mailbox-warm"></a>`mailbox-warm` · pass · fail: 0 of 14 days (gaps #1) | <Op verb="Mailbox.warm" /> on dana@leaseline.app at 40 a day | 2 min | 14 days; warm intros keep running |
| <a id="check-approved-pages"></a>`approved-pages` · fail (gaps #8) | <Op verb="Site.publish" /> your pricing Page | 15 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · pass (gaps #8): AE · Priya Shah takes Interested replies; 31 open Leads have a person owner | <Op verb="Role.staff" />, already done | 0 min | none |

`Your number · Before none sent · Now 3.3 Interested replies per 100 delivered · Target 4 by Dec 31 · no halves on the leaf · n 152 delivered`

Each draft costs about $0.05 to research and write, and research stops at $0.10 per Prospect. Mailboxes cost $7 to $14 a month each, paid by the outbound Domain pool. That comes to about $5 a month at 105 delivered, plus one Mailbox.

## When it starts
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| A company files a permit, lease, license or rental registration | `public-filing` | `event` on `Company.filed` where a permit, lease, license or registration the ICP files | 14d | the daily mint run’s public-record watch, 06:00 |
| A company posts an opening for the role Leaseline serves | `hiring` | `event` on `Opening.published` where the opening is for the role the Product serves or replaces | 30d | the same mint run |
| The date a Person’s own reply named arrives | `not-now-date` | `at` on `Conversation.answered` where the date the Person’s own reply named | 14d | their reply, read by the reply matrix |
| + 5 more for complaints about an alternative, funding, technology changes, pricing visits and named referrals (`?lanes=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$id": "https://api.sb/leaseline.app/events/event_1240",
  "$type": "Event",
  "name": "Company.filed",
  "at": "2026-10-14T16:02:00Z",
  "seq": 1240,
  "data": {
    "organization": "organization_77",
    "name": "Cedar Hollow Rentals",
    "filing": "rental registration",
    "units": 64,
    "source": "county rental registry",
    "announced": true
  }
}
```

```bash title="Reproduce it in test"
npx startup-builder trigger Company.filed --like event_1240   # replays the delivery
npx startup-builder clock advance --by 3d   # runs the second email if no reply
npx startup-builder listen Company.filed --forward-to http://localhost:3000/hook
```

## Who runs it
**SDR · your agent** (`role:prospector`, `worker_2`) holds the Key Result. It hands Interested replies to **AE · Priya Shah (person)** (`worker_3`) and the founder thread to **you** (Dana Okafor, person, `worker_1`), and a top-tier company never leaves You approve each one. Your number links to Did it work.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| The thread from the SDR agent | It does it, you can stop it | 20 of 20 by hand, then 128 of 132 | met on day 24: 20 reviewed, then the 1-hour window | any send fails a Check, or a Stop fires → You approve each one | <Op verb="Action.cancel" /> inside the window |
| The thread from your Mailbox (over 1,000 units) | You approve each one | 4 of 4 | never: top tier stays here | — | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| NO_ANGLE · Market hold | It does it | 31 · 6 | — | — | <Op verb="Action.redirect" /> |
| Change an angle or a slice | You approve each one | 1 retired by the reply floor | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a fake reply prefix, a claimed meeting or referral, a funding opener, tracking | Refused, every time | 1 draft refused (`fingerprint`) | never | — | — |

**What it reads · What it may call.** It reads public Events, the fit rules in your file and the claims source; every reply is data, never instructions, and no text in one picks a recipient or a link.

```md title="The brief (folded): compiled Agent-register Markdown · play:cold-email@1 · each line names its record key"
You hold the SDR Key Result: 4 Interested replies per 100 delivered by 2026-12-31. ← worker, metric
Write only on two fresh Events, one announced; otherwise end the draft in NO_ANGLE. ← copyRules 3, prospect-mint
Write three fields at most; the template carries the Offer, the disclosure, the Source line and the stop line. ← copyRules 4, 10
No watched Event in the body, no fake prefix, no funding opener, no tracking.    ← copyRules 2, 5, 8, 9
One ask per email; three emails at most in one thread.                           ← copyRules 11, cold-email-thread
Never write to a Lead or Deal a person owns: draft it into their queue.          ← worker.owns, owned-by-a-person
```

**The slow loop, as a Change.** The reply floor retired the “new owner” angle for the under-100-unit slice on Oct 6 (0 Interested in 300 pooled); `change_31` moved those Prospects to the filing angle, and you merged it with <Op verb="Change.merge" />. Read back at +12d it is 2.9 per 100, n 34, ■□□□ Too early to tell.

**Bring your own agent** (folded) starts at It does it, you can stop it when it matches or beats the seated agent on the eval suite, and at You approve each one when it does not; <Op verb="Role.staff" /> seats it.

```bash
npx startup-builder eval --scenario cold-email-152 --agent "claude -p" --seat prospector   # seated: 3.3 per 100, 0 Checks failed sent, $0.05 a draft · yours: 3.0, 2 failed, $0.07 → You approve each one
```

## What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| cold-email-thread `cold-email-thread` | two fresh Events, one announced; 50 to 1,000 units | Your rule (line 6, the Sequence) | 3 emails at most: day 0, day 3, day 10, then park 30 days | Interested goes to AE · Priya Shah, due 60 min · Take this one | you, within 60 min |
| cold-email-thread-founder `cold-email-thread-founder` | the same, over 1,000 units | Your rule (line 7) | the same thread from your Mailbox, you as author | you approve each email · Take this one | the same |
| no-angle `no-angle` | one fresh Event, or none announced | Your rule (copyRules 3) | nothing; the company waits for a second Event | nobody | the same |
| market-hold `market-hold` | an unresolved Market or an unverified row | Your rule (the Market hold) | nothing; the draft holds and never retries another way | nobody | the same |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | “Yes, Thursday afternoon?” | books it on the AE’s calendar; the Brief goes with it (When it hands to you) | AE · Priya Shah (person) | 60 min | <Op verb="Meeting.book" /> |
| Send me pricing | “What does it cost for 64 units?” | the Pricing Page’s list Price for Pro and Team, and one next step | SDR · your agent | 1 business hour | <Op verb="Conversation.answer" /> |
| Not now | “Write me in January.” | the thread stops; one email on the date they named, quoting their words | SDR · your agent | the date they named | <Op verb="Message.schedule" /> |
| Wrong person | “Talk to Lee, our ops lead.” | asks if they’ll say so to Lee; it never writes to Lee until they agree | SDR · your agent | 1 business day | <Op verb="Conversation.answer" /> |
| Out of office | an auto-reply until Oct 28 | the next email waits for the return date | nobody | the return date | <Op verb="Message.schedule" /> |
| Question it can’t answer | “Do you sync with our accounting system?” | To a person, the question in the Brief | AE · Priya Shah | 60 min | <Op verb="Conversation.escalate" /> |
| Stop | “Remove me.” | nothing else sends to them, from any of your Startups | nobody | at once | <Op verb="Contact.suppress" /> |

## When it hands to you
Interested replies and questions it can’t answer go to **AE · Priya Shah (person)**; the founder thread comes to **you** (Dana Okafor, person). One Brief per Role, as captured (`brief` is Not live yet, gaps #7).

```json title="What lands in each queue · sample"
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_622",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-15T14:12:00Z",
    "on": "prospect_212",
    "brief": {
      "who": "Maya Chen, Cedar Hollow Rentals",
      "said": "Yes, Thursday afternoon?",
      "why": "a 64-unit rental registration on Oct 14 and a leasing coordinator opening",
      "booked": "Thu 15:00 Central",
      "never": [
        "the watched Events named back to her",
        "a price beyond the list",
        "a discount"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_598",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-09-22T17:00:00Z",
    "on": "prospect_188",
    "brief": {
      "who": "Oakridge Management, 1,100 units",
      "chose": "cold-email-thread-founder",
      "why": "over 1,000 units: from your Mailbox, you approve each email",
      "draft": "approval_61"
    }
  }
]
```

Each receiver answers with <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason, or <Op verb="Action.redirect" />, each a one-call window. Once a person claims, the thread’s pending emails cancel with `claimedByPerson` (Not live yet, gaps #7), and every reply goes to the claimer’s queue. An Interested reply nobody claims in 60 min pauses new sends (`unanswered-positive`) and goes up through <Op verb="Task.escalate" />.

**On time:** AE · Priya Shah, 5 of 5 claimed within 60 min, median 14 min; you, 4 of 4 approvals before their deadline; n 9, ■□□□ Too early to tell beside Other Startups’ 92 % on time. **Your queue:** counted by kind: in week 3, 20 drafts to review by hand; since then, about 1 Interested reply and 1 approval a week.

**The fixed line:** <Op verb="Deal.assign" /> sets `owner` to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.

## When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
| --- | --- | --- | --- |
| <a id="check-owned-by-a-person"></a>`owned-by-a-person` (rule j; Not live yet, gaps #8) | an email to a Contact whose Lead, open Deal or Conversation a person owns | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| `mailbox-warm` (on <Op verb="Message.schedule" />; gaps #1) | a first cold email from a Mailbox that has not finished warming | Wait for the warm-up to finish, 14 days from day 0. | <Op verb="Mailbox.warm" /> |
| <a id="check-customer-collision"></a>`customer-collision` (Not live yet, gaps #1) | a cold email to a Contact with an active Subscription | Send it to their CSM instead: the Contact leaves the List. | <Op verb="Lead.assign" /> |
| <a id="check-fingerprint"></a>`fingerprint` (the record’s Fingerprint stop) | a draft too close to many bodies sent in the last 30 days | Rewrite the reason line from this company’s own Event. | <Op verb="Content.draft" /> |
| <a id="check-market-hold"></a>`market-hold` (the record’s Market hold) | a draft for an unresolved Market or an unverified row | Verify the Market row; the draft never retries another way. | <Op verb="Task.assign" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-bounce"></a>`bounce` | hard bounces over 2 % of a Mailbox’s day, at 20+ sends | <Op verb="Mailbox.rest" />; over 3 % of its last 100, <Op verb="Mailbox.retire" /> |
| <a id="stop-shadow-complaint"></a>`shadow-complaint` | stop, remove-me and hostile replies over 1 % of a Domain’s last 1,000 | the Domain pauses |
| <a id="stop-provider-spam"></a>`provider-spam` | a provider-reported spam rate of 0.08 % | every Mailbox on that provider pauses |
| <a id="stop-placement"></a>`placement` | inbox placement under 70 % on a seed test | <Op verb="Mailbox.rest" /> |
| <a id="stop-blocklist"></a>`blocklist` | a blocklist listing | the Domain retires; a warmed spare takes its slot |
| <a id="stop-authentication"></a>`authentication` | the Monday check finds SPF, DKIM, DMARC or the stop header failing | the Domain pauses; <Op verb="Domain.authenticate" /> |
| <a id="stop-reply-floor"></a>`reply-floor` | replies under 1 % after 300 delivered in one angle and slice | those cells stop; no Interested reply retires the angle |
| <a id="stop-negative-reply"></a>`negative-reply` | stop and hostile replies over 3 % of a template’s last 100 | the template pauses |
| <a id="stop-unanswered-positive"></a>`unanswered-positive` (standard `response-60m`) | an Interested reply waits past its deadline | new sends pause until it is answered |
| <a id="stop-wrong-person"></a>`wrong-person` | the monthly hand check of 50 finds over 10 % wrong-person | minting halts |
| <a id="stop-fleet-canary"></a>`fleet-canary` | a bounce or placement drop across 30 other Startups on one provider within an hour | the Play pauses across your Startups |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every Mailbox stops; replies still come to you |

The captured refusal, then the Stop that fired as a `Campaign.paused` reason (Not live yet, gaps #2); the rewrite that sent is the Brookline thread in Example.

```json title="The captured refusal · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "Your SDR agent’s first cold email did not send: dana@leaseline.app has warmed 3 of 14 days.",
  "checks": [
    {
      "check": "domain-authenticated",
      "status": "pass"
    },
    {
      "check": "mailbox-warm",
      "status": "fail",
      "observed": "3 of 14 days",
      "doc": "/plays/cold-email#check-mailbox-warm",
      "fix": "Wait 11 days; warm intros keep running.",
      "then": "Mailbox.warm"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "reason": {
      "limit": "placement",
      "observed": "64 %",
      "bound": "70 %",
      "window": "1 seed test"
    },
    "doc": "/plays/cold-email#stop-placement",
    "task": "task_588"
  }
]
```

## Did it work
A held-back company gets no email, so it can’t reply: the leaf has no held-back half and prints beside Other Startups’ results. The 10 % of companies held back at random read Meetings and dollars from the same assignment (rules m–o). Each figure’s call is <Op verb="Metric.query" /> by node, and every node above the leaf is Not live yet (gaps #4).

`3.3 Interested replies per 100 delivered · no halves on the leaf · n 152 · path → arr`

| Node | Written to (90 %) | Held back (10 %) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `positive-reply-rate` | 3.3 per 100 delivered (5 of 152) | no email, so no reply | — (no halves on the leaf) | — | Other Startups’ results 3.4 per 100, ■■■□ Likely, n 41,200 delivered |
| `new-leads` ↑ | 3.6 Leads per 100 companies (5 of 139) | 0 (0 of 15) | +3.6 [−4.1, +7.9] | ■□□□ Too early to tell | held back at random · n 154 companies · 31 still maturing |
| `new-arr` ↑ | $348, 1 Customer · Booked $348: credited, not all caused by this Play | $0, 0 Customers | +$250 per 100 companies [−$240, +$740] · Worth about +$160 a month | ■□□□ Too early to tell (1 vs 0 Customers) | the same assignment · 2 trials still deciding |
| `net-new-arr` · `arr` | +$348 | $0 | carried: it moves no other bridge term | ■□□□ Too early to tell | carried from `new-arr` |

The leaf counts Interested replies per 100 delivered first emails, over 30d, to 300 delivered. The held-back read counts Leads and Meetings from each company within 60 days of its draw, held-back companies included, whoever reached them.

**How it moves it:** each first email cites one public reason from that week in 62 words median, with one ask, from a warmed Mailbox at 96 % inbox placement.

**Guardrails:** treated against held back: Meetings held per Lead, 0.60 against —, and unsubscribes plus stop replies, 1.3 % of delivered against the 3 % Stop.

```json title="The Campaign card · sample"
{
  "$id": "https://api.sb/leaseline.app/campaigns/cold-email",
  "$type": "Campaign",
  "play": "play:cold-email@1",
  "path": [
    "positive-reply-rate",
    "new-leads",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "new-leads",
    "unit": "per-100",
    "heldBack": 15,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 152,
    "maturing": 31,
    "interval": null,
    "readability": "inadmissible",
    "basis": "held-back",
    "pooled": false
  },
  "ledger": {
    "spend": 14,
    "workerCost": 9,
    "hours": 1.9,
    "pipelineArr": 1296,
    "wonArr": 348,
    "projectedArr": 163,
    "paybackDays": 66
  }
}
```

Outside benchmark: the median sequence went to 40 recipients in 2024, down from 180 in 2022, as senders cut volume (a sales-engagement vendor’s send data, 2026-01).

**Before it · After it.** Before it: `positioning-tournament` picks the angle and the List comes from your Audience file. After it: `instant-response` answers people who write back on a form, `lead-nurture` hears Not now, and `moment-outreach` runs inside it as the window rows of When it starts.

## Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days); dana@leaseline.app warmed for 14 days, so the first email sent on day 15. 154 companies were drawn, 15 held back at random, and 152 first emails reached 139 companies. Read every captured thread at `?threads=all`; three follow the tables.

| What happened, by route | Prospects | Delivered | Replies · Meetings · Won (credited, not all caused by this Play) |
| --- | --- | --- | --- |
| The thread from the SDR agent | 148 | 148 first, 102 second, 61 third | 10 · 3 · 1 on Pro ($348) |
| The thread from your Mailbox (over 1,000 units) | 4 | 4 first, 3 second | 1 · 0 · 0 |
| NO_ANGLE · Market hold | 31 · 6 | 0 · 0 | — |
| Replies by kind | Interested 5 · pricing 1 · Not now 2 · wrong person 1 · out of office 1 · Stop 1 | — | — |
| At 100 delivered a month (about the Use it when volume) | about 300 delivered in 12 weeks | the leaf reads then | Other Startups’ results: 3.4 per 100, ■■■□ Likely, n 41,200 |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_118` Campaign.created | the three steps; the dry run fails `mailbox-warm` and `approved-pages` | 20 min |
| 0 | `event_120` Mailbox.warmed | the warm-up starts on dana@leaseline.app at 40 a day | 2 min |
| 3 | `event_177` Action.refused | `mailbox-warm` held the first email at 3 of 14 days | — |
| 15 | `event_301` Message.scheduled | the first emails send; you reviewed 20 drafts by hand | 25 min |
| 18 | `event_342` Conversation.answered | the first Interested reply, booked with Priya | — |
| 24 | `event_388` Role.updated | promoted: emails send after a 1-hour window | — |
| 33 | `event_470` Campaign.paused | `placement` at 64 % rested the Mailbox 2 days; it came back at 96 % | 5 min |
| 43 · 55 | `event_590` Change.merged · `event_701` Readout.created | the reply floor retired one angle; read back at 2.9 per 100, n 34 | 5 min |
| 1–56 | `event_302` Approval.created, first of 24 | you reviewed 20 drafts and approved 4 founder emails; weekly reviews, from the <Op verb="Task.next" /> log | 50 min · **total 1.9 h measured, 2 h asked** |

> **SDR · your agent → Maya Chen, Cedar Hollow Rentals, Oct 15, 08:40** · Subject: renewal notices for 64 new units · Hi Maya, Cedar Hollow’s registration for 64 new units on Ash Street went on the county record on Oct 14.¹ Leaseline sends every renewal notice 60 days out, per owner, from one calendar.² Worth 15 minutes before those leases start?³ *Signed with the Role’s disclosure line, the Source line and the stop line.*⁴
>
> **Maya, 13:12** · “Yes, Thursday afternoon?” <Op verb="Meeting.book" /> booked Thu 15:00 on Priya’s calendar, and the Brief reached her at 13:13 (When it hands to you).

```diff title="Brookline Living, 2026-09-16 · the draft fingerprint refused, then the rewrite that sent"
- Saw you’re growing fast. Leaseline helps teams like yours scale renewals.
+ Your opening for a leasing coordinator lists renewal notices as half the role.
```

> **Lee Park, Harbor Point Homes, 2026-10-07 10:20** · “Do you sync with our accounting system?” · **SDR · your agent, 10:21** · *Good question for our account lead. Priya replies by 11:21 today.*⁵ The Brief went to Priya (`task_640`); she answered at 10:58.

¹ An announced Event with its public source; the second Event, the opening, stays in the Source line. ² Every sentence maps to an approved Page. ³ One ask, at opinion grade. ⁴ The fixed lines, compiled from the Role’s Settings and the template. ⁵ The routed line, compiled from the Role’s Settings.

## Your settings
```mdx title="plays/cold-email.mdx"
---
holdout: 0.1      # 1 in 10 companies drawn gets no email
mailbox: dana@leaseline.app
cap: 25           # first emails a day per Mailbox
---
Write to property managers with 50 to 500 units on two fresh public reasons, one announced.
Over 1,000 units, send from my Mailbox; I approve each one.
```

```text
$ npx startup-builder show plays/cold-email
holdout 0.1 · mailbox dana@leaseline.app · cap 25 · founder over 1,000 units     your file  plays/cold-email.mdx:2-4,6-7 (Ask 2026-08-24; angle retired by change_31, 2026-10-06)
family demand · worker role:prospector, owns never · chooses none (D38) · sequences cold-email-thread, cold-email-thread-founder, not-now-recontact, referral-first-touch · approval delay-window · checks owned-by-a-person, mailbox-warm, customer-collision, fingerprint, market-hold · stops 12 · placements gmail, outlook, yahoo-mail    catalog  play:cold-email@1 (Not live yet, gaps #5)
```

### Every key from the catalog
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-prospect-mint"></a>`prospect-mint` | Prospect mint: Turns Monitor Events on watched Organizations into verified Prospects, each with a live reason, grouped into cells of 50 or fewer. Starts at Sends nothing. |
| Tactic | <a id="tactic-cold-email-compose"></a>`cold-email-compose` | Cold email compose: Researches one Organization, fills three fields of the founder’s template at most, and checks the draft against the claims source, or returns no angle. Starts at You approve each one. |
| Tactic | <a id="tactic-send-gate-check"></a>`send-gate-check` | Send gate check: Checks Suppression, a live reason, the Market, the basis stamp, the Person-month grant, the facts and the labels before any cold Message exists. Starts at Sends nothing. |
| Tactic | <a id="tactic-cold-email-send"></a>`cold-email-send` | Cold email send: Sends a passed draft as plain text from an outbound Mailbox with tracking off, records it with its reason and stamp, and handles bounces. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-reply-matrix"></a>`reply-matrix` | Reply matrix: Labels every outreach reply with one of 11 labels, maps it to one of seven reply kinds, and runs that kind’s move by its deadline. Starts at You approve each one. |
| Tactic | <a id="tactic-sending-stop-loss"></a>`sending-stop-loss` | Sending stop loss: Reads the Play’s own bounces, replies and seed tests on every send, and rests, pauses or retires a Mailbox, Domain, cell or the Play. Starts at Sends nothing. |
| Trigger | <a id="trigger-hiring"></a>`hiring` | Opening published: `event` on `Opening.published`, window 30d. |
| Trigger | <a id="trigger-public-filing"></a>`public-filing` | Public filing: `event` on `Company.filed`, window 14d. |
| Trigger | <a id="trigger-competitor-complaint"></a>`competitor-complaint` | Competitor complaint: `event` on `Review.published`, window 7d. |
| Trigger | <a id="trigger-funding"></a>`funding` | Funding: `at` on `Company.funded`, window 45d. |
| Trigger | <a id="trigger-technology-change"></a>`technology-change` | Technology change: `event` on `Monitor.checked`, window 30d. |
| Trigger | <a id="trigger-pricing-visit"></a>`pricing-visit` | Pricing visit: `event` on `Visit.recorded`, window 72h. |
| Trigger | <a id="trigger-not-now-date"></a>`not-now-date` | Not now date: `at` on `Conversation.answered`, window 14d. |
| Trigger | <a id="trigger-referral-named"></a>`referral-named` | Referral named: `event` on `Conversation.answered`, window 7d. |
| Sequence | <a id="sequence-cold-email-thread"></a>`cold-email-thread` | Cold email thread: 4 steps; it ends on Any reply; A bounce; Suppression at any scope; A booked Meeting; An open Deal; An expired reason. |
| Sequence | <a id="sequence-cold-email-thread-founder"></a>`cold-email-thread-founder` | Cold email thread founder: 4 steps; it ends on Any reply; A bounce; Suppression at any scope; A booked Meeting; An open Deal; An expired reason; The Mandate paused or revoked. |
| Sequence | <a id="sequence-not-now-recontact"></a>`not-now-recontact` | Not now recontact: 1 steps; it ends on Any reply; Suppression at any scope; A booked Meeting. |
| Sequence | <a id="sequence-referral-first-touch"></a>`referral-first-touch` | Referral first touch: 1 steps; it ends on Any reply; A bounce; Suppression at any scope; A booked Meeting. |
| Benchmark | <a id="benchmark-cold-email-recipients-per-sequence"></a>`cold-email-recipients-per-sequence` | Reply rate per Sequence, 500 or more recipients against 21 to 50: 2.4–6.2 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |
| Benchmark | <a id="benchmark-cold-email-contacts-per-organization"></a>`cold-email-contacts-per-organization` | Reply rate, 3 or more contacts per Organization against 1 to 2: 3.5–5.1 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |
| Benchmark | <a id="benchmark-cold-email-tracking-off"></a>`cold-email-tracking-off` | Reply rate with open and click tracking on against off: 4.4–7.4 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |
| Benchmark | <a id="benchmark-cold-email-edited-by-hand"></a>`cold-email-edited-by-hand` | Reply rate of fully automated emails against emails edited by hand: 4.4–5.2 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |
| Benchmark | <a id="benchmark-cold-email-sequence-size-2024"></a>`cold-email-sequence-size-2024` | Reply rate per Sequence, 1,000 or more recipients against 50 or fewer: 2.1–5.8 % (An email-finder vendor’s annual cold email report, 2024 data; correlational, 2024-12-31). |
| Benchmark | <a id="benchmark-cold-email-agency-reply-per-send"></a>`cold-email-agency-reply-per-send` | Replies divided by emails sent, agency-managed cold email: 0.45 % (A lead-generation agency’s response-rate study, 2025 data; replies over sends, 2025-12-31). |
| Benchmark | <a id="benchmark-cold-email-short-first-email"></a>`cold-email-short-first-email` | Reply rate of first emails under 50 words, at the median sender: 1.47 % (A sending platform’s cold email report, January to June 2026 platform data, 2026-06-30). |
| Benchmark | <a id="benchmark-cold-email-wrong-person-rate"></a>`cold-email-wrong-person-rate` | Share of agent-built research profiles that describe the wrong person: 4 % (Heiding et al., evaluating large language models’ ability to automate spear phishing, 2026-01-01). |