# Funil configurável (/docs/crm/funil)





O funil do PEPINO ZAP não é um quadro de cards que você arrasta à mão: é **configurável por regras**. Você cria **etapas** e, em cada uma, define **uma regra sobre a conversa**. As conversas se distribuem sozinhas pelas etapas conforme atendem (ou não) a cada regra — então o funil reflete o estado real do atendimento, sem ninguém mover nada.

* **No painel:** Funil → (criar/editar) — canvas com arrastar-e-soltar, no mesmo estilo do [construtor de fluxo](/docs/crm/fluxos).
* **Na API:** [Funil](/docs/api/funil/listFunnels) — o editor visual usa exatamente estes endpoints.

## Como uma conversa cai numa etapa [#como-uma-conversa-cai-numa-etapa]

Cada etapa tem uma `position` (ordem). Uma conversa é colocada na **etapa de maior `position` cuja regra ela satisfaz**. É isso que dá o **formato de funil**: as etapas iniciais pegam muitas conversas, as finais (mais avançadas) pegam menos, e a queda entre elas é a sua taxa de conversão.

* Uma conversa fica em **uma** etapa (a mais avançada que casa).
* Conversas que não casam com nenhuma etapa ficam **fora do funil** (`unplaced`).
* A avaliação é feita **na leitura** ([`GET /v1/funnels/{id}/data`](/docs/api/funil/getFunnelData)), sobre as conversas mais recentes do escopo (instância opcional do funil).

## A regra de uma etapa [#a-regra-de-uma-etapa]

A regra combina condições com &#x2A;*E (AND)** — a conversa precisa satisfazer **todas** as condições presentes. Condição vazia/"any" = sem restrição.

| Critério                    | Valores                                 | A conversa entra quando…                                                |
| --------------------------- | --------------------------------------- | ----------------------------------------------------------------------- |
| **Origem**                  | `any` · `inbound` · `outbound`          | foi **receptiva** (o cliente iniciou) ou **ativa** (a empresa iniciou). |
| **Status**                  | `any` · `open` · `pending` · `resolved` | está aberta, pendente ou resolvida.                                     |
| **Etiqueta**                | `labelId`                               | tem a etiqueta indicada (ex.: "Proposta enviada").                      |
| **Posição no fluxo de bot** | ver abaixo                              | está/passou por um ponto do seu [fluxo de chatbot](/docs/crm/fluxos).   |

### Posição no fluxo de bot (`flowMode`) [#posição-no-fluxo-de-bot-flowmode]

| `flowMode`    | Significado                                                        |
| ------------- | ------------------------------------------------------------------ |
| `any`         | Não considera o fluxo.                                             |
| `in_flow`     | A conversa está num fluxo ativo (opcional: `flowId` específico).   |
| `at_node`     | Está **no nó** `nodeId` do fluxo `flowId` (um ponto exato do bot). |
| `completed`   | **Concluiu** o fluxo (`flowId` específico ou qualquer um).         |
| `not_in_flow` | Não está em nenhum fluxo.                                          |

<Callout type="info">
  Combine os critérios para etapas precisas. Exemplos:
  <br />• "Novos leads" → `origin: inbound`, `flowMode: in_flow`.
  <br />• "Qualificados" → `flowMode: at_node` no nó "Quer orçamento?" do seu fluxo.
  <br />• "Proposta enviada" → `labelId` da etiqueta Proposta, `status: open`.
  <br />• "Ganhos" → `status: resolved`, `labelId` da etiqueta Fechado.
</Callout>

## Visualização (canvas) [#visualização-canvas]

O funil é desenhado num **canvas** (igual ao editor de fluxo): cada etapa é um nó com o **nome**, a **contagem** de conversas e um resumo da regra. Você **arrasta** as etapas para organizar, **liga** uma na outra (aresta visual) e, ao **clicar numa etapa**, vê as conversas que chegaram ali. A ligação entre etapas é apenas cosmética — quem decide o conteúdo da etapa é a **regra**, não a aresta.

## Montando um funil pela API [#montando-um-funil-pela-api]

1. **Crie o funil** — [`POST /v1/funnels`](/docs/api/funil/createFunnel) com `name` e, opcionalmente, `instanceId` (limita a uma instância).
2. **Adicione as etapas** — [`POST /v1/funnels/{id}/stages`](/docs/api/funil/createFunnelStage), uma por etapa, com `name`, `color`, a `rule` e `position` (a ordem; maior = mais avançada).
3. **(Opcional) Ligue as etapas** no canvas com [`PATCH .../stages/{stageId}/connection`](/docs/api/funil/setFunnelStageConnection).
4. **Leia os dados** — [`GET /v1/funnels/{id}/data`](/docs/api/funil/getFunnelData): contagem e até 50 conversas por etapa, mais `unplaced` e `totalEvaluated`.

```bash
# Cria o funil
curl -X POST https://api.pepinozap.com.br/v1/funnels \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Funil de vendas" }'

# Adiciona uma etapa "Proposta" (conversas abertas com a etiqueta X)
curl -X POST https://api.pepinozap.com.br/v1/funnels/fnl_.../stages \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Proposta", "color": "amber", "position": 2,
        "rule": { "status": "open", "labelId": "lbl_..." } }'

# Lê o funil (contagem + conversas por etapa)
curl https://api.pepinozap.com.br/v1/funnels/fnl_.../data \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx"
```

<Callout type="warn">
  A avaliação é **on-read** sobre as **5.000 conversas mais recentes** do escopo.
  Como cada conversa fica na etapa **mais avançada** que casa, etapas com regras
  mais "amplas" (ex.: só `status: open`) devem ter `position` **menor** que
  etapas mais específicas — senão elas "capturam" conversas que deveriam aparecer
  mais à frente.
</Callout>
