# Stages and gates

> Sales stages are defined per installation; when stage gates are on, an opportunity advances only once it meets their conditions.

Each installation's sales pipeline is defined on the **Settings → Stages** (*Ayarlar → Aşamalar*) page: the key, name, and color of each open stage; the names for won, lost, and canceled; whether the Cancel stage is enabled; and the **stage rules**.

## Stage keys

The API always uses the **key**; the name is what users see. The closing keys are fixed:

| Key | Meaning |
|---|---|
| `Win` | Won |
| `Lost` | Lost |
| `Cancel` | Canceled (may be disabled in the installation) |
| `Account` | Customer-tracking container (not counted in the sales funnel) |

Open stage keys are specific to each installation. For example, the Makro pipeline uses `Qualify`, `Viable`, `Present Solution`, `Negotiation`, `Expect to Close`, while a new installation defaults to `Lead`, `In Progress`. Don't hard-code keys — read them from the [`GET /api/v1/me`](/rest-api/auth/me) response:

```json
"constants": {
  "stages": ["Qualify", "Viable", "Present Solution", "Negotiation", "Expect to Close", "Win", "Lost", "Cancel"],
  "open_stages": ["Qualify", "Viable", "Present Solution", "Negotiation", "Expect to Close"],
  "stage_labels": { "Qualify": "Qualify", "Win": "Win", "Lost": "Lost", "…": "…" },
  "stage_sla": { "Qualify": 30, "Viable": 60, "Present Solution": 60, "Negotiation": 30, "Expect to Close": 15 },
  "stage_rules": true
}
```

## Stage rules (gates)

In installations with `stage_rules: true`:

- Open stages are passed through **in order**; you can't skip a stage.
- To move to the next stage, the current stage's gate must be satisfied.
- `Win` can be set only from the last two open stages (`Negotiation` and `Expect to Close` in Makro).
- A closed opportunity can't be reopened; [Revive opportunity](/rest-api/deals/revive) creates a new record.

Gates in the Makro pipeline:

| Stage | To move to the next stage |
|---|---|
| `Qualify` | BANT 4/4 (budget, authority, need, timing) |
| `Viable` | At least one face-to-face (F2F) visit since the project started, and a product selected on the opportunity |
| `Present Solution` | The latest trial's outcome is Successful (*Başarılı*) or Partially Positive (*Kısmen Olumlu*) |
| `Negotiation` | Quote price (or estimated value) and payment term entered |

If the gate isn't satisfied, the [stage endpoint](/rest-api/deals/stage) returns `409 gate`:

```json
{
  "ok": false,
  "error": "gate",
  "message": "Viable'a geçmek için: BANT kriterleri 4/4 sağlanmalı (Budget · Authority · Need · Time)",
  "gate_problems": ["BANT kriterleri 4/4 sağlanmalı (Budget · Authority · Need · Time)"]
}
```

The single-opportunity endpoint always includes the `gate_ok`, `gate_problems`, and `next_stage` fields; check them before changing the stage so you can show users what's missing.

In installations with `stage_rules: false`, there are no gates: an opportunity can move to any open stage, or to won or lost.

## Durations (SLA)

Each open stage has a target in days (`stage_sla`), and each opportunity has a total lifetime (`opp_lifetime_days`, 180 days by default). Overruns show up as negative values in the opportunity's `sla_left` and `lifetime_left` fields and lower its health score. The values vary by installation and are set on the **Settings → Stage setup** (*Ayarlar → Aşama kurulumu*) card.

## Winning and losing

- `Win`: the company becomes `AC` (active customer), the line items of the accepted quote are written to the company as contracted prices, a draft contract is created if the Contracts module is enabled, and the `opp_won` event is sent to apps.
- `Lost` / `Cancel`: the `reason` field is stored as the loss reason (`constants.loss_reasons`; `Diğer` (Other) if the reason isn't in the list). On `Lost`, the `opp_lost` event is sent to apps.
- Every stage change also sends an `opp_stage` event (with the old and new stage).