Open Deals: next step, close month, stall line
Open Deals by Deal status: each count, ARR, median days and the call that moves it, with lost reasons ranked.
Every open Deal, by Deal status, with its next step, the month the buyer decides and the line where it stalls.
The record
| Deal status | Deals | ARR | Conversion to Won | Median days | The call that moves it |
|---|---|---|---|---|---|
| Open | 8 | $2, | win rate by Deal status, Not live yet, gaps #2 | 6 d, | POST /{namespace}/deals/{deal}/advance |
| Qualified | 6 | $4, | win rate by Deal status, Not live yet, gaps #2 | 9 d, | POST /{namespace}/deals/{deal}/propose |
| Proposed | 3 | $1, | win rate by Deal status, Not live yet, gaps #2 | 11 d, | POST /{namespace}/deals/{deal}/win |
| Won | 9 in 90 days | $5, | none: a final Deal status | sales cycle, Not live yet, gaps #2 | POST /{namespace}/customers/{customer}/activate |
| Lost | 14 in 90 days | $10, | none: a final Deal status | sales cycle, Not live yet, gaps #2 | POST /{namespace}/deals |
Count, ARR and median days from statusSince · from GET /{namespace}/deals in the window below · sample
Expected from open Deals: +$1, from 17 open Deals worth $7, if all were won · Not live yet, gaps #2 · sample. It is each open Deal’s ARR times its Deal status’s 90-day win rate, and it feeds the cash projection.
| Deal | Deal status | ARR if won | Buyer decides | Next step | The call that moves it |
|---|---|---|---|---|---|
deal_28 | Proposed | +$347 ARR | 2026-10-24 | Pinecrest Lofts: signing call on Oct 22 | POST /{namespace}/deals/{deal}/win |
deal_33 | Qualified | +$347 ARR | 2026-10-29 | Harbor Row: demo with the owner on Oct 23 | POST /{namespace}/deals/{deal}/propose |
deal_31 | Qualified | +$2, | 2026-10-30 | Northgate Rentals: the two-year Quote once the discount is approved | POST /{namespace}/deals/{deal}/propose |
deal_35 | Open | +$347 ARR | 2026-10-31 | Elm Court: security answers by Oct 27 | POST /{namespace}/deals/{deal}/advance |
| Lost reason, ranked | Deals | ARR lost | The Play that answers it |
|---|---|---|---|
price | 5 | −$5, | Risk-reversal offers |
no-decision | 3 | −$3, | Buying committee |
missing-capability | 2 | −$694 ARR | Lead reactivation |
timing | 2 | −$694 ARR | Lead nurture |
competitor | 1 | −$347 ARR | Switch kit |
no-fit | 1 | −$347 ARR | Positioning tournament |
Run it
Show me every Deal by status, then move today’s three on: qualify Birchway Properties, send Pinecrest Lofts its proposal and mark Maple Street Homes won. Send nothing.
curl "https://api.sb/leaseline.app/deals?facets=status&total=true" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
curl -X POST "https://api.sb/leaseline.app/deals/deal_36/advance?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
curl -X PATCH "https://api.sb/leaseline.app/deals/deal_36?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"closesOn":"2026-11-14","nextStep":"Demo with the 4 owners on Oct 22"}'
curl -X POST "https://api.sb/leaseline.app/deals/deal_28/propose?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"quote":"quote_4"}'
curl -X POST "https://api.sb/leaseline.app/deals/deal_27/win?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { facets } = await $.Deal.list({ facets: 'status', total: true }) // count, ARR and median days in status, from statusSince
await $.Deal.advance({ deal: 'deal_36' }, { mode: 'try' }) // Birchway Properties, Open to Qualified
// 422 · Birchway Properties did not move to Qualified: closesOn and nextStep are empty.
// stage-fields: Fill each field the refusal names, then move the Deal on again. · then Deal.update
await $.Deal.update({ id: 'deal_36', closesOn: '2026-11-14', nextStep: 'Demo with the 4 owners on Oct 22' }, { mode: 'try' }) // the two fields the refusal named
await $.Deal.propose({ deal: 'deal_28', quote: 'quote_4' }, { mode: 'try' }) // Pinecrest Lofts, call held Oct 15
return await $.Deal.win({ deal: 'deal_27' }, { mode: 'try' }) // Maple Street Homes signed the $29 plan
npx startup-builder do Deal.list --json '{"facets":"status","total":true}'
npx startup-builder do Deal.advance --json '{"deal":"deal_36"}' --try
npx startup-builder do Deal.update --json '{"id":"deal_36","closesOn":"2026-11-14","nextStep":"Demo with the 4 owners on Oct 22"}' --try
npx startup-builder do Deal.propose --json '{"deal":"deal_28","quote":"quote_4"}' --try
npx startup-builder do Deal.win --json '{"deal":"deal_27"}' --try{
"name": "do",
"arguments": {
"code": "const { facets } = await $.Deal.list({ facets: 'status', total: true }) // count, ARR and median days in status, from statusSince\nawait $.Deal.advance({ deal: 'deal_36' }, { mode: 'try' }) // Birchway Properties, Open to Qualified\n// 422 · Birchway Properties did not move to Qualified: closesOn and nextStep are empty.\n// stage-fields: Fill each field the refusal names, then move the Deal on again. · then Deal.update\nawait $.Deal.update({ id: 'deal_36', closesOn: '2026-11-14', nextStep: 'Demo with the 4 owners on Oct 22' }, { mode: 'try' }) // the two fields the refusal named\nawait $.Deal.propose({ deal: 'deal_28', quote: 'quote_4' }, { mode: 'try' }) // Pinecrest Lofts, call held Oct 15\nreturn await $.Deal.win({ deal: 'deal_27' }, { mode: 'try' }) // Maple Street Homes signed the $29 plan",
"mode": "try"
}
}application/json{
"deal": {
"$id": "https: //api.sb/ leaseline.app/ deals/ deal_27",
"$type": "Deal",
"status": "Won",
"value": {
"amount": 348,
"currency": "USD"
},
"closesOn": "2026-10-19",
"statusSince": "2026-10-19T10: 12: 00Z",
"owner": "worker_3"
},
"action": {
…
samplePreviewRefuses when
| Check | Fix | Then |
|---|---|---|
stage-fields fail | Fill each field the refusal names, then move the Deal on again. | PATCH /{namespace}/deals/{id} |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "Birchway Properties did not move to Qualified: closesOn and nextStep are empty.",
"checks": [
{
"check": "stage-fields",
"status": "fail",
"observed": "closesOn, nextStep",
"doc": "/code/refusals#check-stage-fields",
"fix": "Fill each field the refusal names, then move the Deal on again.",
"then": "Deal.update"
}
]
}It says no, says why, and names the fix.
| Code | On | Refuses | Then |
|---|---|---|---|
stage-fields | POST /{namespace}/deals/{deal}/advance | a field the next Deal status needs is empty | PATCH /{namespace}/deals/{id} |
no-meeting-held · Not live yet, gaps #2 | POST /{namespace}/deals/{deal}/propose | a proposal before any call with the buyer was held | POST /{namespace}/meetings/book |
stalled-deal · Stop · Not live yet, gaps #2 | every send to the Deal | twice its Deal status’s median days with no dated next step | PATCH /{namespace}/deals/{id} |
Plays that use it
| Play | What it does |
|---|---|
| Closer handoff | Hands a large Deal that stalled twice to a commissioned closer, paid only on collected revenue, and tests it against the Deals your agent keeps. |
| Buying committee | Writes to 3 or more roles at each named company, one a week, and hands each engaged company to your AE within a day. |
| Instant response | Answers every form and email within 5 minutes from your own pages, books the call, starts the trial or hands it to the right person. |
| Lead reactivation | Writes once to each old Lead nobody works, only when something new answers what they asked, from their last contact at the Startup. |
| Switch kit | Wins your rival’s users with an importer tested on its exports and a dry run they see first, stating no rival fact without a source. |
Compiled, not written: edit its page, 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.