Skip to content

Assert Deal

PUT
/deals/assert

Create or update a deal. Matches by name + company_id.

Deliberately NOT wired into the closed-stage gates or the completeness rule: assert is the sync-shaped surface (external systems pushing state, no human to answer a 400), the same category the internal router excludes for POST /v1/deals/webhook/sync and the CRM pull worker (#15530 “Out of scope”). Only input hygiene applies here: ids must exist and close_date must parse.

#16060: a stage move made here now emits deal.stage_changed and writes cb_deal_stage_history, like every other stage writer. background_tasks is injected (not a body field, so the request schema is unchanged) and the publish is queued only after the session context has exited — a rolled-back assert publishes nothing. Because assert is the sync-shaped surface, the SAME stage arrives on every tick of the caller’s poll loop: the event fires only on an actual transition, never on a re-assert of the current stage.

Authorizations

Parameters

Header Parameters

X-Target-Org-Id
Any of:
string

Request Body required

object
amount
Any of:
number
close_date
Any of:
string
company_id
Any of:
string
currency
Any of:
string
description
Any of:
string
name
required

Deal name (match key)

string
pipeline_id
Any of:
string
stage_id
Any of:
string

Responses

200

Successful Response

object
data
required
object
action
required

‘created’ or ‘updated’

string
deal_id
required
string
pagination
Any of:
object
has_next
required

Whether there are more pages

boolean
limit
required

Items per page

integer
next_cursor
Any of:
string
page
required

Current page number (1-indexed)

integer
total
required

Total number of items

integer

422

Validation Error

object
detail
Array<object>
object
loc
required
Array
msg
required
string
type
required
string