API v1

Voz dentro do seu produto.

Streaming por WebSocket, webhooks assinados e SDKs para JavaScript, Python e Go. O contrato é estável e versionado, e o OpenAPI está aberto antes de você ter uma chave.

v1contrato estável
WebSockete REST
MCPpara a sua própria IA
const ws = new WebSocket(
  "wss://api.voicespeak.app/v1/transcrever" +
  "?idioma=pt-BR&locutores=auto&vocabulario=empresa",
  ["bearer", process.env.VOICESPEAK_KEY]
)

ws.onmessage = (e) => {
  const t = JSON.parse(e.data)
  if (t.tipo === "parcial") mostrarProvisorio(t.texto)
  if (t.tipo === "final")   gravar(t.locutor, t.texto, t.inicio_ms)
}

// PCM 16 bits, 16 kHz, mono, pedaços de 20 ms
microfone.on("data", (pcm) => ws.send(pcm))
const r = await fetch("https://api.voicespeak.app/v1/falar", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${chave}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    voz: "helena",
    formato: "mp3_44100",
    tom: "acolhedor, sem pressa",
    texto: "Seu certificado está pronto para retirada."
  })
})

const audio = await r.arrayBuffer()
import hmac, hashlib
from flask import Flask, request

app = Flask(__name__)

@app.post("/hooks/voicespeak")
def receber():
    corpo = request.get_data()
    esperado = "sha256=" + hmac.new(
        SEGREDO.encode(), corpo, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(
        esperado, request.headers.get("x-voicespeak-signature", "")
    ):
        return "", 401          # nunca confie sem validar

    evento = request.get_json()
    if evento["evento"] == "interacao.resumida":
        anexar_na_oportunidade(evento)
    return "", 204

Autenticação

Toda chamada leva a chave no cabeçalho Authorization. A chave começa com sk_live_ (ou sk_test_, no ambiente de teste) e aparece uma única vez, no momento em que você a cria. Guardamos apenas o hash.

Emita uma chave por integração. Revogar a chave do seu CRM não deve derrubar o widget do site, e só é possível separar as duas coisas se elas nunca compartilharam a mesma chave.

curl https://api.voicespeak.app/v1/quem-sou-eu \
  -H "Authorization: Bearer sk_live_…"

{
  "conta": "Biz Certificadora Digital",
  "chave": { "nome": "CRM produção", "criada_em": "2026-07-02" },
  "escopos": ["conversas:read", "interacoes:read", "webhooks:write"],
  "plano": "pro"
}

Os três conceitos

A API inteira gira em torno de três objetos. Entender a relação entre eles poupa a maior parte das dúvidas.

ObjetoO que éVocê o usa para
CanalPor onde a voz entra e sai: um número de telefone, uma linha de WhatsApp, um widget no seu site.Provisionar o widget, definir o teto de conversas simultâneas e escolher quem atende.
ConversaUm atendimento do começo ao fim, em qualquer canal, com todas as falas, a gravação e o desfecho.Ler a transcrição, baixar o áudio, saber se o objetivo foi atingido.
InteraçãoO material escrito depois da conversa: resumo, o que ficou combinado, próximo passo e leitura de interesse.Anexar na oportunidade do CRM sem reler a transcrição inteira.

Rotas

As principais. A lista completa, com todos os parâmetros e exemplos de resposta, está no OpenAPI.

RotaO que fazEscopo
POST /v1/transcreverTranscreve um arquivo enviado. Para tempo real, use o WebSocket abaixo.conversas:read
POST /v1/falarSintetiza fala. Devolve o arquivo ou abre o fluxo.mensagens:write
POST /v1/legendasGera SRT, VTT ou ASS de um áudio ou vídeo.conversas:read
POST /v1/dublarDubla para um ou mais idiomas preservando o timbre.conversas:read
GET /v1/conversasLista atendimentos com filtro por pessoa, canal, período e desfecho.conversas:read
GET /v1/interacoesOs resumos escritos depois de cada conversa.interacoes:read
GET /v1/ligacoes/{id}/gravacaoURL assinada do áudio, válida por 15 minutos.conversas:read
POST /v1/canaisProvisiona um canal, inclusive o widget de voz do seu site.canais:write
POST /v1/voz-web/sessaoAbre uma conversa já sabendo quem é o visitante.voz_web:sessao
PUT /v1/embed/origensDefine quais domínios podem embutir o widget. Substitui a lista inteira.discador:embed
POST /v1/vocabularioCadastra termos com grafia e pronúncia.agentes:write
POST /v1/webhooksRegistra um destino e assina eventos.webhooks:write
GET /v1/usoConsumo do ciclo: minutos, caracteres e chamadas.uso:read

Escopos

Uma chave carrega apenas os escopos marcados na criação. Chamar uma rota fora do escopo devolve 403 com o escopo que faltou, não um 404 genérico que faz você procurar erro de digitação na URL.

EscopoPermite
conversas:readLer atendimentos, transcrições e gravações; enviar áudio para transcrever.
interacoes:readLer os resumos escritos após cada conversa.
mensagens:writeSintetizar fala e enviar mensagens.
contatos:read · contatos:writeLer e manter a base de pessoas atendidas.
canais:read · canais:writeVer e provisionar canais, incluindo o widget de voz.
agentes:read · agentes:writeConfigurar agentes, roteiros e vocabulário.
numeros:read · numeros:writeComprar, atribuir e liberar números de telefone.
webhooks:read · webhooks:writeVer entregas e registrar destinos.
voz_web:sessaoAbrir conversa no site já identificando o visitante.
discador:embedEmitir o bilhete do discador embutido e gerir os domínios autorizados.
uso:readConsultar consumo e limites do ciclo.
empresas:read · usuarios:readLer estrutura da conta e pessoas. Só faz sentido para quem opera várias contas.

Streaming

Tempo real usa WebSocket. O áudio sobe em PCM 16 bits, 16 kHz, mono, em pedaços de 20 ms, o mesmo tamanho de quadro que a telefonia usa, porque é o que mantém a detecção de fala precisa sem inundar a rede.

Duas mensagens voltam: parcial, que muda enquanto a pessoa fala e serve para mostrar na tela, e final, que não muda mais e é a que você guarda. Tratar parcial como final é o erro mais comum de quem integra pela primeira vez, o texto pisca e a última palavra troca sozinha.

// mensagens que chegam pelo socket
{ "tipo": "parcial", "texto": "fechamos o mês com quatro" }
{ "tipo": "parcial", "texto": "fechamos o mês com quatrocentos e doze" }
{ "tipo": "final",
  "texto": "Fechamos o mês com 412 certificados emitidos.",
  "locutor": "L1", "inicio_ms": 4120, "fim_ms": 7480,
  "confianca": 0.97 }

// e no fim
{ "tipo": "encerrado", "duracao_ms": 2547310,
  "conversa_id": "254f1b8d-…" }

Erros e limites

Todo erro traz um codigo estável para o seu switch e uma mensagem em português para o seu log. O código é o contrato; a mensagem pode melhorar com o tempo.

HTTPCódigoO que fazer
401CHAVE_INVALIDAA chave não existe ou foi revogada. Emita outra no painel.
403ESCOPO_AUSENTEA resposta diz qual escopo faltou. Emita uma chave com ele.
409CANAL_JA_VINCULADOAquele canal já tem responsável. Libere antes de vincular outro.
413ARQUIVO_GRANDEAcima de 500 MB por envio. Divida ou use o streaming.
422AUDIO_ILEGIVELFormato não reconhecido ou faixa vazia. O corpo diz o que foi detectado.
429LIMITE_EXCEDIDORespeite o Retry-After. Os SDKs já fazem isso sozinhos.
503SEM_CAPACIDADETeto de conversas simultâneas atingido. Tente de novo ou aumente o teto.

SDKs e MCP

Os SDKs cuidam de autenticação, novas tentativas com espera progressiva, streaming e validação de webhook, que é justamente onde a maioria dos erros acontece. Para as demais linguagens, gere o cliente a partir do OpenAPI.

npm install @voicespeak/sdk

import { VoiceSpeak } from "@voicespeak/sdk"

const vs = new VoiceSpeak({ chave: process.env.VOICESPEAK_KEY })

const { texto } = await vs.transcrever({ arquivo: "./reuniao.m4a" })
const ok = vs.webhooks.validar(corpoCru, assinatura, segredo)
pip install voicespeak

from voicespeak import Cliente

vs = Cliente()   # lê VOICESPEAK_KEY do ambiente

r = vs.transcrever(arquivo="reuniao.m4a", locutores="auto")
for trecho in r.trechos:
    print(trecho.locutor, trecho.texto)
go get github.com/voicespeak/go-sdk

cliente := voicespeak.Novo(os.Getenv("VOICESPEAK_KEY"))

r, err := cliente.Transcrever(ctx, voicespeak.Pedido{
    Arquivo:   "reuniao.m4a",
    Idioma:    "pt-BR",
    Locutores: "auto",
})
# a SUA IA descobre e usa as ferramentas do VoiceSpeak
# mesmos escopos, mesma auditoria da API

{
  "mcpServers": {
    "voicespeak": {
      "url": "https://api.voicespeak.app/v1/mcp",
      "headers": { "Authorization": "Bearer sk_live_…" }
    }
  }
}

# ferramentas expostas: transcrever, falar, buscar_conversas,
# resumir, voz_web_sessao, a lista é gerada do catálogo do servidor.

Perguntas frequentes

Onde fica a referência completa?
Em https://api.voicespeak.app/v1/openapi.json. É contrato de máquina: gere o cliente a partir dele em vez de escrever à mão. Ele cobre só a API pública, as rotas internas do painel ficam de fora de propósito, porque documentá-las ensinaria você a chamar o que muda na próxima refatoração de tela.
Como as chaves funcionam?
A chave começa com sk_live_ e é mostrada uma única vez, na criação. Guardamos só o hash, não conseguimos recuperá-la para você, apenas emitir outra. Cada chave carrega os escopos que você marcou, e o certo é emitir uma por integração: revogar uma não derruba as outras.
A chave pode ir no meu JavaScript?
Não. Com a chave no navegador, qualquer visitante age em nome da sua conta. Para casos que precisam de algo no cliente (o widget de voz, o discador embutido), o seu backend troca a chave por um bilhete de curta duração e uso único, e é ele que viaja.
Existem limites de chamada?
Existem, por conta e por rota, e a resposta sempre diz onde você está: X-RateLimit-Remaining e Retry-After. Ao estourar você recebe 429, nunca uma resposta parcial silenciosa. Os tetos acompanham o plano e são negociáveis no Business.
Há SDK oficial?
Para JavaScript/TypeScript, Python e Go. Eles cuidam de autenticação, novas tentativas com espera progressiva, streaming e validação de webhook, que é onde a maioria dos erros acontece. Para as outras linguagens, gere o cliente a partir do OpenAPI.
Dá para conectar a minha própria IA às ferramentas do VoiceSpeak?
Dá. Além do REST, expomos um servidor MCP: o seu assistente descobre as ferramentas disponíveis e as chama diretamente, com os mesmos escopos e a mesma auditoria da API. É como um agente do seu lado abre uma conversa por voz com quem já está na frente dele.
Existe ambiente de teste?
Existe: chaves sk_test_ operam sobre dados isolados, com áudio sintético e webhooks reais. Nada do que acontece ali toca a sua conta de produção, e nada é cobrado.

A chave sai em dois minutos

Crie a conta, emita uma chave de teste e chame /v1/quem-sou-eu. Se isso funcionar, o resto é ler a tabela acima.