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.
- Channel
- Email and inboxes
- Kind
- Outreach
- Summary
- startupbuilder.dev
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.
# Not live yet (gaps #2)
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"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'cold-email' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"cold-email"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'cold-email' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"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"
},
{
…
Hand today’s first Prospect to the SDR agent and show me what it chose and why. Don’t send.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Opening.published%22%2C%20%22Company.filed%22%2C%20%22Review.published%22%2C%20%22Company.funded%22%2C%20%22Monitor.checked%22%2C%20%22Visit.recorded%22%2C%20%22Conversation.answered%22)&limit=1" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"like":"event_1240"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22prospect_212%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22prospect_212%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"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 }
npx startup-builder do Event.list --json '{"where":"name in (\"Opening.published\", \"Company.filed\", \"Review.published\", \"Company.funded\", \"Monitor.checked\", \"Visit.recorded\", \"Conversation.answered\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1240"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"prospect_212\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"prospect_212\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "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\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` }) // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` }) // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
"mode": "try"
}
}application/json{
"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",
…
sample · 4 Not live yetPreviewOn PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim
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 |
- Day 18: first Interested reply
- First signal
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/
Also runs as: Moment outreach.
Start it this week
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"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | 2,140 companies fit; 3 inbound a month | POST /{namespace}/metrics/query |
baseline warn · Not live yet, gaps #8 | The leaf starts at your first send; the 10 % held-back companies read Meetings. | POST /{namespace}/metrics/query |
domain-authenticated pass | leaseline.app: 3 of 3 records resolve | POST /{namespace}/domains/{domain}/authenticate |
mailbox-warm fail · Not live yet, gaps #1 | Start the warm-up today; the first email sends on day 15. | POST /{namespace}/mailboxes/{mailbox}/warm |
approved-pages fail · Not live yet, gaps #8 | Publish your pricing Page; every email states only what your pages say. | POST /{namespace}/sites/{site}/publish |
role-unstaffed pass · Not live yet, gaps #8 | — | POST /{namespace}/roles/{role}/staff |
JSON
{
"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"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · baseline · pass: 2,140 companies fit, 3 inbound a month · warn: no history (gaps #8) | POST /{namespace}/metrics/query on positive-reply-rate; the held-back companies fill Before | 1 min | none |
domain-authenticated · mailbox-warm · pass · fail: 0 of 14 days (gaps #1) | POST /{namespace}/mailboxes/{mailbox}/warm on dana@leaseline.app at 40 a day | 2 min | 14 days; warm intros keep running |
approved-pages · fail (gaps #8) | POST /{namespace}/sites/{site}/publish your pricing Page | 15 min | none |
role-unstaffed · pass (gaps #8): AE · Priya Shah takes Interested replies; 31 open Leads have a person owner | POST /{namespace}/roles/{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=) |
{
"$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
}
}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:, 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 | POST /{namespace}/actions/{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 | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| NO_ANGLE · Market hold | It does it | 31 · 6 | — | — | POST /{namespace}/actions/{action}/redirect |
| Change an angle or a slice | You approve each one | 1 retired by the reply floor | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{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.
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 POST /{namespace}/changes/{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; POST /{namespace}/roles/{role}/staff seats it.
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 | POST /{namespace}/meetings/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 | POST /{namespace}/conversations/{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 | POST /{namespace}/messages/{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 | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Oct 28 | the next email waits for the return date | nobody | the return date | POST /{namespace}/messages/{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 | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Remove me.” | nothing else sends to them, from any of your Startups | nobody | at once | POST /{namespace}/contacts/{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).
[
{
"$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 POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{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 POST /{namespace}/tasks/{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: POST /{namespace}/deals/{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 |
|---|---|---|---|
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. | POST /{namespace}/tasks/{task}/assign |
mailbox-warm (on POST /{namespace}/messages/{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. | POST /{namespace}/mailboxes/{mailbox}/warm |
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. | POST /{namespace}/leads/{lead}/assign |
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. | POST /{namespace}/content/draft |
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. | POST /{namespace}/tasks/{task}/assign |
| Stop (pauses the Play) | Pauses when | Then |
|---|---|---|
bounce | hard bounces over 2 % of a Mailbox’s day, at 20+ sends | POST /{namespace}/mailboxes/{mailbox}/rest; over 3 % of its last 100, POST /{namespace}/mailboxes/{mailbox}/retire |
shadow-complaint | stop, remove-me and hostile replies over 1 % of a Domain’s last 1,000 | the Domain pauses |
provider-spam | a provider-reported spam rate of 0.08 % | every Mailbox on that provider pauses |
placement | inbox placement under 70 % on a seed test | POST /{namespace}/mailboxes/{mailbox}/rest |
blocklist | a blocklist listing | the Domain retires; a warmed spare takes its slot |
authentication | the Monday check finds SPF, DKIM, DMARC or the stop header failing | the Domain pauses; POST /{namespace}/domains/{domain}/authenticate |
reply-floor | replies under 1 % after 300 delivered in one angle and slice | those cells stop; no Interested reply retires the angle |
negative-reply | stop and hostile replies over 3 % of a template’s last 100 | the template pauses |
unanswered-positive (standard response-60m) | an Interested reply waits past its deadline | new sends pause until it is answered |
wrong-person | the monthly hand check of 50 finds over 10 % wrong-person | minting halts |
fleet-canary | a bounce or placement drop across 30 other Startups on one provider within an hour | the Play pauses across your Startups |
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.
| Check | Fix | Then |
|---|---|---|
domain-authenticated pass | — | POST /{namespace}/domains/{domain}/authenticate |
mailbox-warm fail · Not live yet, gaps #1 | Wait 11 days; warm intros keep running. | POST /{namespace}/mailboxes/{mailbox}/warm |
JSON
{
"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"
}
]
}It says no, says why, and names the fix.
[
{
"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 POST /{namespace}/metrics/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
- Chose
- cold-email-thread
- Why
- 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
- From
- cold-email-thread · cold-email-thread-founder · no-angle · market-hold
- Expects
- an Interested reply within 10d
- Reopens when
- no Conversation.answered from prospect_212 within 10d; the thread then parks for 30d
- By
- worker_2
JSON
{
"$id": "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"
}| 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.
{
"$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=; 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 POST /{namespace}/tasks/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?”
POST /{namespace}/meetings/bookbooked Thu 15:00 on Priya’s calendar, and the Brief reached her at 13:13 (When it hands to you).
- 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
---
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. $ 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
Compiled, not written: edit the Play record cold-email and its Leaseline run, then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.