Exemplos
Exemplos completos de código em JavaScript, Python e cURL para casos de uso comuns da API Onvox AI.
Exemplos de Código
Todos os exemplos desta página usam os 4 únicos endpoints que aceitam autenticação por X-API-Key: POST /api/analyses, GET /api/salespersons, GET /api/analyses e GET /api/analyses/{id}. Detalhe completo de cada um em Endpoints. Operações como criar usuário ou consultar saldo de créditos não têm endpoint de API Key hoje; o acesso é feito apenas pelo painel web (sessão de navegador).
Criar Análise a partir de um arquivo local (base64)
Quando o áudio está no seu disco (não numa URL pública), codifique em base64 e envie como Data URL no campo audioKey:
const API_KEY = 'evai_your_key_here';
const BASE_URL = 'https://api.evolu-ai.com/api';
async function criarAnaliseDeArquivoLocal(caminhoArquivo, salespersonId) {
const fs = require('node:fs');
const buffer = fs.readFileSync(caminhoArquivo);
const base64 = buffer.toString('base64');
const dataUrl = `data:audio/mpeg;base64,${base64}`;
const res = await fetch(`${BASE_URL}/analyses`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({
salespersonId,
audioKey: dataUrl
})
});
return await res.json();
}Base64 aumenta o tamanho do payload em ~33%. Para arquivos grandes, prefira hospedar o áudio numa URL pública HTTPS temporária e usar o formato do exemplo abaixo (mais leve e mais rápido).
Criar Análise a partir de uma URL de áudio
curl -X POST 'https://api.evolu-ai.com/api/analyses' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: evai_your_key' \
-d '{
"salespersonId": "user_xxx",
"audioKey": "https://exemplo.com/audio.mp3"
}'Varrer o histórico e correlacionar com o seu sistema
GET /api/analyses é o único endpoint que varre o histórico: pagine por cursor até nextCursor vir null. Cada item traz externalCallId, que é a chave de correlação com o CDR do PABX.
const API_KEY = 'evai_your_key_here';
const BASE_URL = 'https://api.evolu-ai.com/api';
async function* varrerAnalises(filtros = {}) {
let cursor = null;
do {
const query = new URLSearchParams({ ...filtros, limit: '100' });
if (cursor) {
query.set('cursor', cursor);
}
const res = await fetch(`${BASE_URL}/analyses?${query}`, {
headers: { 'X-API-Key': API_KEY }
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${await res.text()}`);
}
const pagina = await res.json();
yield* pagina.items;
cursor = pagina.nextCursor;
} while (cursor);
}
// Setembro inteiro, só as concluídas, indexadas pelo id da chamada no PABX
const porChamada = new Map();
for await (const analise of varrerAnalises({
from: '2026-09-01T00:00:00Z',
to: '2026-09-30T23:59:59Z',
status: 'completed'
})) {
porChamada.set(analise.externalCallId, analise.displayScore);
}A listagem é um índice: não traz transcrição, áudio nem scorecard. Depois de achar o id aqui, busque o dossiê completo em GET /api/analyses/{id} (exemplo abaixo), só para as análises que você realmente vai abrir.
Achar a análise de uma chamada específica do PABX
curl -s 'https://api.evolu-ai.com/api/analyses?externalCallId=yeastar:1694000000.123' \
-H 'X-API-Key: evai_your_key'Devolve {"items": [...], "nextCursor": null, "hasMore": false} com zero ou um item, já que externalCallId é único por empresa.
Buscar uma análise pelo ID
const API_KEY = 'evai_your_key_here';
const res = await fetch('https://api.evolu-ai.com/api/analyses/anal_xxx', {
headers: { 'X-API-Key': API_KEY }
});
const analise = await res.json();
console.log(`Score: ${analise.displayScore} | Status: ${analise.status}`); // displayScore = nota oficialConfigurar e receber Webhooks
Documentação completa (payload por papel, verificação de assinatura em JS e Python, retry/backoff) em Webhooks.
Ao contrário dos outros exemplos desta página, analysisWebhooks.create não é chamável com X-API-Key: é uma adminProcedure (sessão de navegador), configurada pela tela Configurações → Webhooks de Análise, não por integração externa. O trecho abaixo é só o lado RECEPTOR (o que roda no SEU servidor para verificar a assinatura de cada entrega).
// No seu endpoint receptor: verificar a assinatura antes de processar
const crypto = require('node:crypto');
function verifyOnvoxAiWebhook(secret, timestamp, rawBody, signatureHeader) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const received = signatureHeader.replace(/^sha256=/, '');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(received, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Tipos TypeScript
Os tipos abaixo cobrem os campos principais da resposta de POST /api/analyses. GET /api/analyses/{id} devolve um objeto bem maior (dossiê completo com diagnóstico, indicadores universais, transcrição e custo). Veja a lista completa em Endpoints.
interface Analysis {
id: string;
score: number | null;
summary: string | null;
clientName?: string | null;
salespersonName?: string | null;
audioDurationSeconds?: number | null;
profile?: string | null;
stage?: string | null;
bant?: {
budget: string;
authority: string;
need: string;
timing: string;
} | null;
objections?: Array<{
objection: string;
resolved: boolean;
}> | null;
dimensionScores?: {
rapport: number;
listening: number;
objections: number;
clarity: number;
} | null;
interactionType?: string | null;
interactionScore?: number | null;
interactionScorecard?: Record<string, unknown> | null; // critérios do tipo de interação, ver Endpoints
productExploration?: { explored: boolean; products: string[] } | null;
keywordDetection?: Record<string, unknown> | null;
publicLink?: string;
createdAt: string;
}
interface Salesperson {
id: string;
name: string;
role: 'salesperson' | 'supervisor';
supervisorName: string | null;
}
// Resposta de GET /api/analyses (listagem, índice): conjunto FECHADO de campos.
interface AnalysisListItem {
id: string;
createdAt: string;
updatedAt: string;
status: 'pending' | 'processing' | 'completed' | 'failed';
source: string;
provider: string | null;
externalCallId: string | null;
externalOwnerId: string | null;
companyId: string | null;
salespersonId: string | null;
salespersonName: string | null;
supervisorName: string | null;
clientName: string | null;
displayScore: number | null;
score: number | null;
interactionScore: number | null;
interactionType: string | null;
interactionTypeSource: string | null;
interactionTypeLabel: string | null;
summary: string | null;
audioDurationSeconds: number | null;
attributionStatus: string;
}
interface AnalysisListPage {
items: AnalysisListItem[];
nextCursor: string | null;
hasMore: boolean;
}Endpoints
Referência completa dos endpoints REST públicos disponíveis para integrações externas via API Key.
Webhooks
Receba um POST assinado quando uma análise é concluída — UI, API externa ou coleta de integração (esta última configurável por destino) —, com payload reduzido por papel, verificação de assinatura HMAC-SHA256 e política de retry.