← Back to brief

reference hs pipeline stages

memory · reference_hs_pipeline_stages.md

⚠ CRITICAL: stage ID names DO NOT match what they represent

The pipeline labels were renamed to fit SkyRun's BD process, but the underlying default-pipeline stage IDs kept the original HubSpot generic names. Result: contractsent is actually the Won stage, and closedwon is actually the Lost stage. Get this wrong and you trigger the wrong HS auto-notification (e.g. the Hadank "Contract Sent" false-positive on 2026-04-30 morning came from deal_sync.py mapping post_walkthrough_pending_agreement → presentationscheduled, which fires the "Contract" notification).

ALWAYS reference this table before patching any code that writes deal stage IDs.

Canonical mapping (live source — pipelineId: default, portal 23273108)

displayOrderStage IDSkyRun LabelProbabilityWhat this means in our process
0appointmentscheduledFirst \Ground Rules Appointment Scheduled0.1Initial intro / qualification call booked
1qualifiedtobuySecondary \Discovery Appointment Scheduled0.3Discovery / walkthrough scheduled or complete
2presentationscheduledContract \Contract Received by Decision Makers0.7We've SENT the management agreement; awaiting return
3decisionmakerboughtinFinal \Decision Makers Have Scheduled a Final Appointment0.9Verbal commit + agreement returned but not yet signed
4contractsentWon \Contract Signed by Decision Makers1.0🎉 SIGNED — closed-won
5closedwonLost \Decision Makers Declined to Sign the Contract0.0❌ Declined / closed-lost

Code-side stage transitions

deal_sync.py maps internal deal-state strings to HS stage IDs. The current correct mapping (patched 2026-04-30 PM after Hadank incident):

python
INTERNAL_TO_HS_STAGE = {
    "discovery_call_scheduled":           "appointmentscheduled",     # First
    "discovery_complete":                 "qualifiedtobuy",            # Secondary
    "post_walkthrough_pending_agreement": "qualifiedtobuy",            # Secondary  ← was wrong, fixed
    "agreement_sent":                     "presentationscheduled",     # Contract
    "agreement_received":                 "decisionmakerboughtin",     # Final  ← was wrong, fixed
    "agreement_signed":                   "contractsent",              # Won
    "lost":                               "closedwon",                 # Lost
}

Stage-related HS auto-notifications (what fires when)

HubSpot auto-notifies the deal owner (and configured watchers) when a deal moves into specific stages:

If you transition a deal forward without explicit confirmation from Joseph or Rachel, you risk firing a notification that contradicts the actual sales reality.

How to query live

javascript
// In an authenticated HubSpot tab, via chrome_bridge:
fetch('/api/crm-pipelines/v1/pipelines/deals?portalId=23273108', {
  headers:{'X-HubSpot-CSRF-hubspotapi': (document.cookie.match(/csrf\.app=([^;]+)/)||[])[1]}
}).then(r=>r.json())

Returns the full pipeline with pipelineId, label, and a stages array containing stageId, label, displayOrder, and metadata.probability.

Cross-references