Skip to content

Launch sites

Launches a ready Startup on one launch site at a time; the agent books it and builds the kit, and the founder writes every word.

Channel
Launches
Run oneMode try
You, to your agent

Hand the latest launch Event to the Marketing Lead agent and show me what it chose and why. Don’t post.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Monitor.checked%22%2C%20%22Contact.subscribed%22%2C%20%22Version.deployed%22%2C%20%22Organization.announced%22%2C%20%22Person.commented%22%2C%20%22Visitor.identified%22%2C%20%22Person.posted%22%2C%20%22Change.merged%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_1206"}'

# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22post_318%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%22post_318%22" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Monitor.checked", "Contact.subscribed", "Version.deployed", "Organization.announced", "Person.commented", "Visitor.identified", "Person.posted", "Change.merged")', 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 (\"Monitor.checked\", \"Contact.subscribed\", \"Version.deployed\", \"Organization.announced\", \"Person.commented\", \"Visitor.identified\", \"Person.posted\", \"Change.merged\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1206"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"post_318\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"post_318\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Monitor.checked\", \"Contact.subscribed\", \"Version.deployed\", \"Organization.announced\", \"Person.commented\", \"Visitor.identified\", \"Person.posted\", \"Change.merged\")', 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"
  }
}
Response200application/json
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_431",
    "$type": "Decision",
    "choice": "brief-a-reply",
    "reason": "a new Hacker News thread asks “anyone used Leaseline for multi-owner renewals?”; the brief holds fragments only, and you write every word",
    "stakes": "low",
    "options": [
      "book-the-launch",
      "time-it-to-a-moment",
      "send-the-notice",
      "brief-a-reply",
      "follow-up-signups",
      "not-now"
  …
sample · 4 Not live yetPreview

On PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim

action_1 is a fragment brief of 12-word facts, never a sentence for the thread. action_2 puts it in your tray; you write the reply and post it by hand.

380 ICP Visitors per launch week against 118 a week before · before-after, not proof · n 3 · path → arr

Try another: the launch EventChoiceReason
Hacker News, Oct 19: a new thread names Leaselinebrief-a-replyfragments only; you write every word
Product Hunt, Sep 8: every readiness check passes; never launched therebook-the-launchready, and the site has rested
A rival’s dated price rise on Sep 4time-it-to-a-momentmoves the booking 3 days to sit beside it
Owner portal shipped Oct 18; Product Hunt rested 34 of 180 daysnot-nowthe site rests 180 days; launch-week holds the Change

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · ICP Visits per launch → People reached → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +250 ICP Visitors per launch (Other Startups’ results; no lift of your own to read) × 1 launch a month × 0.008 Visitors to paid × $590 first order ARR ≈ +$1,180. Under First signal: Each launch reads at day 7 and its Customers at day 30; at 1 a month it reads before-after, beside Other Startups’ results.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Person.posted · first reply brief 2m 40s · 7 keys Not live yet

Start it this week

Terminal
npx startup-builder add play launch-sites   # 1 · writes plays/launch-sites.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":"launch-sites"}'

# 3 · keep it: you accept every date and write every thread word
curl -X POST https://api.sb/leaseline.app/campaigns \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"launch-sites"}'

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

# off: bookings cancel and the deploy freeze lifts
curl -X PATCH https://api.sb/leaseline.app/campaigns/launch-sites \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusedlaunch-sites can’t start: 2 checks fail.
CheckFixThen
use-when fail · Not live yet, gaps #8Grow the list to 100 who said yes; the waitlist counts.POST /{namespace}/contacts/{contact}/subscribe
baseline pass · Not live yet, gaps #8118 ICP Visitors a week, 28-day baselinePOST /{namespace}/metrics/query
launch-readiness failOpen the demo with no signup; the gate reads the live Site.POST /{namespace}/sites/{site}/publish
domain-authenticated pass—POST /{namespace}/domains/{domain}/authenticate
mailbox-warm pass · Not live yet, gaps #1the Startup’s Mailbox, warm since JulyPOST /{namespace}/mailboxes/{mailbox}/warm
role-unstaffed pass · Not live yet, gaps #8every thread word and every date goes to the founder, DanaPOST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "launch-sites can’t start: 2 checks fail.",
  "checks": [
    {
      "check": "use-when",
      "status": "fail",
      "observed": "74 of 100 People who said yes to hearing from Leaseline",
      "doc": "/plays/launch-sites#check-use-when",
      "fix": "Grow the list to 100 who said yes; the waitlist counts.",
      "then": "Contact.subscribe"
    },
    {
      "check": "baseline",
      "status": "pass",
      "observed": "118 ICP Visitors a week, 28-day baseline",
      "doc": "/plays/launch-sites#check-baseline",
      "then": "Metric.query"
    },
    {
      "check": "launch-readiness",
      "status": "fail",
      "observed": "8 of 9: the demo asks for a signup",
      "doc": "/plays/launch-sites#check-launch-readiness",
      "fix": "Open the demo with no signup; the gate reads the live Site.",
      "then": "Site.publish"
    },
    {
      "check": "domain-authenticated",
      "status": "pass",
      "doc": "/plays/launch-sites#check-domain-authenticated",
      "then": "Domain.authenticate"
    },
    {
      "check": "mailbox-warm",
      "status": "pass",
      "observed": "the Startup’s Mailbox, warm since July",
      "doc": "/plays/launch-sites#check-mailbox-warm",
      "then": "Mailbox.warm"
    },
    {
      "check": "role-unstaffed",
      "status": "pass",
      "observed": "every thread word and every date goes to the founder, Dana",
      "doc": "/plays/launch-sites#check-role-unstaffed",
      "then": "Role.staff"
    }
  ]
}

It says no, says why, and names the fix.

CheckFix (one call)Your timeWait
use-when · baseline · fail: 74 of 100 who said yes; pass: 118 a week (gaps #8)POST /{namespace}/contacts/{contact}/subscribe from the waitlist form; POST /{namespace}/metrics/query on launch-icp-visits fills Before10 minabout a week at 4 a day
launch-readiness · fail (gaps #8): 8 of 9POST /{namespace}/sites/{site}/publish the demo with no signup30 minnone
domain-authenticated · mailbox-warm · role-unstaffed · passnothing to do0 minnone

Your number · Before 118 ICP Visitors a week · Now 380 per launch week · Target 400 by Dec 31 · before-after, not proof · n 3 launches

A launch costs no cash: the sites list it for free, and the notice goes from your own Mailbox. The kit and the reply briefs cost about $2 a launch (Worker cost). Your time is the cost: about 7 hours per launch, most of it the 4-hour reply block on the day.

When it starts

WhenTrigger idStarts onWindowHow it gets in
Every readiness check passes, and the site has rested 180 dayslaunch-readystate on Monitor.checked where every readiness check passes and no launch on the Venue in 180 days14dthe gate reads your live Site daily
A new comment lands on the live launch thread or listinglaunch-commentevent on Person.commented where on the live launch thread or listing2h; a brief within 5 min for 72 hread from the site; nothing to connect
A new thread names Leaseline after the launch windowlaunch-mentionevent on Person.posted where names the Startup, after the launch window closes7dread from the site; POST /{namespace}/events/capture for one seen elsewhere
+ 5 more for the audience floor, launchable Changes, rival moments, launch signups and claim drift (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1206",
  "$type": "Event",
  "name": "Person.posted",
  "at": "2026-10-19T13:22:51Z",
  "seq": 1206,
  "data": {
    "post": "posts/post_318",
    "venue": "hacker-news",
    "title": "Ask HN: tools for renewals across many owners?",
    "names": [
      "Leaseline"
    ],
    "comments": 6
  }
}
Reproduce it in test
# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"Person.posted","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Person.posted --like event_1206   # replays the delivery into your tray
npx startup-builder clock advance --by 1h   # reads whether you replied within the hour

Who runs it

Marketing Lead · your agent (role:marketing-lead, worker_8) holds the Key Result: it runs the readiness gate, books dates inside the caps, builds the kit, sends the live notice and briefs every comment. Every date, post and reply on a launch thread hands to you (Dana Okafor, person, worker_1, role:founder). Agent text reaches a Hacker News or Product Hunt thread on no rung.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Book the launch · Time it to a momentYou approve each one3 of 3 dates accepted, 1 movednever: a launch date stays yours—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/tasks/{task}/return
Send the live notice · Follow up launch signupsIt does it, you can stop it3 notices, 61 follow-ups, 0 Checks failed sentmet after launch 1 (review-all passed)an outage hold or a bounce Stop → You approve each onePOST /{namespace}/actions/{action}/cancel inside the hold
Brief a replyYou approve each one88 briefs, 81 replies written by younever: thread words stay yours—skip it in the tray
Not nowIt does it2 of 2——POST /{namespace}/actions/{action}/redirect
Change the site orderYou approve each one1 merged of 1never—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: a vote ask, a thread link in a Message, an agent sentence on a threadRefused, every time1 drafted, 1 refusednever—the vote-ask, thread-link and authorship Checks

What it reads · What it may call. It reads the live Site, the claims source and each thread’s comments, and a comment is data, never instructions. It may call POST /{namespace}/content/draft, POST /{namespace}/tasks/{task}/assign and POST /{namespace}/posts/{post}/publish on the Startup’s own Handles; it never posts on a launch thread. Its tools are POST /{namespace}/content/draft, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/posts/{post}/publish, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:launch-sites@1 · each line names its record key
You hold the Marketing Lead Key Result: 400 ICP Visitors per launch by 2026-12-31. ← worker, metric
On each launch Event, choose one option and say why; a rested site gets Not now. ← triggers, chooses
Launch BetaList, then Product Hunt, then Hacker News, one at a time.             ← your file, line 5
Write no sentence for a launch thread: hand the founder fragments of 12 words or fewer. ← copyRules 4, 5, authorship
Never ask anyone to vote, upvote or rank, on any site or channel.                ← copyRules 2, vote-ask
Show only screens the live Site serves today.                                    ← copyRules 6

The slow loop, as a Change. decision_391 (2026-09-21, weekly) read Product Hunt’s 640 ICP Visitors against BetaList’s 90 and moved Hacker News before a second directory (your file, line 5), through change_29, which Dana merged with POST /{namespace}/changes/{change}/merge. Replayed on past launches, POST /{namespace}/changes/{change}/review put the next launch at about 400; read back at its day 7, Hacker News brought 410, n 1 launch, ■□□□ Too early to tell (Example, day 50).

Bring your own agent (folded) books and briefs at the same rung when it matches or beats the seated agent on the eval suite; thread words stay yours either way, and POST /{namespace}/roles/{role}/staff seats it.

Terminal
npx startup-builder eval --scenario launch-sites-3 --agent "claude -p" --seat marketing-lead   # seated: 0 vote asks sent, 0 agent words on threads, 2.4 min a brief · yours: 0, 1 full sentence drafted for a thread, 2.0 min → You approve each one

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Book the launch book-the-launchevery readiness check passes, and the site rested 180 daysYour rule (line 5)POST /{namespace}/content/draft the kit from the live Site → POST /{namespace}/tasks/{task}/assign the date to you, with a deploy freezeyou accept the date, due 1 business day · Take this oneyou
Time it to a moment time-it-to-a-momenta rival’s dated price rise or shutdown, or a shipped Change, in the next 14 daysAgent’s call, with its reasonPOST /{namespace}/tasks/{task}/assign a moved dateyou accept it, due 1 business day · Take this oneyou
Send the live notice send-the-noticethe launch goes liveYour rule (the booking)launch-live-notice to People who said yes, 10 % held back → POST /{namespace}/posts/{post}/publish on Leaseline’s own Handlesnobodythe same
Brief a reply brief-a-replya launch comment, or a new thread naming LeaselineAgent’s call, with its reasonPOST /{namespace}/content/draft of fragments → POST /{namespace}/tasks/{task}/assignyou write and post it, due 60 min · Take this oneyou
Follow up launch signups follow-up-signupsa signup whose first Source is the launchYour rule (the Sequence)launch-signup-follow-up: a first-value nudge, then a fixes notenobodythe same
Not now not-nowa check fails, the site rested under 180 days, or another of your Startups launches there that dayYour rule (the rest and the caps)nothing; names the check, the rest’s end date or the other launchnobody; the gate reads it again dailythe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interesteda notice reply: “Can I see this with my 12 buildings?”goes to instant-response as a new Lead, with the launch on its AcquisitionSDR · your agent, then AE · Priya Shah (person)5 minPOST /{namespace}/leads
Send me pricinga thread comment: “What does it cost?”a fragment brief with the Pricing Page’s list Price; you write the replyyou (Dana, person)60 minPOST /{namespace}/tasks/{task}/assign
Not nowa notice reply: “Not for us this year.”nothing more sends to them about the launchnobodyat onceGET /{namespace}/decisions
Wrong person“Forwarding to our ops manager.”a one-line thanks; it never writes to an address from their textMarketing Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply to the noticenothing: the notice carries no follow-upnobody—GET /{namespace}/decisions
Question it can’t answera thread comment: “How do you handle owners in two time zones?”the brief marks it unknown to the claims source; you answer, or say you are checkingyou (Dana, person)60 minPOST /{namespace}/conversations/{conversation}/escalate
Stop“Unsubscribe.”no notice, follow-up or newsletter sends to them againnobodyat oncePOST /{namespace}/contacts/{contact}/unsubscribe

When it hands to you

Every date, post and thread reply hands to you (Dana Okafor, person); interested notice replies go through instant-response to the AE. As captured, the reply brief in your tray (brief is Not live yet, gaps #7).

What lands in each queue · sample
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_521",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-19T14:22:00Z",
    "on": "post_318",
    "brief": {
      "thread": "Ask HN: tools for renewals across many owners?",
      "asked": "anyone used Leaseline for multi-owner renewals?",
      "fragments": [
        "per-owner batches, 60 days out",
        "41 property managers on it",
        "free plan: 10 units"
      ],
      "chose": "brief-a-reply",
      "never": [
        "a vote ask",
        "a sentence written for you",
        "a link to the thread in any Message"
      ]
    }
  }
]

You answer a brief by writing the reply and posting it by hand, with POST /{namespace}/tasks/{task}/return and a reason, or with POST /{namespace}/actions/{action}/redirect; a date with POST /{namespace}/approvals/{approval}/approve or POST /{namespace}/tasks/{task}/return. A brief past its due time stays in the tray marked late, and nobody else can post in your name, so nothing goes up a Role. During a launch’s 72 hours the agent pings you within 5 minutes of each comment.

On time: You: 81 of 88 briefs answered within 60 min, median 9 min on launch days, n 88, ■■□□ Early sign beside Other Startups’ 86 %. Your queue: counted by kind: per launch, 1 date, 1 kit review and about 30 reply briefs; between launches, about 2 mention briefs 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)RefusesFixThen
owned-by-a-person (rule j; Not live yet, gaps #8)a notice or follow-up to a Contact whose Lead or open Deal a person ownsLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
authorship (launch sites)an agent sentence for a Hacker News post, title or comment, or a Product Hunt maker comment or replyWrite it yourself from the fragments.POST /{namespace}/tasks/{task}/assign
vote-askany Message, Post or Page that asks anyone to vote, upvote or rank the launchCut the ask; say it is live and what it does.POST /{namespace}/content/draft
thread-linka Message or Post carrying a Hacker News thread linkLink your own Site instead.POST /{namespace}/content/draft
readinessa launch after a readiness check fails since bookingFix the failing check; the launch moves to the next open date.POST /{namespace}/tasks/next
venue-rest (launch sites)a second launch on one site within 180 days, or a sunk post deleted and posted againWait for the rest’s end date, or run launch-week.GET /{namespace}/decisions
portfolio-caps (launch sites)two of your Startups on one site in a day, or one founder on one site twice in 30 daysTake the next open date the caps allow.POST /{namespace}/tasks/next
Stop (pauses the Play)Pauses whenThen
outageerrors over 2 % of requests, or p95 over 3 s for 5 minthe notice and the Posts hold until the Site recovers
bounce (email)bounces over 2 % of the notice’s sendsthe Mailbox pauses
complaint (email)complaints near 0.1 %the notice pauses on every Mailbox
kill-switchyou press itevery Tactic pauses at once; the freeze lifts

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

422RefusedThe Product Hunt live notice did not send: it asks People to upvote.
CheckFixThen
vote-ask failCut the ask; say it is live and what it does.POST /{namespace}/content/draft
thread-link pass—POST /{namespace}/content/draft
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The Product Hunt live notice did not send: it asks People to upvote.",
  "checks": [
    {
      "check": "vote-ask",
      "status": "fail",
      "doc": "/plays/launch-sites#check-vote-ask",
      "fix": "Cut the ask; say it is live and what it does.",
      "then": "Content.draft"
    },
    {
      "check": "thread-link",
      "status": "pass"
    }
  ]
}

It says no, says why, and names the fix.

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "outage",
      "observed": "p95 3.8 s for 6 min",
      "bound": "3 s for 5 min",
      "window": "launch day"
    },
    "doc": "/plays/launch-sites#stop-outage",
    "task": "task_406"
  }
]

Did it work

At 1 launch a month, no held-back half of launches reads, so the basis is before-after (rule o): the columns read Now and Before, and nothing prints as Added. Each figure’s call is POST /{namespace}/metrics/query by node, and every node above the leaf is Not live yet (gaps #4).

380 ICP Visitors per launch week against 118 a week before · before-after, not proof · n 3 · path → arr

Chose
brief-a-reply
Why
a new Hacker News thread asks “anyone used Leaseline for multi-owner renewals?”; the brief holds fragments only, and you write every word
From
book-the-launch · time-it-to-a-moment · send-the-notice · brief-a-reply · follow-up-signups · not-now
Expects
your reply within 60 min
Reopens when
no Post.published by worker_1 on post_318 within 60m
By
worker_8
JSON
{
  "$id": "decisions/decision_431",
  "$type": "Decision",
  "choice": "brief-a-reply",
  "reason": "a new Hacker News thread asks “anyone used Leaseline for multi-owner renewals?”; the brief holds fragments only, and you write every word",
  "stakes": "low",
  "options": [
    "book-the-launch",
    "time-it-to-a-moment",
    "send-the-notice",
    "brief-a-reply",
    "follow-up-signups",
    "not-now"
  ],
  "by": "worker_8",
  "on": "post_318",
  "expected": "your reply within 60 min",
  "reopensWhen": "no Post.published by worker_1 on post_318 within 60m"
}
NodeNow (56 days)Before (the 28-day baseline)AddedConfidenceBasis
launch-icp-visits380 per launch: BetaList 90, Product Hunt 640, Hacker News 410118 ICP Visitors a week, from every Source— · Worth about +$1,200 a month—before-after, not proof · Other Startups’ results +250 per launch, ■■■□ Likely, n 640 launches
icp-reached2,490 ICP Visitors in the 56 days944 per 56 days——before-after
new-arr ↑$3,023, 7 launch-sourced Customers (6 on Pro, 1 on Team) · Booked: credited, not all caused by this Play$1,388 per 56 days, every Source— · 11 trials still deciding—before-after, not proof
net-new-arr · arrcarried from new-arrcarried——carried

Before against after reads ICP Visitors whose first Source is a launch listing, short link or site referrer, in the 7 days after each launch, against the 28-day baseline before the first. It is not proof; Other Startups’ results, with a 10 % notice holdout, print beside it.

How it moves it: each launch put the no-signup demo before a site’s readers for a day, and Dana answered 81 comments at a median of 9 minutes.

Guardrails: before against after: play-sourced-customers, 7 against 0, and launch-sourced Customers active from day 14 to day 30, 5 of 7 against Leaseline’s 4 of 7 for every Source.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/launch-sites",
  "$type": "Campaign",
  "play": "play:launch-sites@1",
  "path": [
    "launch-icp-visits",
    "icp-reached",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "launch-icp-visits",
    "unit": "count",
    "heldBack": 0,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 3,
    "maturing": 0,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 0,
    "workerCost": 6,
    "hours": 22,
    "pipelineArr": 3816,
    "wonArr": 3023,
    "projectedArr": 1180,
    "paybackDays": 0
  }
}

Outside benchmark: 27 % of Hacker News launch-post titles name AI, models or agents (142 launch posts, a count of the public launch list, 2026-10-24), so a title that names what the Product does stands apart.

Before it · After it. Before it: owned-newsletter grows the 100 People who said yes. After it: launch signups go to product-led, interested notice replies to instant-response, and a shipped Change on a rested site goes to launch-week.

Example

Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 3 launches on 3 sites, 3 live notices to 212 People who said yes (21 held back), and 88 reply briefs. Read every captured thread at ?threads=all; three follow the tables.

What happened, by optionDecisionsSent or postedICP Visitors in 7 daysWon (credited, not all caused by this Play)
Book the launch · Time it to a moment3 · 13 launchesBetaList 90 · Product Hunt 640 · Hacker News 4107 Customers (+$3,023 ARR)
Send the live notice · Follow up launch signups3 · 61573 notices · 112 follow-ups—11 trials still deciding
Brief a reply · Not now88 · 281 replies, by you——
All · the 28-day baseline158—380 per launch · 118 a week$3,023
At 1 launch a month (the Use it when volume)about 50 a month1 launchbefore-after, not proofOther Startups’ results: +250 per launch, ■■■□ Likely, n 640
DayEventWhat happenedYour time
0event_129 Campaign.createdthe three steps; dry run fails use-when and launch-readiness30 min
6event_221 Monitor.checkedlaunch-ready: 103 who said yes, and the demo opens with no signup—
8event_262 Visitor.identifiedBetaList live; the first launch-sourced signup1.5 h
22event_401 Campaign.pausedoutage: p95 3.8 s at 08:10; the notice waited 22 min—
22event_405 Post.publishedProduct Hunt live at 00:01 PT; you wrote the maker comment and 46 replies5 h
28 · 50event_536 Change.merged · event_880 Readout.createdHacker News next: replayed at about 400, read back at day 7 at 410, n 15 min
1–56event_160 Task.assigned, first of 92you accepted 3 dates and wrote 81 replies, from the POST /{namespace}/tasks/next log14 h · total 22 h measured, 21 h asked

Product Hunt, Sep 15, 00:20 PT, a commenter · “Does this work when each building has a different owner?”

Dana, 00:27 · Yes, that is the case we built for: each owner gets their own renewal batch, 60 days out.¹ The demo has three owners loaded; no signup.² Written by Dana from the brief’s fragments.

Sep 15, 09:40 · the commenter signed up from the listing (Visitor.identified, first Source Product Hunt) and paid for Pro on Sep 29.

Product Hunt live notice, 2026-09-15 · the draft vote-ask refused, then the rewrite that sent
- We’re live on Product Hunt today: please upvote us!
+ Leaseline is live on Product Hunt today, with a demo you can open with no signup. Tell us what you think on the listing.

Hacker News, 2026-10-06 09:14 · a commenter asked how Leaseline handles owners in two time zones; the claims source holds no answer, so the brief marked it unknown, due 10:14. · Dana, 09:31 · wrote her own reply: the batch runs in each owner’s time zone, and she would add it to the docs that week.³

¹ Your words, from a fragment: “per-owner batches, 60 days out”. ² A screen the live Site serves. ³ Every thread word is yours; the agent wrote none.

Your settings

plays/launch-sites.mdx
---
noticeHoldout: 0.1     # 1 in 10 who said yes gets no notice
replyBlock: 09:00-13:00 ET
---
BetaList first, then Product Hunt, then Hacker News, one at a time. I write every word on the threads.
Text
$ npx startup-builder show plays/launch-sites
notice holdout 0.1 · reply block 09:00-13:00 ET · site order     your file  plays/launch-sites.mdx:2,3,5 (Ask 2026-08-24; line 5 by change_29, 2026-09-21)
family demand · worker role:marketing-lead, owns never · chooses 6 (4 rule, 2 read) · sequences launch-live-notice, launch-signup-follow-up · every thread word by the founder · checks owned-by-a-person, authorship, vote-ask, thread-link, readiness, venue-rest, portfolio-caps · stops 4 · placements product-hunt, hacker-news, betalist, gmail, outlook, yahoo-mail, x, linkedin    catalog  play:launch-sites@1 (Not live yet, gaps #5)

Every key from the catalog

Key Id What it is
Tactic launch-readiness-gate Launch readiness gate runs nine rule checks on a live Startup and books a launch only when every check passes. Starts at Sends nothing.
Tactic launch-booking Launch booking orders the eligible Venues, picks a date inside the Portfolio caps and the Human’s reply block, and books a deploy freeze. Starts at It does it, you can stop it.
Tactic launch-kit Launch kit compiles the gallery, Video, tagline, fact sheet and red-team list from the live Site and the claims source for the Human. Starts at You approve each one.
Tactic owned-audience-notice Owned audience notice tells consented People the Startup is live, admits the Waitlist batch, and posts from the Startup’s own Handles, with no vote ask. Starts at You approve each one.
Tactic launch-desk Launch desk watches a live launch thread for 72 hours and hands the Human a fragment-only reply brief for each comment within 5 minutes. Starts at Sends nothing.
Tactic launch-readout Launch readout counts ICP Visits a launch brings in 7 days, and Customers still active from day 14 to day 30, against a holdout. Starts at Sends nothing.
Tactic claims-check Claims check maps every draft sentence to an approved source or the Person’s own words, and holds anything else before it reaches anyone. Starts at Sends nothing.
Tactic 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 claim-drift Claim drift finds each live claim a merged or reverted Change made false within 1 hour, then corrects, pauses or routes it. Starts at You approve each one.
Tactic deploy-freeze Deploy freeze holds every live deploy and named Flag through the launch days, while reverts run at any hour and approved fixes ship in steps. Starts at Sends nothing.
Tactic founder-send-tray Founder send tray shows each approved draft with its source trail; the founder presses post by hand or through the Venue’s own posting path. Starts at You approve each one.
Trigger launch-ready Launch ready: state on Monitor.checked, window 14d.
Trigger owned-audience-floor Owned audience floor: threshold on Contact.subscribed, window 30d.
Trigger launchable-change Launchable change: event on Version.deployed, window 30d.
Trigger rival-moment Rival moment: event on Organization.announced, window 14d.
Trigger launch-comment Launch comment: event on Person.commented, window 2h.
Trigger launch-sourced-signup Launch-sourced signup: event on Visitor.identified, window 30d.
Trigger launch-mention Launch mention: event on Person.posted, window 7d.
Trigger claim-drift Claim drift: event on Change.merged, window 1d.
Sequence launch-live-notice Launch live notice: 1 steps; it ends on Opt-out; Signup.
Sequence launch-signup-follow-up Launch signup follow-up: 3 steps; it ends on Opt-out; An open Issue from the Customer, which Support takes over; Day 30 after the launch.
Benchmark show-hn-ai-title-share Share of Hacker News launch-post titles that name AI, models or agents: 27 % (Count of the public Hacker News launch-post list, re-run in a verification pass, 2026-10-24).

Compiled, not written: edit the Play record launch-sites 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.