Skip to content

State Machine Card

A printable summary of the pipeline state machine. Tape it above your monitor.

State Plain meaning Typical duration
NEW Inquiry arrived. No outreach yet. Minutes to hours (5-min SLA target).
CONTACTING First outreach made. Awaiting response. Days.
QUALIFIED Motivated and shopping. Covers searching + touring. Weeks to months.
COMMITTED Buyer’s agreement signed. Working with you, not just browsing. Days to weeks before an offer lands.
IN_CONTRACT Offer accepted; in escrow. 30–45 days (market-dependent).
CLOSED Funded. Keys exchanged. Terminal-ish (anniversary touches handled separately).
ARCHIVED Set aside after no engagement. Not terminal — re-engageable. Indefinite.
TRASHED Bad contact data. Not terminal — fix the data and it re-enters NEW. Indefinite.

The diagram shows the buyer events. Seller leads move through the same eight columns; only the three paperwork events between QUALIFIED, COMMITTED and IN_CONTRACT are different, and those are listed under Seller pipeline below.

stateDiagram-v2
    direction LR
    [*] --> NEW: contact_form_submission

    NEW --> CONTACTING: contact_attempted
    NEW --> TRASHED: bogus_contact_detected

    CONTACTING --> QUALIFIED: motivation_confirmed
    CONTACTING --> ARCHIVED: timeout_21d_no_response
    CONTACTING --> TRASHED: bogus_contact_detected

    QUALIFIED --> COMMITTED: buyer_agreement_signed
    QUALIFIED --> ARCHIVED: timeout_180d_no_progress

    COMMITTED --> IN_CONTRACT: contract_executed
    COMMITTED --> QUALIFIED: deal_collapsed

    IN_CONTRACT --> CLOSED: closing_complete
    IN_CONTRACT --> QUALIFIED: contract_voided

    ARCHIVED --> CONTACTING: lead_re_engaged
    TRASHED --> NEW: contact_info_updated
From → To Trigger What it means in practice
NEW → CONTACTING First logged outreach (call / email / text) The SLA clock stops here.
NEW → TRASHED Bogus contact detected Junk number, fake email, duplicate.
CONTACTING → CONTACTING Lead responded Stays put. Records that the conversation is two-way.
CONTACTING → QUALIFIED Motivation confirmed They told you they’re serious. Pre-approval for buyers; listing intent for sellers.
CONTACTING → ARCHIVED No response (design target: 21 days with ≥6 attempts) Today this is the Archive: no response button; nothing archives automatically.
QUALIFIED → COMMITTED Buyer’s agreement signed Put the signed document reference in the note.
QUALIFIED → ARCHIVED No progress (design target: 180 days) Today this is the Archive: no progress button.
COMMITTED → IN_CONTRACT Contract executed Offer accepted, escrow opened.
IN_CONTRACT → CLOSED Closing complete Deal funded.

Reverse transitions (require a reason code)

Section titled “Reverse transitions (require a reason code)”

A reverse move is a real event with analytical value — not a failure to track. The state machine enforces a reason code at the moment of transition.

From → To Event Reason options
COMMITTED → QUALIFIED deal_collapsed Financing fell through, Inspection issue, Buyer changed their mind, Seller withdrew, Lost to a competing offer, Agreement expired, Other.
IN_CONTRACT → QUALIFIED contract_voided Financing fell through, Inspection issue, Appraisal gap, Title issue, Mutual release, Buyer withdrew, Seller withdrew, Other.
NEW → TRASHED bogus_contact_detected Phone number is invalid, Email bounces, Number reaches the wrong person, Spam or bot submission, Duplicate of another lead, Other.
CONTACTING → TRASHED bogus_contact_detected Same list. Often: number reaches the wrong person.

The reason is picked from a dropdown in the action dialog and stored as a code (financing_fell_through, wrong_person, and so on). Put the specifics in the note.

Re-entry transitions (the “not terminal” cases)

Section titled “Re-entry transitions (the “not terminal” cases)”
From → To Trigger Notes
ARCHIVED → CONTACTING lead_re_engaged The Re-engage button. The lead drops back into your active workflow. If the original agent can no longer receive leads, routing picks a new one and Scribe writes an Agent reassigned row.
TRASHED → NEW contact_info_updated The Contact info fixed button, once a valid email or phone replaces the bad one. The lead re-enters the standard intake flow from the top with a fresh response clock.

ARCHIVED and TRASHED are intentionally re-enterable. A lead in either column is recoverable; neither is a delete.

Every trigger in the tables above is a button in the Lifecycle card on the lead’s detail page, under Next step. Forward moves are full-width buttons that show where they lead (“Log contact attempt → Contacting”); setbacks and exits sit in a smaller row underneath. The board offers the same actions through each card’s ⋯ menu and by dragging a card onto a column the state machine allows. Every route opens the same dialog, and nothing moves until you submit it.

Stage Forward buttons Setbacks and exits
NEW Log contact attempt → Contacting Mark as bogus → Trashed (reason)
CONTACTING Lead responded (stays), Confirm motivation → Qualified Archive: no response → Archived, Mark as bogus → Trashed (reason)
QUALIFIED Buyer agreement signed → Committed Archive: no progress → Archived
COMMITTED Contract executed → In Contract Deal collapsed → Qualified (reason)
IN_CONTRACT Closing complete → Closed Contract voided → Qualified (reason)
CLOSED none (“Closed. Nothing further to record here.”) none
ARCHIVED Re-engage → Contacting none
TRASHED Contact info fixed → New none

“(reason)” means the dialog has a required Reason dropdown. Log contact attempt and Lead responded ask for a channel (Call, Email, Text, In person, Other). Every dialog has an optional note and a This happened earlier… toggle for backdating.

The two Archive buttons fire the same timeout events the platform fires on its own (timeout_no_response and timeout_no_progress in the API). Scribe archives a CONTACTING lead after 21 days with no activity of any kind, and a QUALIFIED lead after 180 days, unless the brokerage has set different windows under Lead Routing. A row Scribe wrote says so and carries the idle count; a row an agent wrote carries their name.

The state machine still rejects anything not in this table. The UI never offers an illegal move, and if two people act on the same lead at once, the second one gets an error explaining the move is not valid from the lead’s current stage.

Every lead carries a pipeline type, buyer or seller. It is set from the inquiry subject when the lead arrives (Selling and Property Valuation are seller-side, everything else is buyer-side), and staff can change it from the Add lead dialog or by editing the lead while it is still NEW or CONTACTING. After that the timeline holds one side’s paperwork and the type is locked.

Seller cards sit in the same columns as buyer cards and show a small Seller tag. NEW, CONTACTING, IN_CONTRACT, CLOSED, ARCHIVED and TRASHED offer exactly the same buttons on both sides. The difference is QUALIFIED and COMMITTED:

Stage Forward buttons (seller) Setbacks and exits (seller)
QUALIFIED Listing agreement signed → Committed Archive: no progress → Archived
COMMITTED Listing is live (stays), Offer accepted → In Contract Listing withdrawn → Qualified (reason)
IN_CONTRACT Closing complete → Closed Contract voided → Qualified (reason)

Listing is live records the listing going active on the MLS. It is a timeline row, not a column move; the lead stays in COMMITTED until an offer is accepted or the listing is withdrawn.

Event Fires from Reason options
listing_agreement_signed QUALIFIED → COMMITTED none
listing_activated COMMITTED → COMMITTED none
offer_accepted COMMITTED → IN_CONTRACT none
listing_withdrawn COMMITTED → QUALIFIED Seller changed their mind, Price disagreement, Listing expired, Moved to another brokerage, Other.

A seller lead is refused any buyer-only event (buyer_agreement_signed, contract_executed, deal_collapsed) with a 400, and a buyer lead is refused the seller events the same way. The board and the Lifecycle card only ever offer the right set, so you will only see this from the API.

On the legacy fields, a seller lead projects to the per-seller status instead of the per-buyer one: QUALIFIED is preparing, COMMITTED is listed, IN_CONTRACT is under_contract, CLOSED is closed. The per-buyer status of a linked client is left alone.

CLOSED does not loop back to anything via the state machine. Anniversary touches, past-client newsletters, and referral follow-ups are handled by the alerts system, not the pipeline. A repeat transaction with a past client creates a new lead.

What counts as an “action” at each column

Section titled “What counts as an “action” at each column”
Column Your next action is usually…
NEW Make first contact within the SLA window.
CONTACTING Follow up; aim for two-way conversation.
QUALIFIED Schedule showings; share matching listings; move toward commitment.
COMMITTED Run the buying process — offers, negotiations.
IN_CONTRACT Coordinate inspections, appraisal, financing milestones.
CLOSED Send the closing gift; queue the anniversary touch.
ARCHIVED Watch for re-engagement signals; click Re-engage and reach out if the score climbs.
TRASHED Nothing until the contact info is updated, then Contact info fixed.