# CRM O CRM do Festero acompanha cada interessado como uma **oportunidade de venda**, que anda por **etapas** do funil até virar venda ganha ou perdida. Estas rotas devolvem as oportunidades e as etapas, para você levar o funil a um BI, a um painel ou a outro sistema. **Escopo exigido:** `crm:read`. Sem ele, as rotas respondem [`scope_missing`](https://developers.festero.com.br/errors.md#scope_missing). [Testar na referência interativa](https://developers.festero.com.br/referencia/) ## Listar oportunidades ### `GET /v1/crm/opportunities` Lista as oportunidades da empresa, da alteração mais antiga para a mais recente, com [paginação por cursor](https://developers.festero.com.br/paginacao.md). Oportunidades mescladas em outra não aparecem. | Parâmetro | Tipo | Descrição | |---|---|---| | `status` | texto | Filtra pela situação: `open`, `won`, `lost`, `duplicate` ou `notclient`. Outro valor responde `400`. | | `stageId` | GUID | Só as oportunidades desta etapa do funil. Pegue os ids em `GET /v1/crm/pipeline-stages`. | | `updatedSince` | data e hora ISO 8601 | Só as oportunidades alteradas a partir deste instante. | | `limit` | inteiro | Tamanho da página, de 1 a 100 (padrão 25). | | `cursor` | texto | O `nextCursor` da página anterior. | ```bash curl "https://platform.festero.com.br/v1/crm/opportunities?status=open&limit=2" \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` ```json { "data": [ { "id": "8d3f6b1e-52a4-4c7e-9a18-0b6c2f4d7e31", "title": "Aniversário de 15 anos da Marina", "status": "open", "stage": { "id": "c41e9a77-6d02-4b58-8f3a-91d5e7b20a64", "name": "Proposta enviada" }, "client": { "id": "2a7b5c90-31de-4f68-b4a2-6e0d8c19f533", "name": "Marina Albuquerque" }, "quoteId": "f09c3d12-7a5b-4e84-a6c1-3b8e5d2f9a70", "eventId": null, "estimatedValue": { "amount": 18500.00, "currency": "BRL" }, "expectedEventDate": "2027-02-13", "eventTypeName": "Aniversário de 15 anos", "estimatedGuests": 120, "source": "vitrine", "closeReason": null, "closedAt": null, "lastContactAt": "2026-10-19T16:20:00-03:00", "nextFollowUpAt": "2026-10-23T10:00:00-03:00", "createdAt": "2026-10-12T09:41:17-03:00", "updatedAt": "2026-10-19T16:20:05-03:00" } ], "nextCursor": "eyJ0IjozOTU0..." } ``` A resposta foi abreviada: com `limit=2`, `data` traria dois itens. ## Buscar uma oportunidade ### `GET /v1/crm/opportunities/{id}` Devolve uma oportunidade pelo identificador, com os mesmos campos da lista. Responde `404` ([`not_found`](https://developers.festero.com.br/errors.md#not_found)) se ela não existe, foi mesclada em outra ou é de outra empresa. A resposta traz `ETag`: veja [Paginação e datas](https://developers.festero.com.br/paginacao.md#recurso-individual-etag). | Parâmetro | Onde | Descrição | |---|---|---| | `id` | caminho | Identificador da oportunidade (GUID). | ```bash curl https://platform.festero.com.br/v1/crm/opportunities/8d3f6b1e-52a4-4c7e-9a18-0b6c2f4d7e31 \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` ## Listar as etapas do funil ### `GET /v1/crm/pipeline-stages` Lista todas as etapas do funil, na ordem do quadro do CRM no Festero. Não tem parâmetros. A resposta usa o mesmo formato das listas, com todas as etapas em `data` e `nextCursor` sempre `null`. ```bash curl https://platform.festero.com.br/v1/crm/pipeline-stages \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` ```json { "data": [ { "id": "6b0d2f84-1c93-4e57-a8d6-3f7a9c5e1b20", "name": "Novo contato", "color": "#6366F1", "displayOrder": 1, "isDefault": true, "isClosedWon": false, "isClosedLost": false, "isVisitStage": false }, { "id": "c41e9a77-6d02-4b58-8f3a-91d5e7b20a64", "name": "Proposta enviada", "color": "#F59E0B", "displayOrder": 3, "isDefault": false, "isClosedWon": false, "isClosedLost": false, "isVisitStage": false }, { "id": "a95e3c17-8b24-4d60-b1f7-0e6d2a4c8f93", "name": "Fechado", "color": "#10B981", "displayOrder": 5, "isDefault": false, "isClosedWon": true, "isClosedLost": false, "isVisitStage": false } ], "nextCursor": null } ``` ## Campos da oportunidade | Campo | Tipo | Descrição | |---|---|---| | `id` | GUID | Identificador da oportunidade. | | `title` | texto | Título. Trechos que parecem telefone, e-mail ou documento aparecem como `[oculto]`. | | `status` | texto | `open`, `won`, `lost`, `duplicate` ou `notclient`. | | `stage` | `{ id, name }` | Etapa atual no funil. | | `client` | `{ id, name }` ou `null` | Cliente vinculado. | | `quoteId` | GUID ou `null` | Orçamento vinculado ([Orçamentos](https://developers.festero.com.br/api/orcamentos.md)). | | `eventId` | GUID ou `null` | Evento vinculado ([Eventos](https://developers.festero.com.br/api/eventos.md)). | | `estimatedValue` | dinheiro ou `null` | Valor estimado da venda. | | `expectedEventDate` | data ou `null` | Data do evento pedida pelo cliente. Na tela do Festero, "Data do evento". | | `eventTypeName` | texto ou `null` | Nome do tipo de evento pretendido. | | `estimatedGuests` | inteiro ou `null` | Número estimado de convidados. | | `source` | texto ou `null` | Origem da oportunidade (canal de captação), em minúsculas. | | `closeReason` | texto ou `null` | Código do motivo do fechamento. | | `closedAt` | instante ou `null` | Quando foi encerrada. | | `lastContactAt` | instante ou `null` | Último contato. | | `nextFollowUpAt` | instante ou `null` | Próximo retorno agendado. | | `createdAt` | instante | Criação. | | `updatedAt` | instante ou `null` | Última alteração. | ## Campos da etapa | Campo | Tipo | Descrição | |---|---|---| | `id` | GUID | Identificador da etapa. | | `name` | texto | Nome da etapa. | | `color` | texto | Cor da etapa no quadro, em hexadecimal. | | `displayOrder` | inteiro | Posição da etapa no funil. | | `isDefault` | booleano | Indica a etapa padrão do funil. | | `isClosedWon` | booleano | A etapa significa venda ganha. | | `isClosedLost` | booleano | A etapa significa venda perdida. | | `isVisitStage` | booleano | Etapa para onde vai a oportunidade quando uma visita é marcada. | ## Campos que pedem atenção - **Sem dados de contato.** Telefone, e-mail e endereço do lead não existem na API, nem anotações, descrições livres ou o motivo de perda em texto: `closeReason` traz só o código. - **As etapas são da sua empresa.** Cada empresa monta o próprio funil; por isso a rota de etapas existe. Use `isClosedWon` e `isClosedLost` para saber se uma oportunidade foi ganha ou perdida em vez de comparar nomes de etapa. - **`status` e etapa andam juntos, mas são coisas diferentes.** `status` diz a situação (`open`, `won`, `lost`, `duplicate`, `notclient`); `stage` diz onde ela está no funil. - **`source` não é uma lista fechada.** Trate-o como texto. O valor depende de por onde a oportunidade entrou (por exemplo, `vitrine`). - **Tempo real:** os avisos [`opportunity.created`](https://developers.festero.com.br/webhooks/eventos.md#opportunity-created) e [`opportunity.stage_changed`](https://developers.festero.com.br/webhooks/eventos.md#opportunity-stage-changed) dispensam consultar o funil de tempos em tempos. ## Erros possíveis | Código | HTTP | Quando | |---|---|---| | [`validation_failed`](https://developers.festero.com.br/errors.md#validation_failed) | 400 | `status` inválido, `limit` fora de 1 a 100 ou `cursor` inválido. | | [`scope_missing`](https://developers.festero.com.br/errors.md#scope_missing) | 403 | A credencial não tem `crm:read`. | | [`not_found`](https://developers.festero.com.br/errors.md#not_found) | 404 | Oportunidade inexistente, mesclada ou de outra empresa. | [Testar na referência interativa](https://developers.festero.com.br/referencia/)