orkasa

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.