Tools on request
Asks your niche each week for one annoying problem, builds the top 10 as free tools within 24 hours, and you answer every asker.
- Step
- Get found
- Channel
- Free tools
- Kind
- Social & video
Be our Content Lead: each Friday, ask property managers for one annoying problem, build the top 10 as free tools within 24 hours, and draft a reply to every asker for me to post. Show me what’s missing; don’t post.
# 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":"request-desk"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'request-desk' }, { 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":"request-desk"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'request-desk' }, { 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": "request-desk can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "2 communities, 41 problems posted a week",
"doc": "/plays/ request-desk#check-use-when",
"fix": "Keep 2 communities with 20 or more problems a week, or run community-answers.",
"then": "Metric.query"
},
…
Hand the latest request to the Content Lead agent and show me what it chose and why. Don’t post.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Schedule.fired%22%2C%20%22Post.replied%22%2C%20%22Post.published%22%2C%20%22Tool.used%22%2C%20%22Tool.called%22%2C%20%22Version.deployed%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_6107"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22problem_23%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%22problem_23%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Schedule.fired", "Post.replied", "Post.published", "Tool.used", "Tool.called", "Version.deployed")', 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 (\"Schedule.fired\", \"Post.replied\", \"Post.published\", \"Tool.used\", \"Tool.called\", \"Version.deployed\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_6107"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"problem_23\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"problem_23\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Schedule.fired\", \"Post.replied\", \"Post.published\", \"Tool.used\", \"Tool.called\", \"Version.deployed\")', 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_602",
"$type": "Decision",
"choice": "build-the-tool",
"reason": "“I rebuild our turnover calendar from a spreadsheet every January” scored 8.4, 3rd of this week’s 10; Leaseline’s calendar Verb builds it from a CSV",
"stakes": "low",
"options": [
"build-the-tool",
"send-a-sample",
"answer-in-writing",
"not-this-week",
"not-ours",
"to-the-ae"
…
sample · 4 Not live yetPreviewOn POST /{namespace}/processes/{process}/enableOff POST /{namespace}/processes/{process}/pauseTake this one POST /{namespace}/tasks/{task}/claim
action_2 publishes the turnover-calendar tool once its known-answer cases pass. action_3 is the reply in the asker’s own thread, waiting in your send tray: you post every reply by hand.
12.1 entry starts per 100 askers against 4.5 before · before-after,
| Try another: the request | Choice | Reason |
|---|---|---|
| u/rentroll_rita: “I rebuild our turnover calendar from a spreadsheet every January.” | build-the-tool | 3rd of the weekly 10; one Verb builds it |
| A manager drops their listings URL in the Friday thread | send-a-sample | 14th of 30 in the thread |
| “Is there a template for an owner’s monthly report?” | answer-in-writing | the template is already on the Site |
| “Can someone build a tenant screening scorer?” | not-ours | not something Leaseline builds; the reply says why |
| Kai at Westbrook Lofts, 180 units: “Does Leaseline do this for a portfolio?” | to-the-ae | over 100 units, asking about the product itself |
- 1 h week 1, then 40 min a week
- Your time
- Day 1: the first tool live
- First signal
- 2+ communities, 20+ problems posted a week
- Use it when
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Requester entry rate → People reached → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +6 entry starts per 100 askers (Other Startups’ results; no lift of your own yet) × 35 askers a month × 0.55 entry to paid × $347 Pro ARR ≈ +$401. Under First signal: Every asker gets an answer, so nothing is held back: it reads before-after, not proof, beside Other Startups’ results.
sample · api.sb/
Start it this week
npx startup-builder add play request-desk # 1 · writes plays/request-desk.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":"request-desk"}'
# 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":"request-desk"}'
# on
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/enable \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# off: no call posts; live tools stay up and open requests still get an answer
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/pause \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"| Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | Keep 2 communities with 20 or more problems a week, or run community-answers. | POST /{namespace}/metrics/query |
owner fail | Book a weekly 45-minute reply slot; no call posts without one. | POST /{namespace}/tasks/{task}/assign |
baseline warn · Not live yet, gaps #8 | n 22: it reads before-after, not proof; every asker gets an answer. | POST /{namespace}/metrics/query |
role-unstaffed warn · Not live yet, gaps #8 | Staff the AE, or leave it: product questions from big askers come to you. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "request-desk can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "2 communities, 41 problems posted a week",
"doc": "/plays/request-desk#check-use-when",
"fix": "Keep 2 communities with 20 or more problems a week, or run community-answers.",
"then": "Metric.query"
},
{
"check": "owner",
"status": "fail",
"observed": "no booked founder reply slot",
"doc": "/plays/request-desk#check-owner",
"fix": "Book a weekly 45-minute reply slot; no call posts without one.",
"then": "Task.assign"
},
{
"check": "baseline",
"status": "warn",
"observed": "1 entry start of 22 askers you answered by hand in 90 days",
"doc": "/plays/request-desk#check-baseline",
"fix": "n 22: it reads before-after, not proof; every asker gets an answer.",
"then": "Metric.query"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"marketing-lead",
"sales-lead"
],
"owned": 0,
"doc": "/plays/request-desk#check-role-unstaffed",
"fix": "Staff the AE, or leave it: product questions from big askers come to you.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · baseline · pass: 2 communities, 41 problems a week; warn: 1 of 22 in 90 days (gaps #8) | POST /{namespace}/metrics/query on requester-entry-rate, which fills Before in Your number | 1 min | none |
owner · fail: no booked reply slot | POST /{namespace}/tasks/{task}/assign a weekly 45-minute reply slot to you | 2 min | none |
role-unstaffed · warn (gaps #8): no AE or Marketing Lead | POST /{namespace}/roles/{role}/staff, or leave it: those routes come to you | 0 min | none |
Your number · Before 4.5 · Now 12.1 entry starts per 100 askers · Target 15 by Dec 31 · before-after,
Each tool costs about $0.60 in build compute and each Sample $0.08 (Worker cost), under the $25 monthly build Limit; posting from your own profile costs nothing. That comes to about $12 a month at 20 tools.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| Someone answers the Friday call with a problem | request-posted | event on Post.replied where a reply to an open call, inside its 48-hour window | built within 24 h; answered within 72 h of the cutoff | POST /{namespace}/handles/{handle}/connect on the Rooms where you post the call |
| Someone drops a URL in the thread | url-dropped | event on Post.replied where a URL in a reply to an open drop-your-URL thread, under its cap of 30 | a Sample within 48 h; 30 a thread | the same Handle |
| An asker runs their tool 3 times in 7 days, or shares it | requester-repeat-use | threshold on Tool.used where an asker runs their tool 3 or more times in 7 days, or shares it | 7d | the tool reports POST /{namespace}/events/capture on each run |
+ 5 more for the weekly slot, tool wishes, day 30, repeat use and day 90 (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_6107" ,
"$type": "Event",
"name": "Post.replied",
"at": "2026-10-17T15:22:09Z" ,
"seq": 6107,
"data": {
"post": "post_88",
"room": "r/PropertyManagement" ,
"reply": "I rebuild our turnover calendar from a spreadsheet every January.",
"problem": "problem_23",
"window": "48h"
}
}npx startup-builder trigger Post.replied --like event_6107 # replays the request
npx startup-builder clock advance --by 1d # runs the build clock’s 24-hour check
npx startup-builder listen Post.replied --forward-to http://localhost:3000/hook Who runs it
Content Lead · your agent (role:, worker_6) holds the Key Result: it reads, ranks and builds. You (Dana Okafor, person, worker_1) post every call and every reply by hand from your own profile. Askers at companies over 100 units who ask about Leaseline go to AE · Priya Shah (person) (role:, worker_3). Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Build it in 24 hours · Send a Sample | It does it, you can stop it | 62 of 64 (2 missed the clock) · 29 of 29 | met on day 8 (the first 10 builds) | any tool fails its known-answer cases → You approve each one | POST /{namespace}/actions/{action}/cancel before the link goes out |
| Answer in writing · Not this week · Not ours to build | You approve each one | 21 of 21 · 33 of 33 · 9 of 9 | never: every reply goes out under your hand | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| To the AE | It does it | 3 of 3 | — | — | POST /{namespace}/actions/{action}/redirect |
| Change the scoring rule | You approve each one | 1 merged of 1 | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: an asker named without their OK, a seeded request, a reply about what it watched | Refused, every time | 1 seeded request refused | never | — | nothing; the Checks hold it |
What it reads · What it may call. It reads the replies to your call and the URLs dropped in the thread, and fetches at most 20 public pages a Sample, never past a login or a form (public-fetch). A run count, a visit or an asker’s reach never appears in a reply. Its tools are POST /{namespace}/problems/rank, POST /{namespace}/apps/{app}/publish, POST /{namespace}/pages, POST /{namespace}/conversations/{conversation}/answer, POST /{namespace}/problems/suggest, POST /{namespace}/leads/{lead}/assign, POST /{namespace}/tasks/{task}/assign, and any other call becomes an Approval under the Role’s Mandate.
You hold the Content Lead Key Result: 15 entry starts per 100 askers by 2026-12-31. ← worker, metric
On each request, choose one option and say why; every asker gets an answer. ← triggers, chooses, copyRules 3
Build the weekly 10 within 24 hours; the last 3 slots are a logged draw. ← your file, line 4
Name an asker only after they agree. ← copyRules 6; consent-stop
Name the entry Offer only when the asker asked about price. ← copyRules 12
Draft every reply for Dana to post by hand. ← tactic request-replyThe slow loop, as a Change. decision_571 (2026-09-21, weekly) read that requests naming a file people already keep (a spreadsheet, a rent roll) led to 5 of the first 7 entry starts, so change_33 added 1 point to the score for them (your file, line 4) and Dana merged it with POST /{namespace}/changes/{change}/merge. Replayed on past requests, POST /{namespace}/changes/{change}/review put entry starts at 13.0 per 100; read back at +28d it is 12.1, n 31, before-after, not proof (Example, day 56).
Bring your own agent (folded) starts at It does it, you can stop it for builds when it matches the seated agent on the eval suite; every reply stays yours to post. POST /{namespace}/roles/{role}/staff seats it.
npx startup-builder eval --scenario request-desk-64 --agent "claude -p" --seat content-lead # seated: 62 of 64 inside 24 h, 0 Checks failed posted, $0.60 a tool · yours: 57 of 64, 1 known-answer fail What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Build it in 24 hours build-the-tool | a buildable request in the weekly 10 | Your rule (line 4) | POST /{namespace}/problems/rank → POST /{namespace}/apps/{app}/publish within 24 h → requester-check-in | you post the reply · Take this one | you |
Send a Sample send-a-sample | a URL in the thread, under its cap of 30 | Your rule (the Sample cap) | POST /{namespace}/pages: a noindex Sample of the checks it ran | you post the reply | you |
Answer in writing answer-in-writing | the answer already exists | Agent’s call, with its reason | POST /{namespace}/conversations/{conversation}/answer, drafted | you post it | you |
Not this week not-this-week | buildable, but outside the weekly 10 | Agent’s call, with its reason | POST /{namespace}/problems/suggest → POST /{namespace}/conversations/{conversation}/answer: not this week, and when | you post it | you |
Not ours to build not-ours | outside what Leaseline builds | Agent’s call, with its reason | POST /{namespace}/conversations/{conversation}/answer: what it is not, and why | you post it | you |
To the AE to-the-ae | over 100 units, asking about Leaseline itself | Agent’s call, with its reason | POST /{namespace}/leads/{lead}/assign → POST /{namespace}/tasks/{task}/assign | POST /{namespace}/tasks/{task}/assign → AE · Priya Shah, due 1 business day · Take this one | you, within 1 business day |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “This is great. Does Leaseline do this every month?” | the entry Offer, because they asked; over 100 units, To the AE | you, from the draft | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Send me pricing | “What does the full thing cost?” | the Pricing Page’s list Price, in their thread | you, from the draft | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Not now | “Thanks, the free tool is all I need.” | nothing more; the check-in at day 30 still asks how it went | nobody | at once | GET /{namespace}/decisions |
| Wrong person | “I’m asking for my boss, she runs the portfolio.” | thanks them; it never writes to anyone they name | you, from the draft | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply to the day-30 check-in | the Interview ask waits for the return date | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Can the tool read our old system’s export?” | To a person, with the file type in the Brief | you | 1 business day | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Please don’t message me again.” | the check-in and the Interview ask stop; the tool stays theirs | nobody | at once | POST /{namespace}/contacts/{contact}/suppress |
When it hands to you
Every reply lands in your send tray, because you post them all by hand; askers over 100 units who ask about Leaseline go to AE · Priya Shah (person). One Brief per Role, as captured (brief is Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/approvals/approval_95" ,
"$type": "Approval",
"verdict": null,
"deadline": "2026-10-19T17:00:00Z" ,
"draft": "Built it: drop your spreadsheet in and it lays out every turnover for the year…" ,
"route": "build-the-tool",
"checks": [
{
"check": "claims-resolve",
"status": "pass"
},
{
"check": "consent-stop",
"status": "pass"
}
]
},
{
"$id": "https://api.sb/leaseline.app/tasks/task_644" ,
"$type": "Task",
"assignee": "worker_3",
"due": "2026-10-07T15:00:00Z" ,
"on": "lead_102",
"brief": {
"who": "Kai, Westbrook Lofts, 180 units" ,
"said": "Does Leaseline do this for a whole portfolio?" ,
"chose": "to-the-ae",
"why": "over 100 units, asking about the product itself" ,
"got": "the owner-report tool, built Oct 3" ,
"never": [
"a price beyond the list",
"what the tool’s runs show"
]
}
}
]You answer with POST /{namespace}/approvals/{approval}/approve (you post it), POST /{namespace}/approvals/{approval}/refuse, POST /{namespace}/tasks/{task}/claim (Take this one) or POST /{namespace}/tasks/{task}/return with a reason, each a one-call window. A reply unposted 72 hours after the cutoff pages you once (answer-clock). A Task nobody claims by its due time goes up a Role through POST /{namespace}/tasks/{task}/escalate, and person-promise fires.
On time: you, 121 of 124 replies posted inside 72 h, median 26 h, n 124; AE · Priya Shah, 3 of 3 within 1 business day, n 3, ■□□□ Too early to tell beside Other Startups’ 96 % on time. Your queue: about 15 replies to post a week, in your Friday and Monday slots, plus 1 weekly review and the next call.
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; gaps #8) | a reply or check-in to a Contact whose Lead or open Deal a person owns | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
correctness (the record’s Correctness stop) | a link to a tool that fails a known-answer case | Fix the tool until its known-answer cases pass, then link it. | POST /{namespace}/apps/{app}/publish |
consent-stop (gaps #3) | a tool Page or Sample that names the asker before they agreed | Ask the asker first, or leave their name off. | POST /{namespace}/messages/{message}/schedule |
claims-resolve (hub) | a Sample sentence for a check it never ran, or a count with no date | Cut the sentence, or link the page and date it checked. | POST /{namespace}/content/draft |
seeded-request (the record’s Seeded request stop) | a request from one of your own Handles, or anyone acting for you | Leave it out of the weekly 10; it is logged. | POST /{namespace}/problems/rank |
room-cadence (Reddit and Hacker News) | a third call in one Room in a month, or a call to a Room whose last call drew no request | Skip that Room this time; it returns next month. | POST /{namespace}/posts/{post}/schedule |
public-fetch (the record’s Public fetch only) | a Sample past 20 pages, faster than 1 a second, or behind a login | Fetch only public pages, slowly; the Sample states what it skipped. | POST /{namespace}/pages |
| Stop (pauses the Play) | Pauses when | Then |
|---|---|---|
build-clock | a picked request not live at 24 h; 3 misses in a week | one honest delay reply; next week’s count drops to 5 |
owner | no booked reply slot, or 7 days with no tray action | the next call does not post |
demand-floor | 2 calls in a row with under 5 qualifying requests on a placement | that placement rests 4 weeks |
answer-clock | a request unanswered 72 h after the cutoff | it pages you once |
room (Reddit and Hacker News) | a moderator removes a call or a reply | that Room rests 30 days and is read again; it restarts at You approve each one |
venue-warning | a restriction notice or an automated flag on any Handle | the Mandate on that Venue pauses at once |
sample-cap | a drop-your-URL thread reaches 30 Samples or 48 h | the thread closes |
spend-limit (the record’s Cost stop) | build or Sample compute reaches its Limit | new builds hold; raising it is an Approval (POST /{namespace}/limits/{limit}/raise) |
entry-floor | after 8 weeks and 50 shipped requests, 0 entry starts | the Play run stops |
kill-switch | you press it | every Tactic and the Mandate pause; live tools stay up |
+ 1 more for the X lane: summons only (?lanes=) |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that posted is the Glenwood thread in Example.
| Check | Fix | Then |
|---|---|---|
claims-resolve fail | Cut the sentence, or link the page and date it checked. | POST /{namespace}/content/draft |
consent-stop pass · Not live yet, gaps #3 | — | POST /{namespace}/messages/{message}/schedule |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The reply to u/glenwood_pm did not post: it says how many times their tool ran.",
"checks": [
{
"check": "claims-resolve",
"status": "fail",
"doc": "/plays/request-desk#check-claims-resolve",
"fix": "Cut the sentence, or link the page and date it checked.",
"then": "Content.draft"
},
{
"check": "consent-stop",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "build-clock",
"observed": "26h 10m",
"bound": "24h",
"window": "1 picked request"
},
"doc": "/plays/request-desk#stop-build-clock" ,
"task": "task_627"
}
]Did it work
Every asker gets an answer, so no half is held back and 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; the leaf and every node above it are Not live yet (gaps #4).
12.1 entry starts per 100 askers against 4.5 before · before-after,
- Chose
- build-the-tool
- Why
- “I rebuild our turnover calendar from a spreadsheet every January” scored 8.4, 3rd of this week’s 10; Leaseline’s calendar Verb builds it from a CSV
- From
- build-the-tool · send-a-sample · answer-in-writing · not-this-week · not-ours · to-the-ae
- Expects
- an entry Offer start from the asker within 30d
- Reopens when
- the tool not live 24h after the pick
- By
- worker_6
JSON
{
"$id": "decisions/decision_602",
"$type": "Decision",
"choice": "build-the-tool",
"reason": "“I rebuild our turnover calendar from a spreadsheet every January” scored 8.4, 3rd of this week’s 10; Leaseline’s calendar Verb builds it from a CSV",
"stakes": "low",
"options": [
"build-the-tool",
"send-a-sample",
"answer-in-writing",
"not-this-week",
"not-ours",
"to-the-ae"
],
"by": "worker_6",
"on": "problem_23",
"expected": "an entry Offer start from the asker within 30d",
"reopensWhen": "the tool not live 24h after the pick"
}| Node | Now (56 days) | Before (the 90 days, per 56) | Added | Confidence | Basis |
|---|---|---|---|---|---|
requester-entry-rate | 12.1 per 100 (7 of 58 matured askers) · 6 still maturing | 4.5 (1 of 22 answered by hand) | — · Worth about +$400 a month | — | before-after, not proof · Other Startups’ results +6.0 per 100, ■■■□ Likely, n 1,880 |
icp-reached | 1,140 people reached by the calls and tools | 310 | — | — | before-after; first visits only |
new-arr ↑ | $1,388, 4 Customers on Pro · Booked: credited, not all caused by this Play | $347, 1 Customer | — | — | before-after · 2 entry starts still deciding |
net-new-arr · arr | carried from new-arr | carried | — | — | carried |
Before against after reads the 56 days against the 90 days before them, scaled to 56; it is not proof, and Other Startups’ results print beside it. The leaf counts entry Offer starts within 30 days per 100 askers who got a shipped tool or Sample link.
How it moves it: each asker got the tool they asked for at a median of 19 h, in their own thread, posted by you.
Guardrails: before against after: paid per entry start, 0.57 against 1.00 (new-paying-customers per entry; 1 of 1 before), and removed posts, 0 of 16 calls against none posted before.
{
"$id": "https://api.sb/leaseline.app/campaigns/request-desk" ,
"$type": "Campaign",
"play": "play:request-desk@1" ,
"path": [
"requester-entry-rate",
"icp-reached",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "requester-entry-rate",
"unit": "per-100",
"heldBack": 0,
"decision": null
},
"readout": {
"value": null,
"n": 58,
"maturing": 6,
"interval": null,
"readability": "inadmissible",
"basis": "before-after",
"pooled": true
},
"ledger": {
"spend": 0,
"workerCost": 41,
"hours": 5.6,
"pipelineArr": 2400,
"wonArr": 1388,
"projectedArr": 401,
"paybackDays": 11
}
}Outside benchmark: this Play’s catalog record carries no sourced range yet, so Other Startups’ results stand in: +6.0 entry starts per 100 askers, ■■■□ Likely, n 1,880.
Before it · After it. Before it: community-answers finds the Rooms where your buyers post. After it: free-tools keeps the tools people return to, signup-interviews hears the day-30 Interview asks, and product-led holds the entry starts.
Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 8 Friday calls in 2 communities, 156 requests, 64 tools built and 29 Samples sent, and every asker answered. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Answered within 72 h | Entry starts (credited, not all caused by this Play) |
|---|---|---|---|
| Build it in 24 hours | 64 | 64 (62 built inside 24 h) | 6 |
| Send a Sample | 29 | 29 | 1 |
| Answer in writing · Not this week · Not ours to build | 21 · 33 · 9 | 21 · 32 · 9 | 0 · 0 · 0 |
| To the AE | 3 | 3 | 1 Quote open ($2,400) |
| All askers · before | 156 · 22 answered by hand | 121 of 124 posted inside 72 h | 7 of 58 matured · 1 of 22 |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_6003 Campaign.created | the three steps; the dry run fails owner | 15 min |
| 0 | event_6005 Task.assigned | your Friday and Monday reply slots, 45 min each | 2 min |
| 1 | event_6019 App.published | the first tool live: a vacancy-cost calculator, 19 h after the ask | — |
| 8 | event_6061 Role.updated | promoted: builds and Samples ship after the known-answer cases pass | — |
| 23 | event_6088 Campaign.paused | build-clock: one build took 26 h; you posted the delay reply | 4 min |
| 28 · 56 | event_6094 Change.merged · event_6131 Readout.created | a point for files people already keep: replayed at 13.0 per 100, read back at +28d at 12.1, n 31 | 5 min |
| 1–56 | event_6012 Approval.created, first of 124 | you posted 124 replies in your slots; claims-resolve refused 2 drafts, each rewritten once and posted; weekly reviews | 5 h · total 5.6 h measured, 6 h asked |
u/rentroll_rita, r/PropertyManagement, Oct 17 15:22 · “I rebuild our turnover calendar from a spreadsheet every January.”
Dana, Oct 18 10:05 · Built it: drop your spreadsheet in and it lays out every turnover for the year, free.¹ leaseline.app/tools/turnover-calendar *Posted with the Role’s disclosure line.*²
Rita, Oct 18 11:40 · ran it 4 times that week, then started a Pro trial on Oct 19.
- Glad it helped: you’ve run the owner report 23 times this week!
+ Glad it helped. If you want it to run every month on its own, say the word and I’ll show you how. Kai at Westbrook Lofts, 2026-10-06 15:00 · “Does Leaseline do this for a whole portfolio? We have 180 units.” · Dana, 15:20 · *Good question. Priya, our account lead, answers by tomorrow 15:00.*³ The Brief went to Priya (
task_644), who replied at 10:12 the next day with a Quote.
¹ The promise kept exactly: the tool, free, within the 24-hour window the call stated. ² The disclosure line, compiled from the Role’s Settings; Dana posts it by hand. ³ The routed line, compiled from the Role’s Settings.
Your settings
---
holdout: 0 # every asker gets an answer; it reads before-after
call: friday # one call a week, in r/PropertyManagement and Dana’s LinkedIn
---
Build the weekly 10 within 24 hours; the last 3 slots are a logged draw. A point more for files people already keep.
Draft every reply for Dana to post by hand.$ npx startup-builder show plays/request-desk
holdout 0 · call friday · weekly 10, 3 drawn · a point for kept files · Dana posts every reply your file plays/request-desk.mdx:2,3,5,6 (Ask 2026-08-24; line 5 by change_33, 2026-09-21)
worker role:content-lead, owns never · chooses 6 (2 rule, 4 read) · sequence requester-check-in · approval every-send, first-send · checks owned-by-a-person, correctness, consent-stop, claims-resolve, seeded-request, public-fetch · stops 10 · placements linkedin, x, reddit, hacker-news, github, google-search, mcp-registry catalog play:request-desk@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record request-desk 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.