# Relatório de Viabilidade - Relatório Semanal Automático CRM Linkia (GHL)
**Data da análise:** 2026-06-22
**Analista:** Amanda (Gerente CRM Linkia)
**Conta:** PX3 Lab | Location ID: W7PGxpfbsFaEEUoQOtUb

---

## 1. Pipelines Disponíveis na Conta

| Pipeline | ID | Total de Leads |
|---|---|---|
| IMPORTAÇÃO ODOO | ISpWA1XXfYHCpModwGyJ | - |
| LEADS QUE VÃO NA PALESTRA CONAFOR | 6YjM6IvNbe5IWyD9JEqN | - |
| PADRÃO PX3 | 4AEDs93pm2FLfDSbSZYM | 302 |
| PROSPECÇÃO ATIVA | Pj7dm7v7AJqUPiG7UESq | 2920 total / 338 na semana 16-22/jun |
| SDR MARIA — PROSPECÇÃO ATIVA | iV13JEVbMgfcad9Xw6gz | 0 (vazio) |

**Pipeline mais indicada para o relatório semanal: PROSPECÇÃO ATIVA** (Pj7dm7v7AJqUPiG7UESq)

---

## 2. Stages da Pipeline PROSPECÇÃO ATIVA

| Stage | ID | Leads na semana (desde 16/06) |
|---|---|---|
| NOVO | 6df57cae-6625-48eb-a349-4e125b11ce29 | 149 |
| QUALIFICADO | e573ee69-bc9f-4656-b1d4-2b91f155f1b6 | 140 |
| AGENDAMENTO | f0ac38d7-d85f-4a2a-82c5-1d1976125e9b | 4 |
| PROPOSTA | c6f8cce8-338d-43f5-bb13-5e98ecd08b64 | 1 |
| GANHAMOS | 4566e2f6-fd0b-4cb5-bc1a-f52239564ebd | 0 |
| PERDEMOS | d1269476-f46f-4d2c-b81b-2418017d2067 | 0 |
| DESQUALIFICADO | 30fdd2cc-81ea-44ec-aa9c-39a3a4f09b83 | 44 |
| JÁ É CLIENTE | deeb3764-f950-4990-9dac-dbf454464db3 | 0 |

**Observação:** Não existe stage chamado "NO-SHOW" em nenhuma das pipelines. Ver seção 5.

---

## 3. Análise da API - Endpoint de Opportunities

### 3.1 Endpoint
```
GET https://services.leadconnectorhq.com/opportunities/search
Headers: Authorization: Bearer {token}, Version: 2021-07-28
```

### 3.2 Parâmetros Suportados (testados e confirmados)
| Parâmetro | Tipo | Descrição | Testado |
|---|---|---|---|
| `location_id` | string | ID da conta (obrigatório) | OK |
| `pipeline_id` | string | Filtrar por pipeline | OK |
| `pipeline_stage_id` | string | Filtrar por stage especifico | OK |
| `status` | string | open / won / lost / abandoned | OK |
| `assigned_to` | string | ID do usuário responsável | OK |
| `q` | string | Busca por nome | OK |
| `order` | string | asc / desc | OK |
| `limit` | integer | Máx por página | OK |
| `date` | integer | **Timestamp epoch em ms - filtra por createdAt >=** | OK |
| `startAfter` | integer | Cursor de paginação (timestamp) | OK |
| `startAfterId` | string | Cursor de paginação (ID) | OK |
| `id` | string | Busca por ID específico | OK |
| `campaignId` | string | Filtrar por campanha | OK |

### 3.3 Parâmetros NÃO suportados (retornam 422)
- `startDate` / `endDate` - não existem
- `createdAt` - não existe
- `dateAdded` - não existe
- `date__gte` / `date__lte` - não existem

### 3.4 Comportamento do filtro `date`
- Aceita: timestamp epoch em **milissegundos** (ex: `1750032000000`) ou segundos (`1750032000`)
- Filtra por: `createdAt >= data_informada` (confirmado em teste com 100 registros)
- **Limitação crítica: não há filtro de data final (end date).** O parâmetro `date` é apenas um "a partir de". Para limitar a uma semana, é necessário filtrar a data final em código, usando o campo `createdAt` de cada oportunidade.

### 3.5 Paginação
- Cursor-based via `startAfter` (timestamp) + `startAfterId` (ID)
- A resposta `meta` traz `nextPageUrl` pronto para usar
- Limite máximo por página: a testar, mas 100 funciona sem problemas

---

## 4. Análise da API - Observações (Notes)

### 4.1 Endpoint disponível
```
GET https://services.leadconnectorhq.com/contacts/{contactId}/notes
Headers: Authorization: Bearer {token}, Version: 2021-07-28
```

### 4.2 Estrutura de uma nota (confirmada em produção)
```json
{
  "id": "LlZX1vJk3eKudbSBZWNs",
  "body": "<p>Contato feito com cliente, não respondeu ainda.</p>",
  "bodyText": "Contato feito com cliente, não respondeu ainda.",
  "userId": "FKCKhrtdwZjHS6ISgAFF",
  "dateAdded": "2026-06-22T15:23:23.815Z",
  "contactId": "tbsOx2FZ24iTbuDodFen",
  "title": "",
  "color": "#fef7c3",
  "pinned": false,
  "relations": [
    { "objectKey": "opportunity", "recordId": "CAUe6AKrP13Dfe1mBGuy" },
    { "objectKey": "contact",     "recordId": "tbsOx2FZ24iTbuDodFen" }
  ]
}
```

### 4.3 O que a nota contém de útil para o relatório
- `bodyText`: texto limpo da observação (sem HTML)
- `dateAdded`: data/hora exata da criação (UTC) - **filtragem por semana deve ser feita em código**
- `userId`: ID do usuário que criou - **pode ser resolvido para nome** via GET /users/?locationId=
- `relations[].objectKey == "opportunity"` + `recordId`: vincula nota a uma oportunidade específica

### 4.4 Limitações do endpoint de notes
- **Não aceita filtros de data** (testado - retorna 422 com startDate/endDate)
- **Não existe endpoint bulk**: é obrigatório buscar notas por contactId, uma chamada por contato
- **Não existe** GET /opportunities/{id}/notes (retorna 404)
- **Não existe** GET /notes?locationId= (retorna erro)

### 4.5 Cobertura de notas na conta PX3
- Teste em 10 contatos do PADRÃO PX3 desta semana: **100% tinham pelo menos 1 nota**
- Equipe PX3 (usuário FKCKhrtdwZjHS6ISgAFF = Monique Miranda) cria notas sistematicamente

---

## 5. Sobre "Qualificados", "Fechamentos" e "No-Shows"

### 5.1 Qualificados
- Identificação direta pelo stage: `pipeline_stage_id = e573ee69-bc9f-4656-b1d4-2b91f155f1b6` (QUALIFICADO)
- **Suportado 100% pela API**

### 5.2 Fechamentos
- Identificação pelo stage GANHAMOS: `pipeline_stage_id = 4566e2f6-fd0b-4cb5-bc1a-f52239564ebd`
- Ou pelo campo `status = "won"` na oportunidade
- **Suportado 100% pela API**

### 5.3 No-Shows
- **NÃO existe stage "No-Show" em nenhuma das 5 pipelines ativas**
- Não existe campo customizado mapeado para no-show nas oportunidades
- Opções para o Renato decidir:
  a. **Criar um stage "NO-SHOW"** na pipeline (ação na interface) - então passaria a ser rastreável via API
  b. **Usar as notas**: identificar no-show pelo texto da observação (ex: busca por "no-show", "não compareceu", "faltou") - workaround via parsing de texto, menos confiável
  c. **Criar um custom field** tipo dropdown com campo "resultado_agendamento" (na-show / compareceu) - então rastreável via API

---

## 6. Usuários da Conta (para resolver "Criado por:")

| ID | Nome |
|---|---|
| MB5OrUBhTca9hbrunaQB | Eduardo Faria |
| n2TXqcFucc2mSfK5p0Do | Mary Oliveira |
| FKCKhrtdwZjHS6ISgAFF | Monique Miranda |
| 0ZFCVED2VANUkXjfB4tL | Naiane Nascimento |
| ac04q9LetfURwWyQZ748 | Renato ADMIN |
| BaTfAnfmGglY1wDQttrX | Renato Moraes |
| PHjPxMsAxfFL43kzANLf | Vinícius ADMIN |
| 3egsMwQ3G5rHFHVhp555 | Vinícius Amaral |

---

## 7. Veredicto de Viabilidade

### O que É possível 100% via API

| Métrica | Como obter | Endpoint |
|---|---|---|
| Total de leads que entraram na semana | `GET /opportunities/search?pipeline_id=X&date={start_epoch_ms}` + filtro de end date em código | Direto |
| Leads qualificados | Filtrar por stage QUALIFICADO + mesma lógica de data | Direto |
| Fechamentos | Filtrar por stage GANHAMOS ou status=won | Direto |
| Visão por stage | Uma chamada por stage, ou post-processamento | Direto |
| Observação mais recente por lead | GET /contacts/{id}/notes, pegar a mais recente por dateAdded | Indireto - 1 req/lead |
| Nome do autor da nota | Mapa de users obtido uma vez via GET /users/ | Indireto |

### O que NÃO é possível diretamente

| Métrica | Problema | Solução |
|---|---|---|
| No-shows | Stage não existe | Criar stage "NO-SHOW" na interface, ou parsear texto de notas |
| Filtro de data de fim em oportunidades | API só tem `date` (inicio), sem end date | Filtrar em código pelo campo `createdAt` da oportunidade |
| Busca bulk de notas | Não existe endpoint de notas por pipeline | Loop: 1 req HTTP por contato |

---

## 8. Arquitetura Técnica Recomendada para o Script Semanal

```
Toda sexta-feira, às 08h (cron):

1. Calcular janela: segunda-feira 00:00 até sexta-feira 23:59 da semana atual
   - start_epoch_ms: timestamp da segunda
   - end_date: sexta-feira (filtrar em Python)

2. GET /opportunities/search com date=start_epoch_ms + pipeline_id
   - Paginar via startAfter/startAfterId até esgotar (meta.nextPageUrl = null)
   - Filtrar em Python: opp.createdAt <= end_date

3. Por cada oportunidade retornada:
   - Registrar: nome, stage, createdAt, status, contactId
   - GET /contacts/{contactId}/notes
   - Filtrar notas com dateAdded dentro da semana
   - Pegar a nota mais recente (max dateAdded)
   - Resolver userId para nome via mapa de users

4. Gerar contagens:
   - Total de leads = len(todas as opps da semana)
   - Qualificados = len(opps com stage QUALIFICADO)
   - Fechamentos = len(opps com stage GANHAMOS ou status=won)
   - No-shows = requer definição (ver seção 5.3)

5. Montar relatório (Markdown, HTML ou PDF)
6. Enviar via Telegram / Email / WhatsApp (fora do escopo da API GHL)
```

### Estimativa de performance
- Semana com 338 oportunidades (semana de 16-22/jun como referência)
- Paginação de oportunidades: ~4 chamadas (100/página)
- Notas: 338 chamadas individuais
- Tempo estimado: ~115 segundos sequencial, ~40s com concorrência (5 threads)
- **Viável para execução automática via cron**

---

## 9. Decisões que Renato precisa tomar antes do desenvolvimento

1. **Qual pipeline(s) incluir no relatório?**
   - PROSPECÇÃO ATIVA (338 leads esta semana)? PADRÃO PX3 (302 total)? Ambas?

2. **Como tratar No-Shows?**
   - Criar stage "NO-SHOW" na pipeline (recomendado)
   - Ou parsear texto de notas

3. **A semana do relatório deve ser definida como:**
   - Segunda a sexta (sem fim de semana)?
   - Segunda a domingo?
   - Últimos 7 dias corridos?

4. **Onde entregar o relatório?**
   - Telegram (texto/PDF)?
   - Email para a equipe PX3?
   - Salvo num Google Drive ou painel?

---

## 10. Conclusão

**O relatório semanal automático é 100% viável via API do CRM Linkia**, com exceção da métrica "no-shows" que depende de uma definição estrutural na pipeline (criar o stage ou usar parsing de notas).

A arquitetura é clara e todos os endpoints necessários foram testados e confirmados em produção com dados reais da conta PX3. O desenvolvimento pode começar assim que as 4 decisões acima forem alinhadas com o Renato.
