Guides
Operation to close
Record an offer, advance the pipeline, and what to do when the gate says no.
Record the offer
An offer is anchored on the operation, not the lead. lead_id is taken from
it, and property_id from the body or from the operation's own — if neither is
present, 422.
curl -X POST "$ORKASA_API/offers" \
-H "Authorization: Bearer $ORKASA_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation_id": "053655cc-47f4-43fd-9369-6f9dee659a28",
"amount": 238000,
"currency": "USD",
"notes": "Subject to credit approval."
}'
Recording an offer does not accept it and does not move the stage. They are
two separate gestures on purpose: receiving a proposal and accepting it are not
the same decision, and accepting has real consequences — the property goes back
to pending and its listings are paused.
offer_type follows the property's listing_type when you omit it. The
response carries a public_token: that is the shareable offer link.
Advance the stage
curl -X PATCH "$ORKASA_API/operations/053655cc-47f4-43fd-9369-6f9dee659a28" \
-H "Authorization: Bearer $ORKASA_KEY" \
-H "Content-Type: application/json" \
-d '{ "stage": "offer" }'
One step at a time, with the current stage's gate passed. If something is missing:
{
"error": {
"code": "validation_error",
"message": "La etapa actual tiene 2 paso(s) pendiente(s).",
"details": {
"reason": "stage_gate_blocked",
"pending_actions": [
{ "id": "propiedadesVisitadas", "label": "Propiedades visitadas" },
{ "id": "favoritaElegida", "label": "Propiedad favorita elegida" }
]
}
}
}
Nothing was written. The operation stayed where it was, and
pending_actions tells you exactly what is missing.
There is no endpoint for "mark these steps as done". That is deliberate:
marking precioAcordado moves the offer to accepted, which unpublishes the
property; marking ofertaPreparada creates an offer row and requires an
amount. A generic "mark done" would let a chat sentence unpublish a listing.
Steps close through precise verbs — record an offer, upload a document — or by
hand on the operation.
Close
won · sold · rented are only reachable from the last active stage of
the flow, gate passed. lost is reachable from anywhere and requires its
reason:
curl -X PATCH "$ORKASA_API/operations/053655cc…" \
-H "Authorization: Bearer $ORKASA_KEY" \
-H "Content-Type: application/json" \
-d '{ "stage": "lost", "lost_reason": "Bought through another agency" }'
Closing fires the deal_won webhook — that is where billing, the team
notification, or whatever comes next hooks in. See
Webhooks.
Importing a book that is already mid-funnel
stage on POST /operations is not gated: there it is an initial state,
not a transition. An agency arriving with live deals creates them in the stage
they are actually in.
curl -X POST "$ORKASA_API/operations" \
-H "Authorization: Bearer $ORKASA_KEY" \
-H "Content-Type: application/json" \
-d '{ "lead_id": "…", "operation_type": "buy", "stage": "offer" }'
After creation, everything goes through the normal rules. An existing operation is never dragged backward.