Tema
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/audioUm 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
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
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
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
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
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
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
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
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
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.
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.
