pipeline

Link Deal Client

Changed on

Link an EXISTING client to a person-anchored deal, WITHOUT moving its stage.

Founder-approved addition (2026-08-18): a pursuit that's still person- anchored (known_contact_id set, promoted_client_id NULL — the normal mid-pursuit shape) is invisible to the client-scoped deal picker, so invoicing that contact's client had nothing to attach to. This endpoint stamps promoted_client_id via services.pipeline_stage_moves. link_deal_to_client, which shares its guarded UPDATE (_update_deal_promoted_client) with the Won gate's own client resolution (ai_platform/agents/pipeline/actions.py's move_deal_stage, for client_resolution={"mode": "link_existing"}) — never a raw ad hoc update — while recording a distinct, non-Won audit event (record_client_promoted_mid_lifecycle, the same one the existing POST /deals/{deal_id}/promote-to-client route uses) since this call never touches pipeline_stage_id — linking a client to an opportunity-stage pursuit must not move it to Won.

Response contract is FIXED (m3-web builds against it): errors are {"error": "<code>"} with 400/404; success is 200 {"deal_id": ..., "promoted_client_id": ...}.

Validations, each a distinct error code:

  • 404 deal_not_found — no such deal in this org.
  • 400 deal_ineligible — the deal exists but review_state != 'approved', OR archived_at IS NOT NULL (mirrors the not_approved/ 400 convention POST /deals/{deal_id}/archive already uses for the same "exists but wrong state" shape).
  • 400 already_client_linked — the deal is not person-anchored (promoted_client_id is already set); this endpoint only handles the NULL → set transition, never a reassignment.
  • 400 contact_mismatch — the deal has no known_contact_id (nothing to validate the client against), or the target client is not linked (client_contact_links) to the deal's known_contact_id. Prevents linking arbitrary deals to arbitrary clients.
post/api/pipeline/deals/{deal_id}/link-client

Request

  • Base URL: https://api.every.ai (the document declares no server; this is the origin it was published from)
  • URL: https://api.every.ai/api/pipeline/deals/{deal_id}/link-client
  • Auth: none declared

Query parameters

user_idstring nullable
org_idstring nullable

Request body

client_idstring uuid required

Response

Successful Response

unknown required

Changes