---
title: "Manage Deal"
method: POST
path: "/api/facade/manage_deal"
tags: ["facade"]
---

# Manage Deal

`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)

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.

## Request body

- WriterRequest: Uniform request body for every facade writer.
  - `action` string, required: The operation to perform — see the tool description for the action vocabulary and each action's id/payload semantics.
  - `id` union: Target entity id, or an ARRAY of ids to apply the same action+payload to each (max 100; see the tool description for which entity the id names per action).
    - string
    - string[]
  - `payload` object, nullable: Action-specific fields, validated by the underlying route's own schema (a bad field 422s with that route's precise errors). See the tool description per action.
  - `items` object[], nullable: For create-like actions only: an array of per-item payloads processed in order with per-item results (max 100). Mutually exclusive with `id` and `payload`.

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/vruum/apis/vruum-public-api.md) · [All operations](https://skmtc.dev/vruum/apis/vruum-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/vruum/apis/vruum-public-api/revisions/b8ada111c30a?raw)
