Skip to content

Next order due

Tells a Customer the day their last order makes the next one due, with the live price and a one-click order.

Channel
More seats and upgrades
Run oneMode try
You, to your agent

Hand our latest Customer whose next audit came due 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(%22Order.delivered%22%2C%20%22Schedule.fired%22%2C%20%22Order.placed%22%2C%20%22Order.refunded%22%2C%20%22Offer.published%22%2C%20%22Message.received%22%2C%20%22Renewal.opened%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_1388"}'

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

const { events: [last] } = await $.Event.list({ where: 'name in ("Order.delivered", "Schedule.fired", "Order.placed", "Order.refunded", "Offer.published", "Message.received", "Renewal.opened")', 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 (\"Order.delivered\", \"Schedule.fired\", \"Order.placed\", \"Order.refunded\", \"Offer.published\", \"Message.received\", \"Renewal.opened\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1388"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"customer_23\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"customer_23\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Order.delivered\", \"Schedule.fired\", \"Order.placed\", \"Order.refunded\", \"Offer.published\", \"Message.received\", \"Renewal.opened\")', 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_455",
    "$type": "Decision",
    "choice": "send-due-notice",
    "reason": "Cedar Point Rentals’ Renewal audit was delivered 2025-11-18, so the next is due 2026-11-18; the map row is approved, and $450 is over the $100 print line",
    "stakes": "low",
    "options": [
      "send-due-notice",
      "offer-every-year",
      "late-note",
      "to-the-owner",
      "not-now"
    ],
  …
sample · 4 Not live yetPreview

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

action_3 is the email notice to contact_14, Cedar Point’s billing owner, held 2 minutes. action_4 is the printed notice on day 16; an Order before then cancels it.

50 per 100 against 19 before · before-after, not proof · n 6 · path → arr

Try another: the CustomerChoiceReason
Cedar Point Rentals: Renewal audit delivered 2025-11-18, next due 2026-11-18send-due-noticedue within the 30-day lead time; the row is approved
Juniper Homes: ordered the audit on time 2 years runningoffer-every-yeartwo on-time Orders: every-year terms at the same Price, for your OK
Maple Court: audit due Oct 9, no Order by Oct 12late-notethe row allows a late audit; one note at the late Price
Fairmont Lofts: invoice past due since Oct 1not-nowkeep-first: their CSM sees them first

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Next outcome acceptance → Won back ↑ → ARR added each week → ARR

Worth’s formula: about +22 Orders per 100 due (Other Startups’ results; no lift of your own yet) × 7 due a month ≈ 1.5 more Orders a month; about 1.4 sit in any 28 days × $450 × 13 ≈ +$8,200 ARR, held while it runs. Under First signal: At 7 due a month, 90 days can tell only +45 per 100 or more, so your file starts at holdout: 0 and reads before-after.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Schedule.fired · first notice 2m 40s after the lead time opened · 9 keys Not live yet

Start it this week

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

# 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":"next-outcome"}'

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

# off: no notice sends; every-year charge notices and their cancel links keep sending
curl -X PATCH https://api.sb/leaseline.app/campaigns/next-outcome \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusednext-outcome can’t start yet: 1 check fails and 2 warn.
CheckFixThen
use-when pass · Not live yet, gaps #8Nothing to do: it counts Customers whose next outcome comes due.POST /{namespace}/metrics/query
billing-connected fail · Not live yet, gaps #8Connect Stripe so every Order, refund and live Price is real.POST /{namespace}/integrations/connect
baseline warn · Not live yet, gaps #8n 16: it reads before-after, not proof, until volume allows a held-back half.POST /{namespace}/metrics/query
owned-by-a-person pass · Not live yet, gaps #8Nothing to do: their notices draft into your queue instead.POST /{namespace}/tasks/{task}/assign
keep-first pass · Not live yet, gaps #8Nothing to do: a past-due Customer gets no notice until their CSM clears them.POST /{namespace}/tasks/next
customer-ask-cap pass · Not live yet, gaps #3Nothing to do: one open ask per Customer, across every Play.GET /{namespace}/decisions
role-unstaffed warn · Not live yet, gaps #8Staff the CSM and AE, or leave them: those hand-offs come to you.POST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "next-outcome can’t start yet: 1 check fails and 2 warn.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "22 Customers with a delivered Renewal audit, 7 due a month",
      "doc": "/plays/next-outcome#check-use-when",
      "fix": "Nothing to do: it counts Customers whose next outcome comes due.",
      "then": "Metric.query"
    },
    {
      "check": "billing-connected",
      "status": "fail",
      "doc": "/plays/next-outcome#check-billing-connected",
      "fix": "Connect Stripe so every Order, refund and live Price is real.",
      "then": "Integration.connect"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "3 of 16 ordered with no notice in 90 days",
      "doc": "/plays/next-outcome#check-baseline",
      "fix": "n 16: it reads before-after, not proof, until volume allows a held-back half.",
      "then": "Metric.query"
    },
    {
      "check": "owned-by-a-person",
      "status": "pass",
      "observed": "2 of the 22 have a person owner, you",
      "doc": "/plays/next-outcome#check-owned-by-a-person",
      "fix": "Nothing to do: their notices draft into your queue instead.",
      "then": "Task.assign"
    },
    {
      "check": "keep-first",
      "status": "pass",
      "observed": "1 past due, held",
      "doc": "/plays/next-outcome#check-keep-first",
      "fix": "Nothing to do: a past-due Customer gets no notice until their CSM clears them.",
      "then": "Task.next"
    },
    {
      "check": "customer-ask-cap",
      "status": "pass",
      "observed": "0 open asks",
      "doc": "/plays/next-outcome#check-customer-ask-cap",
      "fix": "Nothing to do: one open ask per Customer, across every Play.",
      "then": "Decision.list"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "success-manager",
        "sales-lead"
      ],
      "owned": 2,
      "doc": "/plays/next-outcome#check-role-unstaffed",
      "fix": "Staff the CSM and AE, or leave them: those hand-offs come to you.",
      "then": "Role.staff"
    }
  ]
}

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

CheckFix (one call)Your timeWait
use-when · pass: 22 Customers, 7 due a month (gaps #8)POST /{namespace}/metrics/query on next-outcome-acceptance1 minnone
billing-connected · failPOST /{namespace}/integrations/connect with system recurring-billing (Stripe)5 minthe first Order sync, about 10 min
baseline · warn: 3 of 16 in 90 daysPOST /{namespace}/metrics/query; it fills Before in Your number0 minnone
owned-by-a-person · keep-first · customer-ask-cap · pass: 2 owned by you; 1 past due held; 0 open asks (gaps #3, #8)nothing; each runs again on every notice0 minnone
role-unstaffed · warn: 2 of your 22 have a person owner, youPOST /{namespace}/roles/{role}/staff, or leave it: CSM and AE hand-offs come to you, and your 2 get drafts in your queue0 minnone

Your number · Before 19 per 100 · Now 50 per 100 · Target 45 by Dec 31 · before-after, not proof · n 6 matured · Other Startups +22, ■■■□ Likely

Each email notice costs $0.04 from your Domain (Worker cost), and each printed notice about $1.10, under a $100-a-month print Limit. The outcome map and the one-click Order Page cost nothing. That comes to about $7 a month at 7 due with print, and $1 without.

When it starts

WhenTrigger idStarts onWindowHow it gets in
A next audit comes within 30 days of its due datenext-outcome-dueat on Schedule.fired where dueAt - 30d30d, to the due datethe outcome map schedules it from the delivered Order; POST /{namespace}/orders/{order}/deliver writes the date
You deliver a Renewal auditservice-order-deliveredevent on Order.delivered where offer.kind = 'service'1dPOST /{namespace}/orders/{order}/deliver, or POST /{namespace}/integrations/connect (Stripe)
A due date passed 3 days ago with no Order, and the row allows a late auditnext-outcome-overduestate on Schedule.fired where status = 'overdue' and lateAllowed = true14da state on the outcome; no call
+ 5 more: an Order placed or refunded, a changed map row, a done-elsewhere reply, and a yearly charge coming due (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1388",
  "$type": "Event",
  "name": "Schedule.fired",
  "at": "2026-10-19T07:00:04Z",
  "seq": 1388,
  "data": {
    "customer": "customer_23",
    "outcome": "renewal-audit",
    "from": "orders/order_61",
    "delivered": "2025-11-18",
    "dueAt": "2026-11-18",
    "price": 450,
    "currency": "usd"
  }
}
Reproduce it in test
npx startup-builder trigger Schedule.fired --like event_1388   # replays the delivery in test
npx startup-builder clock advance --by 16d   # runs the printed notice (action_4) unless an Order lands first
npx startup-builder listen Order.placed --forward-to http://localhost:3000/hook

Who runs it

CSM · your agent (role:success-manager, worker_5) holds the Key Result. It hands to each Customer’s owner: AE · Priya Shah (person) (worker_3, staffed on day 9) when they ask to change the scope or the price, and you (Dana Okafor, person, worker_1) for every-year terms and for the Customers you own, because the CSM Role has no person. Your number links to Did it work.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Send the due noticeIt does it, you can stop it9 of 9 approved uneditedmet on day 15 (the first 5 notices, then 4 more)a sent date or Price differs (wrong-date, misquote) → You approve each onePOST /{namespace}/actions/{action}/cancel inside the 2-minute hold
Send the late note · Not nowIt does it, you can stop it2 of 2 · 4 of 4the samethe samethe same
Offer every-year termsYou approve each one2 of 2never: a yearly charge is yours to offer—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
To the ownerIt does it1 of 1—a held Customer is asked anyway → You approve each onePOST /{namespace}/actions/{action}/redirect
Change the outcome mapYou approve each one1 merged of 1never—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: a date the map didn’t compute, a consequence past the approved line, a discountRefused, every time1 drafted, 1 refusednever—none: the Check holds it

What it reads · What it may call. It reads the delivered Order, the outcome map’s row and the live Price, and never a Visit or a click. POST /{namespace}/orders/place is the Customer’s own press on the one-click Page, never the agent’s call. Its tools are POST /{namespace}/messages/{message}/schedule, POST /{namespace}/approvals, POST /{namespace}/conversations/{conversation}/escalate, POST /{namespace}/tasks/{task}/assign, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:next-outcome@1 · each line names its record key
You hold the CSM Key Result: 45 next audits ordered per 100 due by 2026-12-31.   ← worker, metric
On each outcome that comes due, choose one option and say why; a held Customer gets Not now. ← triggers, chooses, keep-first
The due date is the one the outcome map computes from their own delivered Order. ← copyRules 1
Every Price is the live Price; no consequence past the approved line.            ← copyRules 2–3
Say it is an offer from Leaseline; never say the audit has started.              ← copyRules 5–6
Every notice carries a done-elsewhere link and an unsubscribe link.              ← copyRules 7

The slow loop, as a Change. decision_377 (2026-09-21, weekly) read 4 notices sent 30 days out with 1 Order by the due date, and 3 Orders in the week after it. change_29 added a reminder on the due date itself (your file, line 5), and Dana merged it with POST /{namespace}/changes/{change}/merge. Replayed on past notices, POST /{namespace}/changes/{change}/review put the row at 58 per 100; it has no read-back yet: 2 notices have reached their window since.

Bring your own agent (folded) starts at It does it, you can stop it when it matches or beats the seated agent on the eval suite, and at You approve each one when it does not; POST /{namespace}/roles/{role}/staff seats it.

Terminal
npx startup-builder eval --scenario next-outcome-31 --agent "claude -p" --seat success-manager   # seated: 0 wrong dates, 0 Checks failed sent, $0.04 a notice · yours: 1 wrong date → You approve each one

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Send the due notice send-due-noticedue within 30 days, row approvedYour rule (line 4)next-outcome-due-notice: email on day 0, print on day 16 at $100 or more, reminders → POST /{namespace}/messages/{message}/schedulethe Customer’s press on the one-click Orderthe same
Offer every-year terms offer-every-yearthey ordered the same audit on time beforeAgent’s call, with its reasonnext-outcome-due-notice with every-year terms at the same Price → POST /{namespace}/approvals; on yes, next-outcome-yearly-notice before each chargeyou approve the terms · Take this oneyou
Send the late note late-notedue 3 days ago, no Order, the row allows lateAgent’s call, with its reasonnext-outcome-overdue-note, one note at the late Pricenobodythe same
To the owner to-the-ownera person owns them, or they ask to change the scope or the priceAgent’s call, with its reasonPOST /{namespace}/conversations/{conversation}/escalate → POST /{namespace}/tasks/{task}/assignAE · Priya Shah, due 1 business day · Take this oneyou
Not now not-nowalready ordered or done elsewhere, another Play holds them, or keep-first appliesYour rule (rule j)nothing; names the holdertheir CSM, so you · Take this oneyou
When they write backFixture replyWhat happensWho answersBy whenCall
Interested“Yes, book the November audit.”the notice’s one-click Order Page; nothing is charged until they pressthe Customer—POST /{namespace}/orders/place (theirs)
Send me pricing“Is it still $450?”the live Price and what the audit covers, from the OfferCSM · your agent5 minPOST /{namespace}/conversations/{conversation}/answer
Not now“We did it in-house this year.”the done-elsewhere answer: the outcome closes, and customer-ask-cap frees the Customernobodyat onceGET /{namespace}/decisions
Wrong person“Our controller, Lee, books these.”asks them to forward it; it never writes to an address from their textCSM · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply until Oct 28the reminder waits for the return date, inside the lead timenobodythe return datePOST /{namespace}/messages/{message}/schedule
Question it can’t answer“Can you add our 2 new owners to the same audit?”To the owner: scope and price are never the agent’s callAE · Priya Shah (person)1 business dayPOST /{namespace}/conversations/{conversation}/escalate
Stop“Stop sending these.”notices stop on every lane; a yearly charge notice and its cancel link still sendnobodyat oncePOST /{namespace}/contacts/{contact}/unsubscribe

When it hands to you

On this Play, hand-offs go to the Customer’s owner, the CSM’s seat: you for every-year terms and the Customers you own, and AE · Priya Shah (person) for a change of scope or price. 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_471",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-09T16:20:00Z",
    "on": "customer_7",
    "brief": {
      "who": "Birchway Properties",
      "said": "Can you add our 2 new owners to the same audit?",
      "chose": "to-the-owner",
      "why": "a change of scope is a Quote, the AE’s",
      "due": "next audit 2026-11-02",
      "never": [
        "a discount",
        "a date the map didn’t compute"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/approvals/approval_64",
    "$type": "Approval",
    "verdict": "approved",
    "deadline": "2026-09-30T17:00:00Z",
    "draft": "Your next Renewal audit is due Oct 29. You’ve booked it on time twice; you can have it booked every year at $450…",
    "route": "offer-every-year",
    "checks": [
      {
        "check": "fact-check",
        "status": "pass"
      },
      {
        "check": "keep-first",
        "status": "pass"
      }
    ]
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_458",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-02T17:00:00Z",
    "on": "customer_31",
    "brief": {
      "who": "Fairmont Lofts",
      "chose": "not-now",
      "why": "invoice past due since Oct 1",
      "held": "keep-first",
      "next": "their audit notice sends once you clear the invoice"
    }
  }
]

The owner answers with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, POST /{namespace}/actions/{action}/redirect, 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 plain notice sends instead. Once a person claims, the agent’s pending notices to that Customer cancel with 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: 4 of 4 claimed within their due time, median 3 h 10 min, n 4, ■□□□ Too early to tell beside Other Startups’ 93 % on time. Your queue: in week 1, 5 approvals and 1 hand-off; after the promotion, about 1 approval (every-year terms) and 1 hand-off a fortnight.

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, gaps #8)a notice to a Customer whose open Deal a person owns, or whose Conversation a person claimedLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
keep-first (rule j, gaps #8)a notice to a Customer who is at risk, past due or has an unsubscribe pendingLet their CSM reach them first, then ask again once they are healthy.POST /{namespace}/tasks/next
customer-ask-cap (gaps #3)a second open ask to one Customer in a window, from any Playusage-upsell holds them until Nov 3.GET /{namespace}/decisions
capacity (the record’s Capacity gate)a notice for an audit the delivery queue cannot finish before its due dateAdd delivery capacity, or move the row’s lead time earlier.PATCH /{namespace}/offers/{id}
fact-check (Not live yet)a notice line no record backs, such as a consequence past the approved lineCut the claim, or name the record that backs it.POST /{namespace}/content/draft
Stop (pauses the Play)Pauses whenThen
wrong-datea sent due date differs from the date the map computes from the delivered Orderthe row pauses and drops to You approve each one
misquotea sent Price or total differs from the live Pricethe Play pauses; You approve each one
already-handleda notice sends for an outcome already ordered or answered done elsewherethe row pauses; POST /{namespace}/tasks for you
refundrefunds or disputes over 5 % of a row’s Orders in 30 days, after 20the row pauses
acceptance-floorunder 3 Orders per 100 notices on a row, after 100the row stops until the next readout
holdout-integritya notice reaches a held-back Customer; over 5 % voids the cohort’s readoutPOST /{namespace}/tasks/{task}/assign
kill-switchyou press itevery notice stops; every-year charge notices and cancel links keep sending
unsubscribeunsubscribes over 1 % of a week’s notices on a rowthat row’s notices pause
complaintcomplaints near 0.1 % of noticesnotices pause on every Mailbox
spend-limit (the record’s Print Limit)print spend reaches its $100 monthly Limitprinted notices hold; POST /{namespace}/limits/{limit}/raise or wait for the month; email still sends

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

422RefusedThe late note to Maple Court did not send: it states a consequence the outcome map does not approve.
CheckFixThen
fact-check fail · Not live yet, gaps #1Cut the claim, or name the record that backs it.POST /{namespace}/content/draft
keep-first pass · Not live yet, gaps #8—POST /{namespace}/tasks/next
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The late note to Maple Court did not send: it states a consequence the outcome map does not approve.",
  "checks": [
    {
      "check": "fact-check",
      "status": "fail",
      "doc": "/plays/next-outcome#check-fact-check",
      "fix": "Cut the claim, or name the record that backs it.",
      "then": "Content.draft"
    },
    {
      "check": "keep-first",
      "status": "pass"
    }
  ]
}

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

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "spend-limit",
      "observed": "$100.40",
      "bound": "$100",
      "window": "October"
    },
    "doc": "/plays/next-outcome#stop-spend-limit",
    "task": "task_466"
  }
]

Did it work

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

50 per 100 against 19 before · before-after, not proof · n 6 · path → arr

Chose
send-due-notice
Why
Cedar Point Rentals’ Renewal audit was delivered 2025-11-18, so the next is due 2026-11-18; the map row is approved, and $450 is over the $100 print line
From
send-due-notice · offer-every-year · late-note · to-the-owner · not-now
Expects
Order.placed for the next Renewal audit by 2026-12-18
Reopens when
no Order.placed for customer_23’s next audit by 2026-11-21, and the row allows a late audit
By
worker_5
JSON
{
  "$id": "decisions/decision_455",
  "$type": "Decision",
  "choice": "send-due-notice",
  "reason": "Cedar Point Rentals’ Renewal audit was delivered 2025-11-18, so the next is due 2026-11-18; the map row is approved, and $450 is over the $100 print line",
  "stakes": "low",
  "options": [
    "send-due-notice",
    "offer-every-year",
    "late-note",
    "to-the-owner",
    "not-now"
  ],
  "by": "worker_5",
  "on": "customer_23",
  "expected": "Order.placed for the next Renewal audit by 2026-12-18",
  "reopensWhen": "no Order.placed for customer_23’s next audit by 2026-11-21, and the row allows a late audit"
}
NodeNow (56 days)Before (the 90 days, no notice)AddedConfidenceBasis
next-outcome-acceptance50 per 100: 3 of 6 matured ordered by the due date + 30 days · 8 still maturing · Booked $2,250 in 5 Orders: credited, not all caused by this Play19 per 100: 3 of 16— · Worth about +$8,200 ARR held—before-after, not proof · Other Startups’ results +22 per 100, ■■■□ Likely, n 4,100
reactivated-arr ↑$17,550 at Oct 19: 3 Orders in the last 28 days × $450 × 13$5,850: 1 Order in its last 28 days——before-after; each $5,850 rolls off 28 days after its Order (one-time-rolloff-arr)
net-new-arr · arrcarried from reactivated-arrcarried——carried

Before against after reads the outcomes that came due in this window against the 16 that came due in the 90 days before it with no notice; it is not proof, and Other Startups’ results print beside it.

How it moves it: each notice reached the Customer 30 days before the due date their own Order set, where before the date passed with nothing sent (next-outcome-acceptance by days to due).

Guardrails: before against after: contraction-arr, $0 from audit Customers who also pay for Pro against $0 before, and refunds, 0 of 5 Orders against a 5 % Stop.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/next-outcome",
  "$type": "Campaign",
  "play": "play:next-outcome@1",
  "path": [
    "next-outcome-acceptance",
    "reactivated-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "next-outcome-acceptance",
    "unit": "per-100",
    "heldBack": 0,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 6,
    "maturing": 8,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 6,
    "workerCost": 1,
    "hours": 1.1,
    "pipelineArr": 900,
    "wonArr": 17550,
    "projectedArr": 8200,
    "paybackDays": 1
  }
}

Outside benchmark: the catalog holds none for this Play yet, so Other Startups’ results stand in: +22 Orders per 100 due, ■■■□ Likely, n 4,100.

Before it · After it. Before it: Renewal audits reach it through Order.delivered, most of them sold by instant-response and paid-pilot. After it: annual-prepay hears the Customers who took every-year terms, and customer-referrals hears the Customers who ordered twice; keep-first holds both while a Customer is at risk. An offer from your other Startups goes through cross-sell, never this notice.

Example

Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 14 Decisions on 13 Customers whose next audit came due, 6 of them past their due date + 30 days. Read every captured thread at ?threads=all; three follow the tables.

What happened, by optionDecisionsOrderedBooked (credited, not all caused by this Play)
Send the due notice73, 2 still maturing$1,350 in 3 Orders
Offer every-year terms22 on every-year terms$900 in 2 Orders
Send the late note · To the owner · Not now2 · 1 · 20 · 1 Quote open · 0$900 Quote open
At 3 due a month (the Use it when volume)about 6 in 56 daysbefore-after, not proofOther Startups’ results: +22 per 100, ■■■□ Likely, n 4,100
DayEventWhat happenedYour time
0event_119 Campaign.createdthe three steps; the dry run fails billing-connected14 min
0event_120 Integration.connectedStripe connected; the first Order sync took 8 min5 min
3event_177 Order.placedthe first next audit ordered: Juniper Homes, in one click—
15event_388 Role.updatedpromoted: due notices send after a 2-minute hold—
28event_532 Change.mergeda reminder on the due date itself: replayed at 58 per 1005 min
39event_640 Campaign.pausedspend-limit: print spend reached $100 on Oct 2; printed notices held to Nov 12 min
1–56event_142 Approval.created, first of 9you approved 9 notices and 2 every-year terms; weekly reviews, from the POST /{namespace}/tasks/next log24 min · total 1.1 h measured, 1 h asked

Leaseline → Juniper Homes’ billing owner, Aug 27, 07:02 · Your Renewal audit was delivered on Sep 25 last year, so the next is due Sep 25.¹ It is $450, as on our pricing Page.² Book it in one click, or tell us it’s done elsewhere.³ This is an offer from Leaseline. *Signed with the Role’s disclosure line.*⁴

Juniper, Aug 27, 09:15 · pressed Book it. Order.placed, $450; the audit was delivered Sep 22.

Maple Court, 2026-10-12 · the late note fact-check refused, then the rewrite that sent
- Your audit is overdue, and late renewal notices could cost you tenants this winter.
+ Your audit was due Oct 9. It can still be done this month at $450; book it in one click, or tell us it’s done elsewhere.

Birchway Properties, 2026-10-08 16:20 · “Can you add our 2 new owners to the same audit?” · Leaseline, 16:22 · *Thanks. Priya, your account lead, replies by tomorrow 16:20 with a Quote.*⁵ The Brief went to Priya (task_471); she claimed it at 17:05 and sent the Quote the next morning at 10:40.

¹ The date the outcome map computes from their own delivered Order. ² The live Price. ³ The one-click Order and the done-elsewhere link. ⁴ The fixed signature line, compiled from the Role’s disclosure Setting. ⁵ The routed line, compiled from the Role’s Settings.

Your settings

plays/next-outcome.mdx
---
holdout: 0        # 7 due a month is too few to hold some back; it reads before-after
---
Tell them 30 days before their next Renewal audit is due; mail a printed notice too.
Remind them on the due date itself.
If they ask to change the scope or the price, bring in our AE.
Text
$ npx startup-builder show plays/next-outcome
holdout 0 · lead time 30 days · due-date reminder · AE for scope and price     your file  plays/next-outcome.mdx:2,4,5,6 (Ask 2026-08-24; line 5 by change_29, 2026-09-21)
family keep · worker role:success-manager, owns never · chooses 5 (2 rule, 3 read) · sequences next-outcome-due-notice, next-outcome-overdue-note, next-outcome-yearly-notice · checks owned-by-a-person, keep-first, customer-ask-cap, capacity, fact-check · stops 10 · placements gmail, outlook + postal-mail under a $100 print Limit    catalog  play:next-outcome@1 (Not live yet, gaps #5)

Every key from the catalog

KeyIdWhat it is
Tacticoutcome-map-keepOutcome map keep: Keeps the founder-approved map from each Service Offer to the outcomes it leads to, with each due rule, lead time and consequence line. Starts at Sends nothing.
Tacticnext-outcome-planNext outcome plan: Turns each delivered Service Order into dated next outcomes on the Customer’s own account, skips any already handled, and assigns the holdout. Starts at Sends nothing.
Tacticnext-outcome-noticeNext outcome notice: Sends one due notice from the Startup’s Mailbox at the lead time: the date, the live Price, a one-click Order and a done-elsewhere link. Starts at You approve each one.
Tacticnext-outcome-orderNext outcome order: Turns a press on the notice into a prefilled Stripe Checkout Order, offers every-year terms at the same Price, and hands it to delivery. Starts at Sends nothing.
Tacticnext-outcome-readoutNext outcome readout: Reads acceptance per outcome against its holdout every 90 days, runs the decay check every 30 days, and flags weak outcomes for the founder. Starts at Sends nothing.
Tacticreply-matrixReply matrix: Labels every outreach reply with one of 11 labels, maps it to one of seven reply kinds, and runs that kind’s move by its deadline. Starts at You approve each one.
Tacticsending-stop-lossSending stop loss: Reads the Play’s own bounces, replies and seed tests on every send, and rests, pauses or retires a Mailbox, Domain, cell or the Play. Starts at Sends nothing.
Triggerservice-order-deliveredService order delivered: event on Order.delivered, window 1d.
Triggernext-outcome-dueNext outcome due: at on Schedule.fired, window 30d.
Triggernext-outcome-overdueNext outcome overdue: state on Schedule.fired, window 14d.
Triggernext-outcome-orderedNext outcome ordered: event on Order.placed, window 1d.
Triggerdelivered-order-reversedDelivered order reversed: event on Order.refunded, window 1d.
Triggeroutcome-map-changedOutcome map changed: event on Offer.published, window 7d.
Triggerdone-elsewhere-replyDone elsewhere reply: event on Message.received, window 3d.
Triggeryearly-charge-dueYearly charge due: at on Renewal.opened, window 30d.
Sequencenext-outcome-due-noticeNext outcome due notice: 4 steps; it ends on An Order for the outcome, here or at a sibling Startup; A done-elsewhere answer; An unsubscribe or a Suppression; A refund or dispute on the delivered Order; The due date passing.
Sequencenext-outcome-overdue-noteNext outcome overdue note: 1 steps; it ends on An Order for the outcome; A done-elsewhere answer; An unsubscribe or a Suppression; 14 days passing.
Sequencenext-outcome-yearly-noticeNext outcome yearly notice: 2 steps; it ends on A cancel; The charge.

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