Integre análise emocional de voz ao seu produto
Envie áudio, consulte o status da análise e baixe o relatório normalizado a partir do seu próprio backend. A mesma inteligência usada pelo portal da Voice Feeling, exposta como API REST.
De um arquivo de áudio a um relatório
Quatro chamadas cobrem o fluxo completo: criar a análise, consultar seu status e baixar o relatório normalizado quando terminar.
Criar uma análise enviando o arquivo
Envie o áudio como multipart/form-data. `consentObtained=true` é obrigatório: confirma que você tem consentimento ou base legal para analisar a gravação.
curl https://voice-feeling.pages.dev/api/v1/analyses \ -H "Authorization: Bearer vf_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Idempotency-Key: 5f3d2b7e-9c2e-4f6a-9c0e-1a2b3c4d5e6f" \ -F "file=@call.wav" \ -F "consentObtained=true" \ -F "businessContext=sales"Criar uma análise a partir de uma URL
Se o áudio já está hospedado na sua infraestrutura, envie JSON com `audioUrl` em vez de enviar o arquivo. O mesmo `consentObtained: true` continua obrigatório.
curl https://voice-feeling.pages.dev/api/v1/analyses \ -H "Authorization: Bearer vf_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Idempotency-Key: 5f3d2b7e-9c2e-4f6a-9c0e-1a2b3c4d5e6f" \ -H "Content-Type: application/json" \ -d '{ "audioUrl": "https://cdn.example.com/calls/2026-09-03-0142.wav", "consentObtained": true, "businessContext": "service" }'Consultar o status
A análise passa por vários estados até `completed` ou `failed`. Faça polling com backoff ou registre um webhook para ser avisado.
curl https://voice-feeling.pages.dev/api/v1/analyses/an_9f3c2e1a \ -H "Authorization: Bearer vf_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # { # "id": "an_9f3c2e1a", # "status": "completed", # "businessContext": "service", # "createdAt": "2026-09-03T14:02:11Z", # "completedAt": "2026-09-03T14:03:47Z", # "reportUrl": "/api/v1/analyses/an_9f3c2e1a/report" # }Baixar o relatório normalizado
Disponível apenas quando a análise está `completed`. O relatório segue o contrato `voicefeeling.report.v1` e nunca contém a resposta bruta do provedor.
curl https://voice-feeling.pages.dev/api/v1/analyses/an_9f3c2e1a/report \ -H "Authorization: Bearer vf_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Envie um cabeçalho `Idempotency-Key` em `POST /analyses` para que novas tentativas de rede não dupliquem a análise.
Chaves de API e scopes
Autentique cada solicitação com uma chave de API no cabeçalho Authorization. Crie e gerencie suas chaves pelo portal, na seção Desenvolvedores.
- Cabeçalho obrigatório
Authorization: Bearer vf_live_<prefix>_<secret>- Formato da chave
- vf_live_<prefixo>_<segredo>. O prefixo identifica a chave nos registros; o segredo só é exibido uma vez, na criação.
Scopes disponíveis
Cada chave declara os scopes que precisa. Uma solicitação sem o scope necessário recebe `api_scope_missing` com o scope faltante na resposta.
analyses:readConsultar análises, seu status e o relatório normalizado.analyses:writeCriar análises a partir de um arquivo enviado ou de uma URL.audios:writeEnviar arquivos de áudio como parte da criação de uma análise.webhooks:manageRegistrar, listar e excluir endpoints de webhook.usage:readConsultar o consumo da organização em relação aos seus limites.
Novas tentativas seguras
Toda entrega pode se repetir: se sua solicitação de rede falhar sem uma resposta clara, reenvie-a com o mesmo cabeçalho `Idempotency-Key`. Se a chave já foi usada com um corpo diferente, a API responde `idempotency_conflict` em vez de criar uma segunda análise.
Notificações de eventos
Em vez de fazer polling, registre um endpoint HTTPS para receber eventos quando uma análise terminar.
Eventos disponíveis
analysis.completedA análise terminou e o relatório normalizado está disponível.analysis.failedA análise terminou em erro após esgotar as tentativas.
Formato do payload
Cada entrega é um POST em JSON com cabeçalhos de identificação e assinatura.
POST https://your-domain.com/webhooks/voicefeeling
Content-Type: application/json
Voice-Feeling-Event: analysis.completed
Voice-Feeling-Signature: t=1756900931,v1=4b1f9e...c2a0
{
"event": "analysis.completed",
"analysisId": "an_9f3c2e1a",
"createdAt": "2026-09-03T14:03:47Z"
}Verifique a assinatura
Calcule o HMAC-SHA256 do timestamp e do corpo com seu segredo, e compare com a assinatura recebida antes de confiar no payload. Rejeite entregas com mais de 5 minutos de diferença entre o timestamp e seu relógio.
const crypto = require("node:crypto");
function isValidSignature(header, rawBody, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(
header.split(",").map((part) => part.split("="))
);
const timestamp = Number(parts.t);
if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) {
return false;
}
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 || ""));
}Novas tentativas e desativação
Entregas com falha são reenviadas com backoff exponencial por cerca de uma hora. Um endpoint com 20 falhas consecutivas é desativado automaticamente; reative-o excluindo e registrando-o novamente pelo portal.
Códigos de erro
Toda resposta de erro usa o mesmo envelope: `{ "error": { "code", "message", "docs_url" } }`. Construa sua integração em torno de `code`, não de `message`, que pode mudar de idioma conforme `Accept-Language`.
| CÓDIGO | HTTP | DESCRIÇÃO |
|---|---|---|
api_key_invalid | 401 | A chave não existe ou não corresponde a nenhuma chave registrada. |
api_key_expired | 401 | A chave tinha uma data de expiração que já passou. |
api_key_revoked | 401 | A chave foi revogada pelo portal. |
api_scope_missing | 403 | A chave não tem o scope necessário; a resposta inclui `required_scope`. |
api_rate_limited | 429 | O limite de solicitações por chave foi excedido; respeite o cabeçalho `Retry-After`. |
api_disabled | 503 | A API pública está desativada neste ambiente. |
consent_required | 422 | Falta `consentObtained: true` na solicitação de criação da análise. |
audio_url_invalid | 422 | `audioUrl` não é uma URL https válida e pública. |
audio_download_failed | 422 | Não foi possível baixar o áudio a partir de `audioUrl`. |
unsupported_audio_content | 415 | O conteúdo do arquivo não corresponde a um formato de áudio suportado. |
audio_too_large | 413 | O arquivo excede o limite de tamanho permitido. |
monthly_analysis_quota_exceeded | 429 | A cota mensal de análises do plano foi atingida. |
daily_upload_quota_exceeded | 429 | A cota diária de envios do plano foi atingida. |
storage_quota_exceeded | 413 | O armazenamento da organização atingiu seu limite. |
idempotency_conflict | 409 | A `Idempotency-Key` já foi usada com um corpo de solicitação diferente. |
analysis_not_found | 404 | Não existe uma análise com esse id para esta organização. |
report_requires_final | 409 | A análise ainda não terminou; o relatório não está disponível. |
webhook_url_invalid | 422 | A URL do webhook não é uma URL https válida e pública. |
webhook_endpoint_not_found | 404 | Não existe um endpoint de webhook com esse id para esta organização. |
webhook_limit_reached | 409 | O número máximo de endpoints de webhook por organização foi atingido. |
Limites técnicos
Projete sua integração considerando estes limites; excedê-los produz o código de erro correspondente, não um corte silencioso.
- Frequência de solicitações
- 120 solicitações / 10 minutos por chave
- Tamanho máximo do áudio
- 50 MiB por arquivo
- Formatos suportados
- WAV, MP3, M4A, OGG, FLAC, WebM, AAC, AIFF
A Voice Feeling mede sinais acústicos (energia, tensão, ritmo) correlacionados a estados emocionais. Eles não são fatos psicológicos, não determinam intenção e nunca constituem um veredito de verdade ou mentira. Qualquer decisão que afete uma pessoa deve combinar isso com contexto humano e as políticas da sua organização.
