Resources
Operations
list · get · create · update
Filters
GET /operations?stage=&operation_type=&lead_id=&open_only=
Responses expose flow, stage, stage_label and is_terminal.
Create
POST /operations funnels through the same primitive as the app: a lead has
at most one open operation per type, so an existing one is returned with
200 instead of creating a duplicate. 201 means newly created.
lead_iduuidrequiredoperation_typebuy | rent | sellrequiredstagestringAn initial state, not a transition: no gate here. That is what lets you import a book whose deals are already mid-funnel.
Update the stage
PATCH /operations/{id} with stage is not a raw column write. It obeys
the rules of the "Avanzar" button:
- one step at a time — skipping a stage is
422 invalid_transition; - the current stage's gate must have passed, otherwise
422 stage_gate_blockedwith what is missing indetails.pending_actions; lost·expired·cancelledare reachable from anywhere;lostrequireslost_reason;won·sold·rentedonly from the last active stage of the flow;- a closed operation does not move (
422 operation_closed).
details.reason carries the machine-readable variant: invalid_stage,
invalid_transition, stage_gate_blocked, operation_closed,
lost_reason_required, db_gate_blocked.
The database enforces gates of its own on top of these — a rental cannot close
before the deposit is paid, for example. They surface as 422 with
details.reason = "db_gate_blocked".
See Stages for the three full journeys.