facade
Manage Deal
Create and manage deals through the pipeline — the consolidated deal writer.
Evidence-based progression (no id, typed payloads):
- handoff: JourneyHandoffRequest; fetch customer_impact for the exact journey and claim first. Copy handoff.context_token and latest.id as expected_context and expected_decision_id. Propose names receiver_user_id, future due_at and brief; review the saved packet and all gaps. Only the named receiver's own authenticated session can accept or return. Owners/operators may withdraw; then propose again to change the receiver or refresh changed context. Never impersonate the receiver. Acceptance creates no impact or revenue credit and does not transfer existing promise or timeline ownership.
- won_review: WonReviewRequest; fetch customer_impact for the account and exact journey first. Copy won_review.context_token and review.id into expected_context and expected_review_id. Confirm or contradict the recorded won outcome and all displayed agreed terms using original customer email/transcript quotations, explicit operator review, a reason and a fresh request_key. Use withdraw to remove the latest assertion without new evidence. This never closes/reopens the deal, changes prices, verifies impact or accepts a handoff. Changed terms, reopened deals and changed sources require another review.
- stage_policy: StageEvidencePolicyRequest with stage_id, expected_updated_at, policy, reason, request_key. Fetch customer_impact for the account and exact journey first; deal_progression has current stages and timestamps. The policy applies to the whole pipeline stage; null removes its requirements.
- advance: DealProgressionRequest with journey_id, stage_id, expected_context copied from context_token, reason, request_key. Obtain explicit operator review. Reads never advance; changed context needs another review. Existing stage writes cannot bypass gated forward moves. CRM-linked deals follow CRM.
Actions (id = deal UUID):
- create: open a deal (no id; payload = {deal_name, person_id?, company_id?, deal_source? (outbound|inbound|referral|manual|imported; default manual), terms?, stage?, pipeline_id?, stage_id?, close_probability?, notes?}). terms is the deal's money record: {offer_id?, amount_minor?, currency?, billing_period?, quantity?, agreed?} — amount_minor is the net price PER BILLING PERIOD, per unit, in the currency's MINOR units (1,800.00 USD/month = 180000); billing_period one_time|monthly|quarterly|annual (recurring periods carry an annual contract value, one_time is a project total); the offer supplies currency and period when omitted; agreed=true only when the customer agreed the price (an agreed, won deal becomes committed revenue, an estimate never does). Omit terms to let the value agent estimate. pipeline_id and stage_id must be supplied together; bulk via items.
- task: create a follow-up task on the deal (payload as for manage_person task).
- note: add a note to the deal's record (payload = {body}). The response's note id and updated_at identify the note for a later edit.
- update: patch deal fields (payload = any of deal_name, terms (partial: only the keys given change), close_probability, expected_close_date, next_step, notes, stage, …).
- stage: advance/move the deal — sugar for update; payload must include {stage}.
- qualify: extract the customer's SPICED record from the deal's conversations and write the Customer Impact record; MEDDIC is derived from it (no payload).
- impact_commitment: record the deal's Customer Impact (Revenue Architecture SPICED) as a claim: payload {situation?, pain?, impact? {rational? {metric, baseline, target, unit, by}, emotional?}, critical_event? {kind: compelling|critical|mandatory, due|milestone, consequence}, decision? {criteria, process, buying_center? [{person_id?, name?, role}], decider, champion, decider_person_id, champion_person_id}, first_impact_by?, beneficiary_person_id?, offer_id?, statement?}. Gaps fill from the standing record; the record earns its status from evidence. A deal-level record is superseded by the new one. A record a customer journey owns (a discovery journey or a delivery promise) keeps its claim: the SPICED points you change are written in place, 409 when the record moved while you saved (read it again), 422 when the write changes what the journey fixes (first_impact_by, beneficiary_person_id, offer_id, statement, a delivery record's decider/champion) or names a buying-center member without a person. A buying_center you send replaces the deal's stakeholders with its members that have a person (a role the engagement's buying roles hold stays the engagement's: edit it there); the decider and champion follow from the buying center unless you name them. A critical event with a consequence plus a named beneficiary is what makes the deal a verified priority (VM4).
- stakeholders: the deal's buying-center registry, one row per (person, role): a person can hold several roles (payload = {action: list|add|update|remove, person_id?, role?, notes?}). add adds role beside the person's other roles (409 when they already hold it); update with role SETS the person's one role and removes their other roles on the deal (to add a role, use add; to drop one, use remove with role), and notes alone change the notes on every row of the person; remove removes the person, or only role when given; list returns every row with each person's persona (their highest-authority role on the deal).
- offer_correction: propose re-filing a WON deal's customer engagement under the offer it really sells (id = deal UUID; payload = {offer_id, reason, supporting_evidence_ids? [evidence UUIDs that show the right offer]}). Nothing changes yet: the answer is the proposal Action and its preview (the engagement and both offers, the First Impact objectives it retires with their runs, the price-gap claims it retires, the open proposals it expires). 409 names why it cannot stand (no_live_journey: change the offer with update instead; same_offer; offer_unavailable; no_commitment_source; journey_has_records with the records that block it). A plain update of the offer of a deal with an engagement is refused (409 engagement_offer_locked): propose a correction.
- offer_correction_accept / offer_correction_reject: decide a proposed correction (id = the offer_correction Action UUID; payload = {expected_version: the version you read}). Only an owner or operator, only after the user confirms. Accepting re-files the engagement in one transaction; every reader then uses the correcting engagement.
- won / lost / stalled: record the deal outcome (payload optional: {loss_reason?, win_factors? [str]}; the action sets the outcome).
- meeting_outcome: record how the deal's booked meeting went (payload = {outcome: completed|no_show|rescheduled|canceled, quality_rating? 1-5, follow_up_notes?}).
- reopen: reopen a closed deal (payload optional: {stage}, a stage name; omitted, the deal returns to negotiation).
- create_pipeline: create a pipeline (no id; payload = {name, is_default?, position?, external_id?, stages?}); each stage takes the create_stage fields, vm_id included.
- rename_pipeline / archive_pipeline / unarchive_pipeline / set_default: id = pipeline UUID. Rename takes payload={name}; the others take no payload.
- reorder_pipelines: no id; payload={ordered_pipeline_ids}.
- create_stage: id = pipeline UUID; payload={name, position?, stage_kind?, probability_default?, external_id?, vm_id?}. vm_id is the stage's Bowtie gate: VM3 (buying process started), VM4 (verified priority) or VM5 (mutual commitment). Omitted, a new stage starts at VM5 when won or lost, else at its name's default open gate; an open stage with a bespoke name, or with a won or lost name, stays unmapped until you map it.
- update_stage / archive_stage / unarchive_stage: id = pipeline UUID and payload.stage_id = stage UUID. Update also accepts name, stage_kind, probability_default, and vm_id (VM3|VM4|VM5; omit to keep the mapping; a won or lost stage stays VM5, and one reopened without vm_id takes the create_stage default).
- reorder_stages: id = pipeline UUID; payload={ordered_stage_ids}.
Bulk: id arrays apply the same action+payload per deal (server-side loop, per-item status — partial failure is reported per item, never silent; max 100). Every action but create checks its payload keys against the route's own model first: an unknown key is a 422 that names it and lists the fields the action takes. Values are validated by the underlying route's own schema, so a bad field returns that route's precise 422.
post/api/facade/manage_deal
Request
- Base URL: https://api.vruum.ai
- URL: https://api.vruum.ai/api/facade/manage_deal
- Auth: HTTPBearer (a scheme the document does not define)
Request body
Response
Successful Response
unknown required
Changes
No recorded changes to this operation across all 1 revision of this API.