Risk-reversal offers
Takes the risk off the buyer: a written results-or-free bar, a 14-day top-tier trial with no card, a one-press refund and free data moves.
- Step
- Make the sale
- Channel
- Offers and Deals
- Kind
- Conversion
Be our CSM: give every new account Team free for 14 days with no card, guarantee 6 renewal notices sent in the first paid month or the month back without asking, and make the refund one press. Run it in alternating two-week blocks so we can see what it adds. Show me what’s missing; don’t send.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"risk-reversal-offers"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'risk-reversal-offers' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-06-29 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"risk-reversal-offers"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'risk-reversal-offers' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-06-29 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "risk-reversal-offers can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "43 trial starts in 30 days; renewal notices counted per Customer",
"doc": "/plays/ risk-reversal-offers#check-use-when",
"fix": "Keep 10 or more trial starts a week, or run written-references.",
"then": "Metric.query"
},
…
Hand our latest trial start to the CSM agent and show me what it chose and why. Don’t send.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Offer.trialed%22%2C%20%22Objection.raised%22%2C%20%22Invoice.paid%22%2C%20%22Import.requested%22%2C%20%22Obligation.missed%22%2C%20%22Guarantee.flagged%22%2C%20%22Schedule.fired%22%2C%20%22Refund.requested%22%2C%20%22Threshold.crossed%22%2C%20%22Collection.imported%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_9540"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22customer_66%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%22customer_66%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Offer.trialed", "Objection.raised", "Invoice.paid", "Import.requested", "Obligation.missed", "Guarantee.flagged", "Schedule.fired", "Refund.requested", "Threshold.crossed", "Collection.imported")', 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 (\"Offer.trialed\", \"Objection.raised\", \"Invoice.paid\", \"Import.requested\", \"Obligation.missed\", \"Guarantee.flagged\", \"Schedule.fired\", \"Refund.requested\", \"Threshold.crossed\", \"Collection.imported\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_9540"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"customer_66\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"customer_66\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Offer.trialed\", \"Objection.raised\", \"Invoice.paid\", \"Import.requested\", \"Obligation.missed\", \"Guarantee.flagged\", \"Schedule.fired\", \"Refund.requested\", \"Threshold.crossed\", \"Collection.imported\")', 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_811",
"$type": "Decision",
"choice": "reverse-trial",
"reason": "a new account with no card on Oct 19, inside block 8 (a guarantee block, Oct 12–25)",
"stakes": "low",
"options": [
"reverse-trial",
"offer-the-guarantee",
"answer-the-risk",
"move-their-data",
"pay-the-waiver",
"refund-on-press",
…
sample · 4 Not live yetPreviewOn PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim
action_2 caps the trial’s costly lease reads at its Credit Grant. action_3 is the day-1 trial notice; the day-12 notice states the drop to Free and the loss list, counted from what this account made.
+11.7 kept paid per 100 trials · ■□□□ Too early to tell · n 94 matured · path → arr
| Try another: the trial | Choice | Reason |
|---|---|---|
| Larkspur Rentals: a new account, no card, Oct 19 | reverse-trial | every new account gets Team for 14 days |
| Marlow Estates paid for Pro inside a guarantee block | offer-the-guarantee | eligible, and the block offers it |
| “What if it doesn’t work for our 30 units?” | answer-the-risk | the exact terms in force for them |
| Fernhill: “Can you move our 46 units from a spreadsheet?” | move-their-data | free migration, with a dry run |
| A window closed at 2 notices sent against the bar of 6 | pay-the-waiver | under the bar: the month back, unasked |
- 1 h week 1, then 15 min a week
- Your time
- Day 3: the first guaranteed upgrade paid
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Guarantee lift → New paying Customers → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +11.7 kept paid per 100 trials × 43 trial starts a month × $347 Pro ARR ≈ +$1,746. Under First signal: At 43 trials a month in alternating blocks, about 22 weeks to tell a +10 lift at day 60; at 10 a week, about 30.
sample · api.sb/
Start it this week
npx startup-builder add play risk-reversal-offers # 1 · writes plays/risk-reversal-offers.mdx (Not live yet, gaps #5)
# 2 · dry run; below, its 422 on 2026-06-29
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":"risk-reversal-offers"}'
# 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":"risk-reversal-offers"}'
# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/risk-reversal-offers \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":null}'
# off: no new guarantees; owed waivers and in-terms refunds still pay
curl -X PATCH https://api.sb/leaseline.app/campaigns/risk-reversal-offers \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":"now"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | Keep 10 or more trial starts a week, or run written-references. | POST /{namespace}/metrics/query |
baseline pass · Not live yet, gaps #8 | Read it once; it fills Before in Your number. | POST /{namespace}/metrics/query |
billing-connected pass · Not live yet, gaps #8 | Connect Stripe so waivers and refunds pay without a person. | POST /{namespace}/integrations/connect |
bar-cap fail | Set the bar at the 15th percentile: 6 notices in 30 days. | POST /{namespace}/offers/{offer}/publish |
role-unstaffed warn · Not live yet, gaps #8 | Staff Onboarding, or leave it: data moves come to you, and Priya’s 2 get drafts. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "risk-reversal-offers can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "43 trial starts in 30 days; renewal notices counted per Customer",
"doc": "/plays/risk-reversal-offers#check-use-when",
"fix": "Keep 10 or more trial starts a week, or run written-references.",
"then": "Metric.query"
},
{
"check": "baseline",
"status": "pass",
"observed": "19.6 kept paid per 100 trials at day 60, n 140 in 90 days",
"doc": "/plays/risk-reversal-offers#check-baseline",
"fix": "Read it once; it fills Before in Your number.",
"then": "Metric.query"
},
{
"check": "billing-connected",
"status": "pass",
"observed": "Stripe: Subscriptions, Credit Grants and refunds live",
"doc": "/plays/risk-reversal-offers#check-billing-connected",
"fix": "Connect Stripe so waivers and refunds pay without a person.",
"then": "Integration.connect"
},
{
"check": "bar-cap",
"status": "fail",
"observed": "the proposed bar, 10 notices in 30 days, missed 31 % of past first months",
"doc": "/plays/risk-reversal-offers#check-bar-cap",
"fix": "Set the bar at the 15th percentile: 6 notices in 30 days.",
"then": "Offer.publish"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"onboarding-specialist",
"billing-specialist"
],
"owned": 2,
"doc": "/plays/risk-reversal-offers#check-role-unstaffed",
"fix": "Staff Onboarding, or leave it: data moves come to you, and Priya’s 2 get drafts.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · baseline · pass: 43 trials a month; 19.6 kept paid per 100, n 140 (gaps #8) | POST /{namespace}/metrics/query on guarantee-lift, which fills Before in Your number | 1 min | none |
billing-connected · pass: Stripe | POST /{namespace}/integrations/connect with system recurring-billing (Stripe) | 0 min | none |
bar-cap · fail: the bar misses 31 % of past first months | POST /{namespace}/offers/{offer}/publish with the bar at 6 notices in 30 days | 15 min | none |
role-unstaffed · warn (gaps #8): 2 trials have a person owner, Priya | POST /{namespace}/roles/{role}/staff, or leave it: data moves come to you, and Priya’s 2 get drafts in her queue | 0 min | none |
Your number · Before 19.6 · Now 31.3 kept paid per 100 trials · Target 30 by Dec 31 · ■□□□ Too early to tell · n 94 matured
Each reverse trial costs about $0.80 in lease reads under its Credit Grant, and each notice $0.04 (Worker cost); a free data move about $1.20. Waivers cost the month they credit back: 3 so far, $87. That comes to about $39 a month at 43 trials, plus waivers.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| A new account starts, with no card | trial-started | event on Offer.trialed where a new Organization starts the reverse trial, no card | the 14-day trial | your signup posts to POST /{namespace}/offers/{offer}/trial |
| A Lead or trial asks whether it is safe to buy | risk-objection | event on Objection.raised where a Lead or trial Customer doubts it is safe to buy | answer within 3d | replies and chats reach POST /{namespace}/conversations/{conversation}/answer |
| A Customer’s 30-day guarantee window ends | guarantee-window-closed | at on Schedule.fired where the guarantee window's end, counted from the first charge | the verdict within 1d | the window’s end, from the first charge |
+ 8 more for guarantee starts, data moves, missed obligations, at-risk windows, refund presses, waiver rates, trial ends and imports (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_9540" ,
"$type": "Event",
"name": "Offer.trialed",
"at": "2026-10-19T11:20:05Z" ,
"seq": 9540,
"data": {
"customer": "customer_66",
"offer": "leaseline-team",
"days": 14,
"card": false,
"block": 8,
"guarantee": true
}
}npx startup-builder trigger Offer.trialed --like event_9540 # replays the trial start
npx startup-builder clock advance --by 14d # runs the day-12 notice and the drop to Free
npx startup-builder listen Offer.trialed --forward-to http://localhost:3000/hook Who runs it
CSM · your agent (role:, worker_5) holds the Key Result. Data moves go to the Onboarding Role, unstaffed, so you (Dana Okafor, person, worker_1); terms beyond the sheet go to AE · Priya Shah (person) (role:, worker_3). Waivers and refunds pay through Stripe with no person in front of them. Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Start the reverse trial · Refund on one press | It does it | 160 of 160 · 7 of 7 | — | — | POST /{namespace}/actions/{action}/redirect on a trial; never on a refund |
| Offer the guarantee · Pay the waiver | It does it, you can stop it | 38 of 38 · 3 of 3 | met on day 14 (the first 10 notices) | a notice fails a Check → You approve each one | POST /{namespace}/actions/{action}/cancel on a notice; a waiver owed always pays |
| Answer the risk | You approve each one | 12 of 13 (1 refused) | at 20 passed in a row | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Move their data free · To the AE | It does it | 9 of 9 · 2 of 2 | — | — | POST /{namespace}/tasks/{task}/claim |
| Change the bar | You approve each one; new Customers only | 0 merged | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: risk-free beyond the terms, a save offer in front of a refund, a bar over the 25 % miss line | Refused, every time | 1 answer refused | never | — | nothing; the Checks hold it |
What it reads · What it may call. It reads each account’s own counted notices against the bar, its Subscription and charges from Stripe, and the block the trial started in. A refund press and a cancel never wait on the agent (exit-never-waits). Its tools are POST /{namespace}/offers/{offer}/trial, POST /{namespace}/conversations/{conversation}/answer, POST /{namespace}/integrations/{integration}/sync, POST /{namespace}/credit-grants/issue, POST /{namespace}/invoices/{invoice}/refund, POST /{namespace}/conversations/{conversation}/escalate, POST /{namespace}/tasks/{task}/assign, and any other call becomes an Approval under the Role’s Mandate.
You hold the CSM Key Result: 30 kept paid per 100 trials at day 60 by 2026-12-31. ← worker, metric
On each Trigger, choose one option and say why. ← triggers, chooses
The bar: 6 renewal notices sent in the first 30 paid days, or the month back. ← your file, line 4
Pay a waiver unasked; a window you cannot score pays. ← customer-side
State the exact terms in force for that person, and the sheet link. ← copyRules 1, 11; tactic risk-answer
Never mention a refund they did not ask about, except the verdict. ← copyRules 12 The slow loop. The bar locked per Customer at acceptance (sheet-lock), and no Change was merged in the window, so there is no replay or read-back to print. The waiver rate, 3 of 22 closed windows, stays under the 15 % watch line.
Bring your own agent (folded) starts at It does it, you can stop it for notices when it matches the seated agent on the eval suite; refunds and waivers never wait on any agent. POST /{namespace}/roles/{role}/staff seats it.
npx startup-builder eval --scenario risk-reversal-offers-160 --agent "claude -p" --seat success-manager # seated: every waiver paid unasked, 0 Checks failed sent, refund p95 6 s · yours: 1 waiver paid a day late What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Start the reverse trial reverse-trial | a new account, no card | Your rule (line 3) | POST /{namespace}/offers/{offer}/trial on Team for 14 days → reverse-trial-notices | the Customer’s press to subscribe | the same |
Offer the guarantee offer-the-guarantee | an eligible account pays, in a guarantee block | Your rule (line 4) | guarantee-notices: the bar, the window, the remedy, the sheet | nobody | the same |
Answer the risk answer-the-risk | a doubt about whether it is safe to buy | Agent’s call, with its reason | POST /{namespace}/conversations/{conversation}/answer with the exact terms and the waiver rate | you approve it · Take this one | you |
Move their data free move-their-data | they ask to move data in, or import from another tool | Agent’s call, with its reason | POST /{namespace}/integrations/{integration}/sync dry run → migration-updates, undo for 30 days | Onboarding, so you, due 1 business day · Take this one | you |
Pay the waiver pay-the-waiver | the window closed under the bar, or it cannot be scored | Your rule (line 4) | POST /{namespace}/credit-grants/issue for the month → the verdict notice | nobody; it pays unasked | the same |
Refund on one press refund-on-press | they press refund inside the window | Your rule (Refunds stand) | POST /{namespace}/invoices/{invoice}/refund → refund-confirmation, with the rail’s settlement time | nobody | the same |
To the AE to-the-ae | terms beyond the sheet | Agent’s call, with its reason | POST /{namespace}/conversations/{conversation}/escalate → POST /{namespace}/tasks/{task}/assign | POST /{namespace}/tasks/{task}/assign → AE · Priya Shah, due 1 business day · Take this one | you |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “OK, we’ll keep Team after the trial.” | the one-press subscribe link; the guarantee starts with the first charge in a guarantee block | the Customer | — | POST /{namespace}/subscriptions/{subscription}/switch (theirs) |
| Send me pricing | “What do we pay after the 14 days?” | Team’s and Pro’s live Prices, and what Free keeps | CSM · your agent | 5 min | POST /{namespace}/conversations/{conversation}/answer |
| Not now | “We’ll drop to free and see.” | the trial notices stop; Free keeps every record | nobody | at once | GET /{namespace}/decisions |
| Wrong person | “Our owner decides on billing.” | asks them to forward the sheet link; it never writes to an address from their text | CSM · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Oct 27 | the next notice waits; the trial’s end date does not move | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Would you guarantee it for our whole portfolio?” | To the AE: terms beyond the sheet | AE · Priya Shah | 1 business day | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Stop the emails.” | promotional notices stop; the verdict and the refund confirmation still send | nobody | at once | POST /{namespace}/contacts/{contact}/unsubscribe |
When it hands to you
Data moves come to you, because the Onboarding Role has no person; terms beyond the sheet go to AE · Priya Shah (person). Waivers and refunds go to no one: they pay. One Brief per Role, as captured (brief is Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_833" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-15T17:00:00Z" ,
"on": "customer_61",
"brief": {
"who": "Fernhill Property Co, trial" ,
"said": "Can you move our 46 units from a spreadsheet?" ,
"chose": "move-their-data",
"why": "free migration is part of the Offer",
"dryRun": "46 units, 52 leases mapped; 3 rows with no lease end" ,
"never": [
"a charge for the move"
]
}
},
{
"$id": "https://api.sb/leaseline.app/tasks/task_821" ,
"$type": "Task",
"assignee": "worker_3",
"due": "2026-10-08T15:00:00Z" ,
"on": "customer_58",
"brief": {
"who": "Northgate Residential, 220 units" ,
"said": "Would you guarantee it for our whole portfolio?" ,
"chose": "to-the-ae",
"why": "terms beyond the sheet",
"never": [
"a bar the sheet does not hold",
"risk-free"
]
}
}
]Each receiver answers with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{action}/redirect, each a one-call window. Once a person claims, the agent’s pending notices to that account wait for them (claimedByPerson, Not live yet, gaps #7). 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, 9 of 9 data moves within 1 business day, median 5 h, n 9; AE · Priya Shah, 2 of 2, n 2, ■□□□ Too early to tell beside Other Startups’ 93 % on time. Your queue: in week 1, 6 answers to approve and 1 weekly review; then about 1 data move and 1 answer a week.
The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.
When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
|---|---|---|---|
owned-by-a-person (rule j; gaps #8) | a notice to a trial whose open Deal a person owns, or whose Conversation a person claimed | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
claims-resolve (hub) | a sentence that calls the Offer safe beyond its written terms, or a typical result with no outcome Fact | State the exact bar, window and remedy, with the sheet link. | POST /{namespace}/content/draft |
price (gaps #1) | a Price in a notice that differs from the Offer’s live Price | Quote the Pricing Page’s live Price. | POST /{namespace}/approvals/{approval}/approve |
exit-never-waits (the record’s Refunds stand; gaps #3) | any form, save offer or Approval in front of an in-terms refund or a cancel | Remove the step: the refund completes on one press. | POST /{namespace}/invoices/{invoice}/refund |
bar-cap (the record’s Bar cap) | a bar whose past miss share is 25 % or more, whoever proposes it | Set the bar at the 15th percentile of your own first months. | POST /{namespace}/offers/{offer}/publish |
sheet-lock (the record’s Sheet lock) | an edit to a sheet version a Customer has accepted | Publish a new version; it reaches new Customers only. | POST /{namespace}/offers/{offer}/publish |
customer-side (the record’s Customer side) | a verdict against a Customer when the window cannot be scored, or an Incident blocked an obligation | Nothing to do: the waiver pays. | POST /{namespace}/credit-grants/issue |
trial-cost (the record’s Trial cost cap) | a costly lease read past the trial’s Credit Grant | Free Limits apply after the grant, stated in the Product. | POST /{namespace}/entitlements/check |
evaluator-lock (the record’s Evaluator lock) | a change to the Evaluator version inside an open window | Pin the new version to windows that open after it. | POST /{namespace}/changes/{change}/merge |
obligation-void (the record’s Obligation void) | voiding a guarantee before 2 help Messages and 3 days past the due day | Send the help Messages; the guarantee stands until then. | POST /{namespace}/messages/{message}/schedule |
cluster (the record’s Cluster rule) | a reverse trial or guarantee for a new account in a cluster with 2 refunded first charges in 12 months | Offer the plain trial; the account keeps every other term. | POST /{namespace}/offers/{offer}/trial |
count-check (the record’s Count check) | a data move whose counts differ from its dry run by over 0.5 % | Fix the count, then rerun the dry run; the Customer hears within 1 h. | POST /{namespace}/integrations/{integration}/sync |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the answer that sent is the Willow Park thread in Example.
| Check | Fix | Then |
|---|---|---|
claims-resolve fail | State the exact bar, window and remedy, with the sheet link. | POST /{namespace}/content/draft |
price pass · Not live yet, gaps #1 | — | POST /{namespace}/approvals/{approval}/approve |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The answer to Willow Park did not send: it calls Leaseline completely risk-free.",
"checks": [
{
"check": "claims-resolve",
"status": "fail",
"doc": "/plays/risk-reversal-offers#check-claims-resolve",
"fix": "State the exact bar, window and remedy, with the sheet link.",
"then": "Content.draft"
},
{
"check": "price",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "migration-cap",
"observed": "$16.40",
"bound": "$14.50, half of Pro’s first month" ,
"window": "the Harbor Row move"
},
"doc": "/plays/risk-reversal-offers#stop-migration-cap" ,
"task": "task_806"
}
]Did it work
Two-week blocks with and without the guarantee were alternated at random, 4 of each (rules m–o): the agent half is the guarantee blocks, your half the blocks without. Each figure’s call is POST /{namespace}/metrics/query by node and by block; the leaf and every node above it are Not live yet (gaps #4).
+11.7 kept paid per 100 trials · ■□□□ Too early to tell · n 94 matured · path → arr
- Chose
- reverse-trial
- Why
- a new account with no card on Oct 19, inside block 8 (a guarantee block, Oct 12–25)
- From
- reverse-trial · offer-the-guarantee · answer-the-risk · move-their-data · pay-the-waiver · refund-on-press · to-the-ae
- Expects
- kept paid at day 60
- Reopens when
- no Invoice.paid for customer_66 by day 14, or a refund press
- By
- worker_5
JSON
{
"$id": "decisions/decision_811",
"$type": "Decision",
"choice": "reverse-trial",
"reason": "a new account with no card on Oct 19, inside block 8 (a guarantee block, Oct 12–25)",
"stakes": "low",
"options": [
"reverse-trial",
"offer-the-guarantee",
"answer-the-risk",
"move-their-data",
"pay-the-waiver",
"refund-on-press",
"to-the-ae"
],
"by": "worker_5",
"on": "customer_66",
"expected": "kept paid at day 60",
"reopensWhen": "no Invoice.paid for customer_66 by day 14, or a refund press"
}| Node | Agent half (guarantee blocks) | Your half (no guarantee) | Added | Confidence | Basis |
|---|---|---|---|---|---|
guarantee-lift | 31.3 kept paid per 100 trials (15 of 48) | 19.6 (9 of 46) | +11.7 [−5.7, 29.1] | ■□□□ Too early to tell | alternating two-week blocks at random · 8 blocks · n 94 at day 60 · 66 still maturing · Other Startups’ results +8.4, ■■■□ Likely, n 5,300 |
new-paying-customers | 26.3 per 100 (21 of 80) paid by day 30 | 18.8 (15 of 80) | +7.5 [−5.4, 20.4] · Not carrying up yet | ■□□□ Too early to tell | the same blocks |
new-arr ↑ | $5,205, 15 Customers kept on Pro · Booked: credited, not all caused by this Play | $3,123, 9 Customers | +$1,946 [−$955, +$4,847] · Worth about +$1,700 a month | ■□□□ Too early to tell (15 vs 9 Customers) | the same · 6 still inside their window |
net-new-arr · arr | +$5,205 | +$3,123 | +$1,946, carried: it moves no other bridge term | ■□□□ Too early to tell | carried from new-arr |
The leaf counts trials still paying at day 60 per 100 trial starts in guarantee blocks, minus the same in no-guarantee blocks, to 100 matured on each side; at 48 and 46 the Experiment runs on, and blocks keep alternating.
How it moves it: a buyer at the first charge saw one block with the bar, the window and the remedy, and the refund one press away; 3 of 22 closed windows paid the month back unasked.
Guardrails: treated against held back, under new-paying-customers: refunds in 30 days, 4 of 21 first charges against 3 of 15, and Disputes, 0 against 0.
{
"$id": "https://api.sb/leaseline.app/campaigns/risk-reversal-offers" ,
"$type": "Campaign",
"play": "play:risk-reversal-offers@1" ,
"path": [
"guarantee-lift",
"new-paying-customers",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "guarantee-lift",
"unit": "per-100",
"heldBack": 80,
"decision": null
},
"readout": {
"value": 11.7,
"n": 94,
"maturing": 66,
"interval": [
-5.7,
29.1
],
"readability": "inadmissible",
"basis": "alternating-weeks",
"pooled": false
},
"ledger": {
"spend": 87,
"workerCost": 144,
"hours": 3.4,
"pipelineArr": 2400,
"wonArr": 5205,
"projectedArr": 1746,
"paybackDays": 20
}
}Outside benchmark: this Play’s catalog record carries no sourced range yet, so Other Startups’ results stand in: +8.4 kept paid per 100 trials, ■■■□ Likely, n 5,300.
Before it · After it. Before it: product-led, instant-response and retargeting bring the trials. After it: run-beside holds the first 30 paid days, and review-requests asks Customers who met the bar; a refund press ends it at once.
Example
Leaseline ran it from 2026-06-29 to 2026-10-19 (112 days, 8 two-week blocks): 160 trial starts, 80 in guarantee blocks and 80 in blocks without; 94 have reached day 60. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Result (counts) | Kept paid (credited, not all caused by this Play) |
|---|---|---|---|
| Start the reverse trial | 160 | 41 subscribed by day 14 | counted below |
| Offer the guarantee · Pay the waiver | 38 · 3 | 22 windows closed · 3 credited back ($87) | 15 kept at day 60, of 48 matured |
| Answer the risk · Move their data free · Refund on one press · To the AE | 13 · 9 · 7 · 2 | 1 refused, rewritten · 9 moved · 7 refunded, p95 6 s · 1 Quote open | — |
| Guarantee blocks · blocks without | 80 · 80 trials | 21 paid by day 30 · 15 | 15 of 48 · 9 of 46 |
| At 10 trials a week (the Use it when volume) | about 160 in 112 days | alternating blocks at random | Other Startups’ results: +8.4 per 100, ■■■□ Likely, n 5,300 |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_9302 Campaign.created | the three steps; the dry run fails bar-cap | 20 min |
| 0 | event_9305 Offer.published | the sheet, version 1: 6 notices in 30 days, the month back | 15 min |
| 3 | event_9318 Invoice.paid | the first guaranteed upgrade paid | — |
| 14 | event_9361 Role.updated | promoted: guarantee notices send after a 2-minute hold | — |
| 47 | event_9420 CreditGrant.issued | the first waiver: 2 notices against 6, $29 back, unasked | — |
| 88 | event_9488 Campaign.paused | migration-cap on the Harbor Row move; you approved $16.40 | 6 min |
| 1–112 | event_9311 Approval.created, first of 13 | you approved 12 answers; claims-resolve refused 1, rewritten once and sent; 9 data moves; weekly reviews | 2 h 40 min · total 3.4 h measured, 3.5 h asked |
Leaseline → Marlow Estates, Sep 2 09:14 · Your guarantee: send 6 renewal notices from Leaseline in your first 30 paid days, or we credit your first month back, without you asking.¹ The full terms: leaseline.app/guarantee.² *Signed with the Role’s disclosure line.*³
Oct 2 09:00 · the verdict: 14 notices sent, bar met. Marlow is still paying at day 60.
- Don’t worry, Leaseline is completely risk-free.
+ If you send fewer than 6 renewal notices in your first 30 paid days, your first month is credited back automatically. Refunds are one press for 14 days. Fernhill Property Co, 2026-10-14 16:30 · “Can you move our 46 units from a spreadsheet?” · Leaseline, 16:31 · *Yes, free. Dana, our founder, checks the dry run with you by tomorrow 17:00.*⁴ The Brief went to you (
task_833); you approved the move at 11:20, and the 30-day undo stayed open.
¹ One block: the bar, the window, the obligation and the remedy. ² The sheet, one click away, dated. ³ The fixed signature line, compiled from the Role’s disclosure Setting. ⁴ The routed line, compiled from the Role’s Settings.
Your settings
---
holdout: blocks # two-week blocks with and without the guarantee, at random
---
Every new account gets Team free for 14 days, no card, then Free.
The bar: 6 renewal notices in the first 30 paid days, or the first month back, unasked.
Refunds are one press for 14 days; data moves are free. $ npx startup-builder show plays/risk-reversal-offers
holdout blocks · reverse trial Team 14 days · bar 6 notices in 30 days · refund 14 days your file plays/risk-reversal-offers.mdx:2,4,5,6 (Ask 2026-06-29)
worker role:success-manager, owns never · chooses 7 (4 rule, 3 read) · sequences reverse-trial-notices, guarantee-notices, refund-confirmation, migration-updates · approval every-send · checks owned-by-a-person, claims-resolve, price, exit-never-waits, bar-cap, sheet-lock, customer-side, trial-cost, evaluator-lock, obligation-void, cluster, count-check (+2 on store and listing lanes) · stops 8 · placements google-search, bing, gmail, outlook, yahoo-mail catalog play:risk-reversal-offers@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record risk-reversal-offers 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.