---
url: https://docs.ouvixpro.ai/guia/telas.md
description: >-
  Como reproduzir o painel OuvixPRO no seu sistema com /v1/catalogo, /v1/tela e
  o áudio: kpis, listas de evidência, rótulos, tons e as nove telas bloco a
  bloco.
---

# Montando a tela

A API entrega o painel do jeito que a interface OuvixPRO mostra: cada card com texto pronto, cor e a lista de conversas que abre ao clicar. Você não precisa reimplementar regra nenhuma — os blocos de `tela` são calculados pelo mesmo código que desenha o painel.

## Em três chamadas

| Chamada | Quando | O que traz |
| --- | --- | --- |
| `GET /v1/catalogo` | uma vez, ao iniciar | rótulos, cores, metas, catálogo de planos. Não muda por dia. Cache de 1 hora. |
| `GET /v1/tela` | a cada período ou turno | as nove telas prontas em `tela`, as listas de evidência em `listas` e os atendimentos referenciados em `atendimentos`. |
| `GET /v1/atendimentos/{id}/audio` | quando a pessoa clica em ouvir | o WAV do trecho, já recortado e com dados sensíveis em silêncio. |

```bash
curl "https://api.ouvixpro.ai/v1/catalogo" -H "Authorization: Bearer $OUVIX_API_KEY"

curl "https://api.ouvixpro.ai/v1/tela?Id_unidade=375&de=2026-10-06&ate=2026-10-06" \
  -H "Authorization: Bearer $OUVIX_API_KEY"

# só uma tela, com os atendimentos que ela usa
curl "https://api.ouvixpro.ai/v1/tela?Id_unidade=375&de=2026-10-06&ate=2026-10-06&tela=venda" \
  -H "Authorization: Bearer $OUVIX_API_KEY"
```

`GET /v1/painel` continua entregando tudo: os números brutos **e** `painel.tela`, idêntico ao de `/v1/tela`. Use `/v1/tela` quando só quer desenhar; use `/v1/painel` quando também quer os dados para cruzar.

## Como os blocos se ligam

Todo card segue o mesmo caminho: **kpi → lista → atendimento → áudio**.

```text
tela.resumo.kpis[3]            →  { label: "Graves", valor: "0", tone: "ok", lista: "graves" }
listas["graves"]               →  { titulo, hint, ids: ["2026-10-06:atend_12", …], badges, notas }
atendimentos[].id              →  o objeto completo, com rotulos e audio
atendimentos[].audio.url       →  GET /v1/atendimentos/2026-10-06:atend_12/audio
```

### Um kpi

| Campo | Tipo | O que é |
| --- | --- | --- |
| `chave` | string | Identificador estável do indicador (episodios, nota, graves…). |
| `label` | string | Título do card, como no painel. |
| `valor` | string | Texto pronto para mostrar: "7.4/10", "9 de 13", "25%", "—". |
| `numero` | number / null | O valor bruto, para quem quer calcular ou ordenar. |
| `tone` | string | ok, warn, bad ou neutral. Cores em /v1/catalogo → tons. |
| `hint` | string / null | Legenda pequena abaixo do número. |
| `lista` | string / null | Chave em tela.listas com os atendimentos que o card abre ao clicar. null quando o card não abre nada. |

### Uma lista

| Campo | Tipo | O que é |
| --- | --- | --- |
| `chave` | string | A mesma chave usada em kpis\[].lista, funil\[].lista, barras\[].lista… |
| `titulo` | string | Título do painel lateral de evidências. |
| `hint` | string | Texto de apoio abaixo do título. |
| `ids` | array | ids dos atendimentos, em ordem cronológica. O objeto completo está em painel.atendimentos (ou em atendimentos, no /v1/tela). |
| `badges` | object | Por id: label e tone do selo que a tela mostra ao lado da conversa. |
| `notas` | object | Por id: texto extra (por exemplo, o insight completo). |

Toda referência a atendimento nas telas é um **id** (`"2026-10-06:atend_12"`). Procure em `atendimentos` (ou em `painel.atendimentos`). O `id` é o mesmo em todas as listas e nos itens de insight.

### Tons e cores

`tone` aparece em kpis, badges, chips, funis e barras. São quatro valores; a cor de cada um está em `catalogo.tons`:

| tone | significado | cor padrão |
| --- | --- | --- |
| `ok` | dentro da meta ou bom | `#059669` |
| `warn` | atenção | `#d97706` |
| `bad` | fora da meta ou grave | `#dc2626` |
| `neutral` | informativo, sem juízo | `#64748b` |

Momentos e tipos de conversa têm cor própria (`catalogo.cores.momento`, `catalogo.cores.tipo`) e já vêm resolvidas em cada `rotulos`. As regras que escolhem o tom estão escritas em `catalogo.regras` (nota: ok ≥ 8, warn ≥ 6; percentual: ok ≥ meta, warn ≥ meta − 20).

### Campos `vazio`

Quando um bloco não tem o que mostrar, ele vem com `vazio` preenchido com a frase que a interface exibe ("Nenhuma matrícula confirmada neste recorte."). Quando há conteúdo, `vazio` é `null`. Mostre a frase no lugar do bloco.

## As nove telas

A ordem abaixo é a ordem dos blocos na interface.

### Resumo {#resumo}

`tela.resumo` — a primeira tela, visão do dono.

| Bloco | O que é |
| --- | --- |
| `kpis` | 4 cards: Episódios, Nota da recepção, Cadastro de novos ("9 de 13"), Graves. |
| `fluxo` | Chegaram → Pararam no balcão → Saíram com despedida (`etapas`, com cor), três linhas de meta (`metas`) e a frase de leitura (`insight`, pode ser null). |
| `balcao` | Quem parou no balcão: alunos de casa, novos, com cadastro, sem próximo passo — cada contagem com a `lista` que abre. |
| `matriculas` | Matrículas confirmadas: `n`, `ids` e `lista`. |
| `churn` | Cancelamento e congelamento: `n`, `cancelar`, `congelar`, `ids`. |
| `alertas` | "O que pede atenção": itens com `codigo`, `titulo`, `severidade` (alta/media) e `lista`. Quando não há alerta, `semAlerta` traz a frase. |
| `dono` | Quatro linhas de decisão: `planoNaoFechou`, `travouEntrada` (facial/catraca/aplicativo), `prometeuDiretoria` (temas), `totalpass` (barreira / explicou a diferença / só passou). |
| `insightsEmAberto` | Quantos insights estão abertos e o texto do atalho para a tela Insights. |
| `oportunidades` | "Oportunidades na fala": o que o cliente pediu, com `fato`, `insight`, `tom` e `lista`. |
| `agregadores` | Dois cards: Gympass e TotalPass. |
| `mix` | Onde a recepção falou (`partes` com percentual e cor) e os assuntos mais frequentes (`assuntos`). |
| `guia` | O que a recepção fez: linhas do guia de aluno (`aluno`) e de aluno novo (`novo`), cada uma com `valor` pronto ("57% (4/7)"). |
| `porHora` | Série por hora com entrada, atendimento, saída. |

### Entrada × Saída {#fluxo}

`tela.fluxo`

| Bloco | O que é |
| --- | --- |
| `avisoFormatoAntigo` | Frase de aviso quando o recorte tem análises no formato anterior; null normalmente. |
| `kpis` | Entradas, Balcão, Saídas, Saídas por entrada (tom pela proporção: ok ≥ 60%, warn ≥ 30%). |
| `colunas` | Três colunas (Entrada, Balcão, Saída), cada uma com `cor`, 3 `kpis` (Episódios, Nota, Guia), um `destaque` com meta (Saudação / Guia de aluno novo / Despedida) e as linhas do `guia`. |
| `porHora` | Série por hora por momento. |
| `entradasSemSaudacao`, `saidasSemDespedida` | ids das conversas a ouvir, ou `vazio`. |

### Qualidade {#qualidade}

`tela.qualidade`

| Bloco | O que é |
| --- | --- |
| `kpis` | 7 cards: Nota média, Nota na entrada, no balcão, na saída, Saudação na entrada, Despedida na saída, Objeções. |
| `guias` | Três tabelas do guia (entrada, balcão, saída), com cor do momento. |
| `graves` | ids dos graves para ouvir com a equipe. |
| `boasPraticas` | ids das conversas com nota 8 ou mais. |

### Acesso {#acesso}

`tela.acesso`

| Bloco | O que é |
| --- | --- |
| `kpis` | Entradas liberadas, Travou na porta, Resolveu na hora ("2 de 2"), TotalPass / Gympass. |
| `ondeTravou` | Barras Facial / Catraca / Aplicativo, cada uma com `hint` e `lista`. |
| `agregador` | Barras Não conseguiu entrar / Recepção mostrou o plano Sky / Só passou. |
| `travas` | Cada conversa que travou: `id`, `badge` (Resolveu na hora / Saiu sem resolver) e as `travas` com rótulo. |
| `cadastros` | Cadastros novos: `id`, `fotoFacial` e o selo "Foto do facial feita" quando houve. |

### Novos alunos {#comercial}

`tela.comercial`

| Bloco | O que é |
| --- | --- |
| `kpis` | Alunos novos atendidos, Com cadastro no balcão, Sem próximo passo, Guia de aluno novo. |
| `funil` | Etapas Atendidos → Visita → Cadastro → Com cadastro → Sem próximo passo, a frase `semCadastro` e os `motivos`. |
| `guiaNovos` | Linhas do guia de aluno novo. |
| `novos` | Cada aluno novo: `id`, `rotulo` (Matrícula · plano, Cadastro no balcão, Saiu sem próximo passo…), `motivo` e o checklist `guia` (item, label, ok). |
| `alunosDeCasa` | Alunos de casa no balcão: 3 kpis, ids de risco de churn e de demanda não resolvida. |
| `oportunidadesLista` | "Dinheiro deixado na recepção": conversas com oportunidade comercial. |

### Horários {#horarios}

`tela.horarios` — séries para o gráfico: `porHoraMomento` (entrada, atendimento, saída por hora), `porHora` (total por hora), `series` com label e cor de cada linha e `unidades` (quando o período cruza mais de uma).

### Protocolo de venda {#venda}

`tela.venda`

| Bloco | O que é |
| --- | --- |
| `titulo`, `texto` | Cabeçalho da tela. |
| `funil` | Conversas de venda → Apresentou o recorrente → Fechou plano. Cada etapa com `valor`, `base`, `pct`, `hint`, `tone` e `lista`. |
| `chips` | Ao lado do funil: "3 não fecharam" e "1 sem desfecho no áudio", com a lista de cada um. |
| `passos` | Os 7 passos do protocolo: `feitos`/`total`, `pct`, `meta`, ids em `fez` e `faltou`, e a `lista` que abre com o selo Fez / Deixou passar. |
| `planosCitados` | Barras por plano citado, cada uma com lista. |
| `objecoes` | Barras por objeção; a lista marca Respondeu / Sem resposta. |
| `conversas` | Cada conversa de venda: `quando`, `desfecho` (Fechou · plano / Não fechou / Sem desfecho no áudio), `badges`, `resumo`, `evidencia` (fala literal), `passos` com `fez` por passo e `proximoPasso`. |
| `catalogo` | O catálogo de planos da unidade, com o recorrente em destaque. |

### Renovação {#renovacao}

`tela.renovacao` — mesma estrutura da venda, aplicada a quem paga o Prime Mensal: `funil` (Alunos do mensal → Ouviram a oferta → Migraram), `passos` do roteiro de renovação, `argumento` (os números do Prime Mensal × Recorrente), `motivos` (por que não migrou) e `conversas` com desfecho Migrou pro recorrente / Ficou no mensal · motivo.

### Insights {#insights}

`tela.insights`

| Bloco | O que é |
| --- | --- |
| `kpis` | Risco de perder aluno, Pra fechar, Decisões suas — cada um com a lista. |
| `blocos` | Um por tipo (risco, pendencia, decisao) que tiver itens: `label`, `hint`, `tone`, `cor`, `contagem` ("3 conversas"), `repetidos` (o mesmo assunto em várias pessoas, com lista) e `itens` (cada conversa com `id`, `quando`, `quemLabel` "Você decide" / "Recepção liga", `titulo`, `fato`, `aberto`, `acao`). |

## Receitas

### Painel lateral de evidências

Ao clicar num kpi, funil, barra ou chip com `lista`, abra um painel com o título e as conversas:

```js
const r = await fetch(`${API}/v1/tela?Id_unidade=375&de=2026-10-06&ate=2026-10-06`, { headers })
const { tela, listas, atendimentos } = await r.json()
const porId = new Map(atendimentos.map((a) => [a.id, a]))

function abrirLista(chave) {
  const l = listas[chave]
  return {
    titulo: l.titulo,
    hint: l.hint,
    conversas: l.ids.map((id) => {
      const a = porId.get(id)
      return {
        quando: a.rotulos.quando,
        momento: a.rotulos.momento,       // { label: "Balcão", cor: "#7c3aed" }
        resumo: a.rotulos.resumo,
        chips: a.rotulos.chips,           // [{ label: "verificado no áudio", tone: "ok", hint }]
        badge: l.badges[id] ?? null,      // { label: "Cadastro no balcão", tone: "ok" }
        nota: l.notas[id] ?? null,
        audio: a.audio,                   // { url, duracao_s, partes } ou null
      }
    }),
  }
}

const graves = tela.resumo.kpis.find((k) => k.chave === 'graves')
if (graves.lista) abrirLista(graves.lista)
```

### Botão de ouvir

```js
async function tocar(a) {
  if (!a.audio) return
  const r = await fetch(`${API}${a.audio.url}?Id_unidade=375&de=2026-10-06&ate=2026-10-06`, { headers })
  const blob = await r.blob()
  const el = new Audio(URL.createObjectURL(blob))
  el.title = a.rotulos.play // "06/10 · 13:16:41 · Balcão"
  await el.play()
}
```

O WAV já vem só com o trecho da conversa e com documento e nome completo em silêncio. Detalhes em [Áudio](/guia/audio).

### Card de kpi

```js
function Card(k, cores) {
  return `<div class="card" ${k.lista ? 'role="button"' : ''}>
    <small>${k.label}</small>
    <strong style="color:${cores.tons[k.tone]}">${k.valor}</strong>
    ${k.hint ? `<span>${k.hint}</span>` : ''}
  </div>`
}
```

## O que não vem

Nenhuma referência a arquivo, caminho ou identificador interno de gravação. O que a interface mostra como "verificado no áudio" chega como o chip `verificado` em `rotulos.chips`, sem o laudo interno. Nome completo e documento não aparecem em texto nem em áudio.
