Skip to content

Qualified Deals: what moves them on

Qualified Deals: what moves one to a proposal, who owns it, how long it waits and what holds it.

A qualified Deal has a value, a close date and a next step. It moves on when a call is held and a Quote goes out.

It moves on when

ToWhenThe callEvent
Proposeda call with the buyer was held and a Quote is attachedPOST /{namespace}/deals/{deal}/proposeDeal.proposed
Lostthe buyer says no, with a reasonPOST /{namespace}/deals/{deal}/loseDeal.lost

Who owns it

TitleWhat it does here
AEruns the call and drafts the Quote
SEjoins when the buyer asks security or setup questions

How long it sits

Median days in itDealsStall linePast it now
9 d618 d1

The stall line is twice the median, read from each Deal’s statusSince · sample

The call that moves it

Propose to a Qualified DealMode try
You, to your agent

Send Harbor Row its proposal. If a call with the buyer comes first, book it. Send nothing.

curl "https://api.sb/leaseline.app/deals?where=status%20%3D%20%22Qualified%22&sort=statusSince" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

curl -X POST "https://api.sb/leaseline.app/deals/deal_33/propose?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"quote":"quote_5"}'

curl -X POST "https://api.sb/leaseline.app/meetings/book?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contact":"contact_22","at":"2026-10-23T16:00:00Z"}'
import { $ } from 'startup-builder'

const { deals } = await $.Deal.list({ where: 'status = "Qualified"', sort: 'statusSince' })
await $.Deal.propose({ deal: 'deal_33', quote: 'quote_5' }, { mode: 'try' })   // no call held with Harbor Row
// 422 · Harbor Row’s proposal did not send: no Meeting with the buyer has been held.
// no-meeting-held: Book a call with the buyer and hold it, then send the proposal again. · then Meeting.book
return await $.Meeting.book({ contact: 'contact_22', at: '2026-10-23T16:00:00Z' }, { mode: 'try' })   // the demo with the owner
npx startup-builder do Deal.list --json '{"where":"status = \"Qualified\"","sort":"statusSince"}'
npx startup-builder do Deal.propose --json '{"deal":"deal_33","quote":"quote_5"}' --try
npx startup-builder do Meeting.book --json '{"contact":"contact_22","at":"2026-10-23T16:00:00Z"}' --try
{
  "name": "do",
  "arguments": {
    "code": "const { deals } = await $.Deal.list({ where: 'status = \"Qualified\"', sort: 'statusSince' })\nawait $.Deal.propose({ deal: 'deal_33', quote: 'quote_5' }, { mode: 'try' })   // no call held with Harbor Row\n// 422 · Harbor Row’s proposal did not send: no Meeting with the buyer has been held.\n// no-meeting-held: Book a call with the buyer and hold it, then send the proposal again. · then Meeting.book\nreturn await $.Meeting.book({ contact: 'contact_22', at: '2026-10-23T16:00:00Z' }, { mode: 'try' })   // the demo with the owner",
    "mode": "try"
  }
}
Response200application/json
{
  "meeting": {
    "$id": "https://api.sb/leaseline.app/meetings/meeting_17",
    "$type": "Meeting",
    "at": "2026-10-23T16:00:00Z",
    "agenda": "Demo for Harbor Row’s owner: renewals and late-rent reminders"
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_21",
    "operation": "Meeting.book",
    "status": "pending",
    "reason": "awaitingApproval",
    "mode": "try"
  }
}
samplePreview

When it won’t move

422RefusedHarbor Row’s proposal did not send: no Meeting with the buyer has been held.
CheckFixThen
no-meeting-held fail · Not live yet, gaps #2Book a call with the buyer and hold it, then send the proposal again.POST /{namespace}/meetings/book
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "Harbor Row’s proposal did not send: no Meeting with the buyer has been held.",
  "checks": [
    {
      "check": "no-meeting-held",
      "status": "fail",
      "observed": "0 Meetings held, 0 booked",
      "doc": "/code/refusals#check-no-meeting-held",
      "fix": "Book a call with the buyer and hold it, then send the proposal again.",
      "then": "Meeting.book"
    }
  ]
}

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

no-meeting-held is Not live yet, gaps #2; the card renders from the sample.

Plays that unstick it

PlayWhat it does
Closer handoffHands 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 committeeWrites to 3 or more roles at each named company, one a week, and hands each engaged company to your AE within a day.
Trust packSends the trust page and prefilled security answers with every large Quote, and releases the security report only after a click-through Agreement.
Written referencesAnswers a buyer’s reference request within days with a reference an opted-in Customer writes and signs, its credit shown on it.

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.

Contents