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.
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 "", 204Autenticaçã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.
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.
| Objeto | O que é | Você o usa para |
|---|---|---|
| Canal | Por 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. |
| Conversa | Um 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ção | O 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.
| Rota | O que faz | Escopo |
|---|---|---|
POST /v1/transcrever | Transcreve um arquivo enviado. Para tempo real, use o WebSocket abaixo. | conversas:read |
POST /v1/falar | Sintetiza fala. Devolve o arquivo ou abre o fluxo. | mensagens:write |
POST /v1/legendas | Gera SRT, VTT ou ASS de um áudio ou vídeo. | conversas:read |
POST /v1/dublar | Dubla para um ou mais idiomas preservando o timbre. | conversas:read |
GET /v1/conversas | Lista atendimentos com filtro por pessoa, canal, período e desfecho. | conversas:read |
GET /v1/interacoes | Os resumos escritos depois de cada conversa. | interacoes:read |
GET /v1/ligacoes/{id}/gravacao | URL assinada do áudio, válida por 15 minutos. | conversas:read |
POST /v1/canais | Provisiona um canal, inclusive o widget de voz do seu site. | canais:write |
POST /v1/voz-web/sessao | Abre uma conversa já sabendo quem é o visitante. | voz_web:sessao |
PUT /v1/embed/origens | Define quais domínios podem embutir o widget. Substitui a lista inteira. | discador:embed |
POST /v1/vocabulario | Cadastra termos com grafia e pronúncia. | agentes:write |
POST /v1/webhooks | Registra um destino e assina eventos. | webhooks:write |
GET /v1/uso | Consumo 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.
| Escopo | Permite |
|---|---|
conversas:read | Ler atendimentos, transcrições e gravações; enviar áudio para transcrever. |
interacoes:read | Ler os resumos escritos após cada conversa. |
mensagens:write | Sintetizar fala e enviar mensagens. |
contatos:read · contatos:write | Ler e manter a base de pessoas atendidas. |
canais:read · canais:write | Ver e provisionar canais, incluindo o widget de voz. |
agentes:read · agentes:write | Configurar agentes, roteiros e vocabulário. |
numeros:read · numeros:write | Comprar, atribuir e liberar números de telefone. |
webhooks:read · webhooks:write | Ver entregas e registrar destinos. |
voz_web:sessao | Abrir conversa no site já identificando o visitante. |
discador:embed | Emitir o bilhete do discador embutido e gerir os domínios autorizados. |
uso:read | Consultar consumo e limites do ciclo. |
empresas:read · usuarios:read | Ler 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.
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.
| HTTP | Código | O que fazer |
|---|---|---|
| 401 | CHAVE_INVALIDA | A chave não existe ou foi revogada. Emita outra no painel. |
| 403 | ESCOPO_AUSENTE | A resposta diz qual escopo faltou. Emita uma chave com ele. |
| 409 | CANAL_JA_VINCULADO | Aquele canal já tem responsável. Libere antes de vincular outro. |
| 413 | ARQUIVO_GRANDE | Acima de 500 MB por envio. Divida ou use o streaming. |
| 422 | AUDIO_ILEGIVEL | Formato não reconhecido ou faixa vazia. O corpo diz o que foi detectado. |
| 429 | LIMITE_EXCEDIDO | Respeite o Retry-After. Os SDKs já fazem isso sozinhos. |
| 503 | SEM_CAPACIDADE | Teto 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 ambienter = 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?
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?
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?
Existem limites de chamada?
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?
Dá para conectar a minha própria IA às ferramentas do VoiceSpeak?
Existe ambiente de teste?
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.