API PARA DESENVOLVEDORES

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.

01 / INÍCIO RÁPIDO

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.

  1. 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"
  2. 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"
      }'
  3. 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"
    # }
  4. 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.

02 / AUTENTICAÇÃO

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.

03 / IDEMPOTÊNCIA

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.

04 / WEBHOOKS

Notificações de eventos

Em vez de fazer polling, registre um endpoint HTTPS para receber eventos quando uma análise terminar.

Eventos disponíveis

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.

05 / ERROS

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ÓDIGOHTTPDESCRIÇÃO
api_key_invalid401A chave não existe ou não corresponde a nenhuma chave registrada.
api_key_expired401A chave tinha uma data de expiração que já passou.
api_key_revoked401A chave foi revogada pelo portal.
api_scope_missing403A chave não tem o scope necessário; a resposta inclui `required_scope`.
api_rate_limited429O limite de solicitações por chave foi excedido; respeite o cabeçalho `Retry-After`.
api_disabled503A API pública está desativada neste ambiente.
consent_required422Falta `consentObtained: true` na solicitação de criação da análise.
audio_url_invalid422`audioUrl` não é uma URL https válida e pública.
audio_download_failed422Não foi possível baixar o áudio a partir de `audioUrl`.
unsupported_audio_content415O conteúdo do arquivo não corresponde a um formato de áudio suportado.
audio_too_large413O arquivo excede o limite de tamanho permitido.
monthly_analysis_quota_exceeded429A cota mensal de análises do plano foi atingida.
daily_upload_quota_exceeded429A cota diária de envios do plano foi atingida.
storage_quota_exceeded413O armazenamento da organização atingiu seu limite.
idempotency_conflict409A `Idempotency-Key` já foi usada com um corpo de solicitação diferente.
analysis_not_found404Não existe uma análise com esse id para esta organização.
report_requires_final409A análise ainda não terminou; o relatório não está disponível.
webhook_url_invalid422A URL do webhook não é uma URL https válida e pública.
webhook_endpoint_not_found404Não existe um endpoint de webhook com esse id para esta organização.
webhook_limit_reached409O número máximo de endpoints de webhook por organização foi atingido.
06 / LIMITES

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
Uso responsável dos sinais acústicos

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.