Contatos e funil

Cada contato do WhatsApp vive numa etapa de um funil por conta. As etapas sobem sozinhas conforme o contato interage com suas transmissões, e você também pode movê-las à mão pelo painel ou pela API.

Toda conta nasce com quatro etapas padrão, nesta ordem: Não respondeu, Respondeu, Negociando e Concluído. Cada etapa tem um identificador de sistema estável (key): nao_respondeu, respondeu, negociando e concluido.

Classificação automática

Duas transições acontecem sozinhas, sem você precisar mexer:

  • Quando um contato é incluído numa transmissão, ele entra em Não respondeu (se ainda não tinha etapa).
  • Quando ele responde, sobe para Respondeu. Uma resposta conta quando cita o envio (resposta citada ou botão) ou quando chega até 7 dias depois do disparo. Isso é o mesmo sinal que alimenta o contador counters.responded das transmissões.

A classificação automática é sticky ao movimento manual: assim que você (ou uma chamada de API) move um contato de etapa, o automático para de mexer nele. A intenção humana sempre vence.

Etapas pela API

Liste as etapas da conta para descobrir o id de cada uma. Um contato traz a etapa atual em stage (null quando ainda não foi classificado).

Listar etapas do funil

Lista as etapas de contato da conta, ordenadas por `position`. O `id` de uma etapa é o que o PATCH de contato aceita em `stage_id`.

curl https://botozap.com.br/api/v1/contact-stages \
  -H "X-API-Key: $BOTOZAP_KEY"

Resposta 200

{
  "data": [
    {
      "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
      "key": "nao_respondeu",
      "label": "Não respondeu",
      "color": "zinc",
      "position": 1
    },
    {
      "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
      "key": "respondeu",
      "label": "Respondeu",
      "color": "green",
      "position": 2
    },
    {
      "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
      "key": "negociando",
      "label": "Negociando",
      "color": "amber",
      "position": 3
    },
    {
      "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
      "key": "concluido",
      "label": "Concluído",
      "color": "pink",
      "position": 4
    }
  ]
}

Listar contatos

Lista os contatos da conta, paginado por cursor. Cada contato traz a etapa do funil em `stage` (`null` quando ainda não foi classificado).

curl https://botozap.com.br/api/v1/contacts?limit=2 \
  -H "X-API-Key: $BOTOZAP_KEY"

Resposta 200

{
  "data": [],
  "paging": {
    "cursors": {
      "before": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa",
      "after": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa"
    },
    "next": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa",
    "previous": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa"
  }
}

Mover um contato de etapa

Envie o stage_id de uma etapa da própria conta. Um stage_id de outra conta é recusado com 422. O movimento é registrado como manual e passa a ser sticky.

Enviar stage_id: null limpa a etapa: o contato volta ao estado virgem (sem etapa e sem marca de manual) e sai do funil. Não fica sticky, então o próximo disparo que o inclua o reclassifica automaticamente do zero.

Mover contato de etapa

Move um contato para outra etapa do funil. O `stage_id` deve ser de uma etapa da própria conta (senão 422). O movimento é registrado como manual e passa a ser sticky (a classificação automática não o sobrescreve).

curl https://botozap.com.br/api/v1/contacts/5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11 \
  -X PATCH \
  -H "X-API-Key: $BOTOZAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stage_id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11"
}'

Resposta 200

{
  "data": {
    "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
    "wa_id": "5511999990001",
    "profile_name": "Maria",
    "phone": "5511999990001",
    "user_id": null,
    "username": null,
    "parent_user_id": null,
    "phone_number_id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
    "last_seen_at": "2026-07-14T12:00:00.000Z",
    "created_at": "2026-07-14T12:00:00.000Z",
    "notes": "pediu orçamento",
    "stage": {
      "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
      "key": "negociando",
      "label": "Negociando"
    }
  }
}

Nota do contato

Cada contato tem um campo notes livre (visível só para a sua equipe), editável pelo PATCH de contato e retornado no shape do contato.

Gerenciar etapas

Além das quatro padrão, você pode criar etapas custom, renomear/recolorir/ reordenar qualquer etapa e excluir as custom. As etapas de sistema (key não nulo) não podem ser excluídas, porque a automação depende de nao_respondeu e respondeu. Excluir uma etapa custom devolve os contatos dela ao estado sem etapa.

Criar etapa custom

Cria uma etapa custom no fim do funil. `color` é um token do conjunto: zinc, green, amber ou pink (nunca hex).

curl https://botozap.com.br/api/v1/contact-stages \
  -X POST \
  -H "X-API-Key: $BOTOZAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "Perdido",
  "color": "zinc"
}'

Resposta 201

{
  "data": {
    "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
    "key": null,
    "label": "Perdido",
    "color": "zinc",
    "position": 5
  }
}

Editar etapa

Renomeia, recolore ou reordena uma etapa (inclusive as de sistema). `position` reordena o funil.

curl https://botozap.com.br/api/v1/contact-stages/5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11 \
  -X PATCH \
  -H "X-API-Key: $BOTOZAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "Em negociação",
  "color": "amber"
}'

Resposta 200

{
  "data": {
    "id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
    "key": "negociando",
    "label": "Em negociação",
    "color": "amber",
    "position": 3
  }
}

Excluir etapa custom

Exclui uma etapa custom; os contatos dela voltam ao estado sem etapa. Etapas de sistema (key não nulo) respondem 422.

curl https://botozap.com.br/api/v1/contact-stages/5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11 \
  -X DELETE \
  -H "X-API-Key: $BOTOZAP_KEY"

Resposta 204