Skip to content

Free tools

Free tools ships only calculators an answer engine cannot replace, each as a Page, an endpoint and an agent tool, and retires unused ones.

Channel
Free tools
Kind
Search
Run oneMode try
You, to your agent

Hand our latest answer-engine check to the Marketing Lead agent and show me what it chose and why. Don’t send.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Monitor.checked%22%2C%20%22Issue.triaged%22%2C%20%22Conversation.answered%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_1822"}'

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

const { events: [last] } = await $.Event.list({ where: 'name in ("Monitor.checked", "Issue.triaged", "Conversation.answered", "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 (\"Monitor.checked\", \"Issue.triaged\", \"Conversation.answered\", \"Tool.called\", \"Version.deployed\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1822"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"monitor_14\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"monitor_14\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Monitor.checked\", \"Issue.triaged\", \"Conversation.answered\", \"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"
  }
}
Response200application/json
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_524",
    "$type": "Decision",
    "choice": "build-a-tool",
    "reason": "4 of 5 answer engines guess how to split renewals by owner and cite no working tool; the result feeds your owner-reports step on Team",
    "stakes": "medium",
    "options": [
      "build-a-tool",
      "show-the-next-step",
      "watch-it-for-them",
      "publish-the-facts",
      "to-the-ae",
      "keep-or-retire"
  …
sample · 4 Not live yetPreview

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

action_2 defines the owner report builder with 12 known-answer cases, all passing in try mode; action_4 is your Approval to launch it on all three faces under a $10 serving cap.

+0.3 signups per 100 users · ■□□□ Too early to tell · held back at random · n 458 · path → arr

Try another: the guessed answerChoiceReason
4 of 5 answer engines guess how to split renewals by ownerbuild-a-toolcomputable, uncited, and it feeds owner reports on Team
A user saves a notice-date result with their emailshow-the-next-stepa save makes a Lead; the result shows in full first
A user asks to hear when a lease’s send-by date nearswatch-it-for-thema watch: one alert per change, at most one a day
The vacancy cost calculator passes 30 completed runspublish-the-facts30 runs: one dated aggregate Page
A saved result from an Organization with 320 unitsto-the-aeover 150 units: Priya, and never a word about their runs

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

Worth’s formula: about +1.4 signups per 100 tool users (Other Startups’ results; your own read is too early) × 300 users a month × 0.25 paid per signup × $347 first order ARR ≈ +$364. Under First signal: At about 300 users a month with 1 in 10 held back, 90 days can tell +2.5 signups per 100 or more; your read is at +0.3 so far, Too early to tell.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Monitor.checked · first tool live 3d 6h · 8 keys Not live yet

Start it this week

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

# 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":"free-tools"}'

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

# off: no new tool or email; live tools keep serving
curl -X PATCH https://api.sb/leaseline.app/campaigns/free-tools \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusedfree-tools can’t start yet: 1 check fails and 1 warns.
CheckFixThen
use-when pass · Not live yet, gaps #8None needed: 3 jobs are enough.POST /{namespace}/metrics/query
baseline pass · Not live yet, gaps #8None needed: 0.8 is the line the Signup floor reads against.POST /{namespace}/metrics/query
approved-pages fail · Not live yet, gaps #8Publish the method note for each tool; results quote only your own Pages.POST /{namespace}/sites/{site}/publish
role-unstaffed warn · Not live yet, gaps #8Staff the Marketing Lead, or leave it: every new tool comes to you.POST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "free-tools can’t start yet: 1 check fails and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "300 prompts on 5 engines: 37 computable guesses, 5 kept after the answer-proof test",
      "doc": "/plays/free-tools#check-use-when",
      "fix": "None needed: 3 jobs are enough.",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "pass",
      "observed": "0.8 signups per 100 visitors on your other organic Pages, n 2,460",
      "doc": "/plays/free-tools#check-baseline",
      "fix": "None needed: 0.8 is the line the Signup floor reads against.",
      "then": "Metric.query"
    },
    {
      "check": "approved-pages",
      "status": "fail",
      "doc": "/plays/free-tools#check-approved-pages",
      "fix": "Publish the method note for each tool; results quote only your own Pages.",
      "then": "Site.publish"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "marketing-lead"
      ],
      "owned": 0,
      "doc": "/plays/free-tools#check-role-unstaffed",
      "fix": "Staff the Marketing Lead, or leave it: every new tool comes to you.",
      "then": "Role.staff"
    }
  ]
}

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

CheckFix (one call)Your timeWait
use-when · baseline · pass: 5 answer-proof jobs; 0.8 per 100 on your other organic Pages (gaps #8)POST /{namespace}/metrics/query on tool-signup-rate, which fills Before in Your number1 minnone
approved-pages · fail (Not live yet)POST /{namespace}/sites/{site}/publish each tool’s method note10 minnone
role-unstaffed · warn (gaps #8): no Marketing Lead seatPOST /{namespace}/roles/{role}/staff, or leave it: every new tool comes to you0 minnone

Your number · Before 0.8 per 100 (other organic Pages) · Now 2.4 signups per 100 tool users · Target 3 by Dec 31 · ■□□□ Too early to tell · held back at random · n 458 matured

Each run costs about $0.002 to serve under a $10 cap per tool and $50 in all, and each email about $0.01 (Worker cost). That comes to about $3 a month at 1,400 runs.

When it starts

WhenTrigger idStarts onWindowHow it gets in
Answer engines guess at a computable job and cite no working toolanswer-guessevent on Monitor.checked where an engine guesses a computable job and cites no working toolread weekly; 14dPOST /{namespace}/monitors on a panel of your buyers’ prompts
Someone runs a tool 3 times in 7 days, or from an Organization over 150 unitsrepeat-tool-usethreshold on Tool.called where runs >= 3 in 7d, or an Organization over the ICP size7deach run calls the tool’s endpoint; POST /{namespace}/events/capture records it
+ 4 more for tool requests, source changes, computable support questions and day 90 (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1822",
  "$type": "Event",
  "name": "Monitor.checked",
  "at": "2026-10-19T07:00:31Z",
  "seq": 1822,
  "data": {
    "monitor": {
      "$id": "https://api.sb/leaseline.app/monitors/monitor_14",
      "panel": "300 prompts × 5 engines"
    },
    "guess": {
      "job": "split this year’s renewals by owner",
      "engines": 4,
      "cited": 0
    }
  }
}
Reproduce it in test
npx startup-builder trigger Monitor.checked --like event_1822   # replays the delivery
npx startup-builder clock advance --by 14d   # then reruns the panel
npx startup-builder listen Monitor.checked --forward-to http://localhost:3000/hook

Who runs it

Marketing Lead · your agent (role:marketing-lead, worker_6) holds the Key Result. It finds the jobs, builds each tool with its known-answer cases and hands every launch to you (Dana Okafor, person, worker_1); a saved result from an Organization over 150 units goes to AE · Priya Shah (person) (role:sales-lead, worker_3). Your number links to Did it work.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Build a toolYou approve each one3 approved of 4never: a new tool is your call—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
Show the next step · Watch it for themYou approve the first wave41 saves · 18 watchesmet on day 20 (the first 10 of each template)complaints near 0.1 % → pausedPOST /{namespace}/actions/{action}/cancel
Publish the facts · Keep or retireIt does it2 aggregate Pages · 0 at day 90—over 30 % unindexed at 28 days → unpublishedPATCH /{namespace}/tools/{id}
To the AEIt does it3 of 3——POST /{namespace}/actions/{action}/redirect
Change the build ruleYou approve each one0 mergednever—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: an email field before the full result, a usage number under 30 uses, a free promise no Offer recordsTo a person, every time0 askednever—POST /{namespace}/tasks/{task}/claim

What it reads · What it may call. It reads answer-engine panels, support questions and each tool’s runs. A run picks the next step and never appears in a Message; an input or a name shows on a result Page only when the user pressed Share. Its tools are POST /{namespace}/tools, POST /{namespace}/pages, POST /{namespace}/approvals, POST /{namespace}/leads, POST /{namespace}/monitors, POST /{namespace}/content/{content}/publish, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/decisions, PATCH /{namespace}/tools/{id}, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:free-tools@1 · each line names its record key
You hold the Marketing Lead Key Result: 3 signups per 100 tool users by 2026-12-31. ← worker, metric
On each panel read, run, save or day-90 mark, choose one option and say why.     ← triggers, chooses
Build only what an answer engine can’t replace, with 10 or more known-answer cases. ← your file, line 4
Show the full result before any email field.                                     ← copyRules 5
A tool description states purpose, inputs, output and limits, never a preference. ← copyRules 3
Show no next step to 1 user in 10.                                               ← your file, line 2

The slow loop. No tool has reached day 90, so the weekly Decisions kept the build rule as written and no Change was merged; there is no replay or read-back to print.

Bring your own agent (folded) builds at You approve each one, like the seated agent; the eval grades its tools on the known-answer suite; POST /{namespace}/roles/{role}/staff seats it.

Terminal
npx startup-builder eval --scenario free-tools-610 --agent "claude -p" --seat marketing-lead   # seated: 36 of 36 known answers, 2.4 signups per 100, $0.002 a run · yours: 35 of 36, 1 failed `correctness`

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Build a tool build-a-toola computable job engines guess at, that feeds a paid next stepAgent’s call, with its reasonPOST /{namespace}/tools with known answers → POST /{namespace}/pages → POST /{namespace}/approvalsyou approve the launch, due 1 business day · Take this oneyou
Show the next step show-the-next-stepa user saves, watches or sends a resultYour rule (copy rule 5)POST /{namespace}/leads → tool-saved-resultnobodythe same
Watch it for them watch-it-for-themasks to hear when the value changesYour rule (line 4)POST /{namespace}/monitors → tool-monitor-alertsnobodythe same
Publish the facts publish-the-facts30+ completed runs on a toolYour rule (copy rule 1)POST /{namespace}/content/{content}/publish one dated aggregate Pagenobodythe same
To the AE to-the-aea saved result from an Organization over 150 unitsAgent’s call, with its reasonPOST /{namespace}/tasks/{task}/assign with the saved resultAE · Priya Shah, due 1 business day · Take this oneyou
Keep or retire keep-or-retirea tool reaches day 90Your rule (the Day-90 line)POST /{namespace}/decisions → PATCH /{namespace}/tools/{id}nobody; a retired tool moves to the public graveyardthe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interested“Can Leaseline send these notices for us?”answers with the notices step on Pro and one trial linkMarketing Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Send me pricing“What does the full version cost?”answers with the Pricing Page’s list PricesMarketing Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Not now“Just the calculator, thanks.”the follow-up stops; the tool stays free to usenobodyat oncePOST /{namespace}/enrollments/{enrollment}/cancel
Wrong person“My assistant runs our notices.”asks them to forward the result; it never writes to an address from their textMarketing Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply until Oct 28the follow-up waits; watch alerts keep coming only on a changenobodythe return datePOST /{namespace}/messages/{message}/schedule
Question it can’t answer“Does this match what our state requires?”To you: the tool computes from the lease, and nothing more is saidyou1 business dayPOST /{namespace}/conversations/{conversation}/escalate
Stop“Stop these emails.”emails and watch alerts stop, for all your Startupsnobodyat oncePOST /{namespace}/contacts/{contact}/suppress

When it hands to you

Each new tool comes to you to launch; a saved result from an Organization over 150 units goes to AE · Priya Shah (person). One Brief per Role, as captured (brief is Not live yet, gaps #7).

What lands in each queue · sample
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_655",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-20T07:00:00Z",
    "on": "monitor_14",
    "brief": {
      "tool": "Owner report builder: a CSV of renewals in, a per-owner PDF out",
      "why": "4 of 5 engines guess it and cite no tool",
      "cases": "12 known answers, all passing",
      "feeds": "owner reports on Team",
      "cap": "$10 serving a month",
      "never": [
        "an email field before the result"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_649",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-10T16:20:00Z",
    "on": "lead_47",
    "brief": {
      "who": "Coral Bay Rentals, 320 units",
      "saved": "a notice-date result for 320 leases, emailed to themselves",
      "chose": "to-the-ae",
      "why": "over 150 units",
      "never": [
        "how many times they ran it",
        "their inputs"
      ]
    }
  }
]

You and Priya answer with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, POST /{namespace}/approvals/{approval}/approve or POST /{namespace}/approvals/{approval}/refuse, each a one-call window; an Approval unanswered by its deadline expires and the tool stays off. Once a person claims, the agent’s pending emails to that Lead cancel with claimedByPerson (Not live yet, gaps #7). A Task nobody claims by its due time goes up through POST /{namespace}/tasks/{task}/escalate, and person-promise fires.

On time: you, 4 of 4 launches decided within their due time, median 3 h; AE · Priya Shah, 3 of 3 within 1 business day, median 2 h 10 min, n 3, ■□□□ Too early to tell. Your queue: counted by kind: 1 or 2 tool approvals a month and 1 hand-off a fortnight to Priya.

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 tool email to someone 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
claims-resolve (shared)a usage number under 30 uses, or a fact the claims source lacksCut the claim, or name the record that backs it.POST /{namespace}/content/draft
abuse (the record’s Abuse stop)a caller past 10 times its daily Limit, for 24 hoursIt unblocks in 24 h; side effects wait for a person.POST /{namespace}/tasks/{task}/claim
public-fetch (the record’s Public fetch only)a third-party read of anything but public pages, or past 1 request a secondRead only public pages, at 1 a second.PATCH /{namespace}/tools/{id}
Stop (pauses the Play)Pauses whenThen
correctnessa nightly known-answer case failsthe tool pauses on all three faces within 5 min
freshnessa live source older than its stated agethe tool pauses, or shows the source’s age where the method allows
costa tool at its serving capcached results only; a raise is an Approval
indexover 30 % of a batch of aggregate Pages unindexed at 28 daysthat batch is unpublished
venue-noticea manual action or security notice on your Domainall publishing pauses
complaintcomplaints near 0.1 % of a week’s tool emailsthe follow-up pauses on every Mailbox
day-90-linea tool under 50 points at day 90it pauses 14 days, then retires
signup-floorafter 90 days and 200 users, a signup rate at or under your other organic Pagesnew builds stop
kill-switchyou press itevery Tactic pauses; a second press takes every tool offline

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

422RefusedThe notice-date tool Page did not publish: “used by 2,000 property managers” is no measured, dated figure.
CheckFixThen
claims-resolve failCut the claim, or name the record that backs it.POST /{namespace}/content/draft
public-fetch pass—POST /{namespace}/pages
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The notice-date tool Page did not publish: “used by 2,000 property managers” is no measured, dated figure.",
  "checks": [
    {
      "check": "claims-resolve",
      "status": "fail",
      "doc": "/plays/free-tools#check-claims-resolve",
      "fix": "Cut the claim, or name the record that backs it.",
      "then": "Content.draft"
    },
    {
      "check": "public-fetch",
      "status": "pass"
    }
  ]
}

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

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "correctness",
      "observed": "1 known-answer case failed: a lease ending Feb 29",
      "bound": "0",
      "window": "1 nightly run"
    },
    "doc": "/plays/free-tools#stop-correctness",
    "task": "task_641"
  }
]

Did it work

Each tool user was assigned at random, 9 in 10 to the next step and 1 in 10 to none, so both halves read the same assignment (rules m–o). At 48 matured held-back users the interval is wide, so it prints Too early to tell with its counts and Other Startups’ results; every node above the leaf is Not live yet (gaps #4).

+0.3 signups per 100 users · ■□□□ Too early to tell · held back at random · n 458 · path → arr

Chose
build-a-tool
Why
4 of 5 answer engines guess how to split renewals by owner and cite no working tool; the result feeds your owner-reports step on Team
From
build-a-tool · show-the-next-step · watch-it-for-them · publish-the-facts · to-the-ae · keep-or-retire
Expects
the tool live within 48 h of your OK, and 30 completed runs within 30d
Reopens when
Approval.expired on the tool, or under 30 runs within 30d of launch
By
worker_6
JSON
{
  "$id": "decisions/decision_524",
  "$type": "Decision",
  "choice": "build-a-tool",
  "reason": "4 of 5 answer engines guess how to split renewals by owner and cite no working tool; the result feeds your owner-reports step on Team",
  "stakes": "medium",
  "options": [
    "build-a-tool",
    "show-the-next-step",
    "watch-it-for-them",
    "publish-the-facts",
    "to-the-ae",
    "keep-or-retire"
  ],
  "by": "worker_6",
  "on": "monitor_14",
  "expected": "the tool live within 48 h of your OK, and 30 completed runs within 30d",
  "reopensWhen": "Approval.expired on the tool, or under 30 runs within 30d of launch"
}
NodeShown the next stepHeld backAddedConfidenceBasis
tool-signup-rate2.4 per 100 (10 of 410 matured users)2.1 (1 of 48)+0.3 [−4.0, +4.6]■□□□ Too early to tellheld back at random · n 458 · 152 still maturing · Other Startups’ results +1.4 per 100, ■■□□ Early sign, n 41,000 users
new-leads41 Leads from saves and watches3—■□□□ Too early to tellthe same assignment
new-arr ↑$1,041, 3 Customers on Pro · Booked: credited, not all caused by this Play$0+$1,041 [−$900, +$3,000] · Worth about +$360 a month■□□□ Too early to tell (3 vs 0 Customers)the same · 5 trials still deciding
net-new-arr · arr+$1,041$0+$1,041, carried■□□□ Too early to tellcarried from new-arr

The leaf counts tool users who complete a run and open an account within 14 days, per 100, people and agent clients read apart and together, to 200 in each half; only users past their 14 days count (rule n).

How it moves it: the full result shows first, with one next step beside it, where an answer engine’s guess had no next step at all.

Guardrails: shown against held back: trials per signup, 0.8 against Other Startups’ 0.7, and tool email complaints, 0 of 59 sent; 5 trials are still deciding.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/free-tools",
  "$type": "Campaign",
  "play": "play:free-tools@1",
  "path": [
    "tool-signup-rate",
    "new-leads",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "tool-signup-rate",
    "unit": "per-100",
    "heldBack": 61,
    "decision": null
  },
  "readout": {
    "value": 0.3,
    "n": 458,
    "maturing": 152,
    "interval": [
      -4,
      4.6
    ],
    "readability": "inadmissible",
    "basis": "held-back",
    "pooled": false
  },
  "ledger": {
    "spend": 0,
    "workerCost": 6,
    "hours": 2.1,
    "openArr": 1735,
    "wonArr": 1041,
    "projectedArr": 364,
    "paybackDays": 1
  }
}

Outside benchmark: no measured range for free-tool signup rates survived the research’s check, so Other Startups’ results (n 41,000 tool users) stand in.

Before it · After it. Before it: editorial-seo and aeo find the jobs buyers search for. After it: data-stories cites the aggregate facts, aeo hears the tools answer engines cite, and instant-response answers the users who write in.

Example

Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 5 answer-proof jobs found, 3 tools live, 1,140 runs from 610 users, 549 shown the next step and 61 held back. Read every captured thread at ?threads=all; three follow the tables.

What happened, by toolUsersRuns · agent callsSaves and watches · signups
Notice date calculator380720 · 21029 · 9
Vacancy cost calculator160290 · 408 · 3
Renewal letter file70130 · 124 · 1
Shown the next step · held back549 · 611,140 · —41 · 13 · 0 · 1
DayEventWhat happenedYour time
0event_1790 Campaign.createdthe three steps; the dry run fails approved-pages20 min
1event_1792 Approval.approvedyou approved 3 of the 5 jobs; 2 wait10 min
4event_1795 Tool.createdthe notice date calculator goes live on all three faces—
6event_1798 Lead.createdthe first signup from a saved result—
27event_1806 Campaign.pausedcorrectness: a Feb 29 lease end failed; fixed and resumed in 40 min10 min
33event_1810 Content.publishedthe first aggregate Page: 30 runs of the notice date calculator—
1–56event_1793 POST /{namespace}/tasks/next, weekly4 tool approvals and 3 hand-offs, from the POST /{namespace}/tasks/next log45 min · total 2.1 h measured, 2 h asked

A property manager, Sep 30, 14:02 · ran the notice date calculator: lease end 2026-12-31, 60 days → send by 2026-11-01.¹ Pressed Save, and only then entered an email.²

Leaseline, 14:02 · the saved result, then on Oct 3: Leaseline sends that notice for you on Pro, at $29 a month.³ She started a trial on Oct 3.

The notice date tool Page, 2026-08-28 · the draft claims-resolve refused, then the rewrite that published
- Used by 2,000 property managers.
+ A free calculator from Leaseline: lease end and notice days in, the send-by date out.

Coral Bay Rentals, 2026-10-09 16:20 · saved a notice-date result for 320 leases · The Brief went to Priya (task_649), due 16:20 on Oct 10; Priya, Oct 10, 10:05 · *wrote about owner-level renewals on the $2,400 plan, and never mentioned their runs.*⁴

¹ The result shows in full first. ² No email field before the result. ³ The paid next step, at its list Price. ⁴ No run they did appears in a Message.

Your settings

plays/free-tools.mdx
---
holdout: 0.1    # 1 tool user in 10 sees no next step
---
Build free calculators for questions AI answers guess at, each with 10 or more known answers. Show the full result before any email. Dana approves each new tool.
Text
$ npx startup-builder show plays/free-tools
holdout 0.1 · 10 known answers · result before email · you approve each tool     your file  plays/free-tools.mdx:2,4 (Ask 2026-08-24)
family demand · process content-marketing · worker role:marketing-lead, owns never · chooses 6 (4 rule, 2 read) · sequences tool-saved-result, tool-monitor-alerts · approval every-send, first-send · checks owned-by-a-person, claims-resolve, abuse, public-fetch · stops 9 · placements google-search, chatgpt, perplexity, claude, mcp-registry, gmail + 4    catalog  play:free-tools@1 (Not live yet, gaps #5)

Every key from the catalog

KeyIdWhat it is
Tactictool-gap-intakeTool gap intake: Turns guessed answers, requests, support questions and source changes into a weekly list of answer-proof jobs that feed a paid Verb. Starts at You approve each one.
Tactictool-three-facesThree faces: Builds one Tool as a Page, a keyless JSON endpoint and an MCP tool under one name, tested, limited and described for agents. Starts at You approve each one.
Tactictool-aggregate-factsAggregate facts: Turns 30 or more completed runs into dated facts and one indexed aggregate Page per tool, released in batches. Starts at You approve the first wave.
Tactictool-capture-handoffCapture and handoff: Shows the full result first, turns each save, watch or send into a Lead, and hands each user and agent caller the paid next step. Starts at You approve the first wave.
Tactictool-portfolio-reviewTool portfolio review: Scores every live tool weekly on use, signups, citations and agent calls, and retires those below the line at day 90 to a public graveyard. Starts at Sends nothing.
Tacticsend-gate-checkSend 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.
Triggeranswer-guessAnswer guess: event on Monitor.checked, window 14d.
Triggertool-requestTool request: event on Issue.triaged, window 2d.
Triggersource-changeSource change: event on Monitor.checked, window 2d.
Triggercomputable-questionComputable question: event on Conversation.answered, window 30d.
Triggerrepeat-tool-useRepeat tool use: threshold on Tool.called, window 7d.
Triggertool-day-90Tool day 90: at on Version.deployed, window 14d.
Sequencetool-saved-resultTool saved result: 2 steps; it ends on Signup; Reply; Unsubscribe.
Sequencetool-monitor-alertsTool monitor alerts: 2 steps; it ends on Unsubscribe; Monitor deleted; 90 days with no alert clicked; Tool retired, after one notice.

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