🎁 Novo Cadastre-se grátis, 10 chamadas por nossa conta. Até US$ 1, sem cartão.

Fala para texto

POST /v1/audio/transcriptions

Transcreve áudio em texto. Compatível com a API OpenAI Audio Transcriptions — o mesmo endpoint atende aos modelos OpenAI Whisper / GPT-4o-transcribe e aos modelos Google Gemini, e o gateway roteia para o upstream correto pelo ID do modelo. Aceita tanto um multipart/form-data (compatível com o SDK da OpenAI) ou um corpo application/json com áudio codificado em base64.

Corpo da requisição

ParâmetroTipoDescrição
model*stringID do modelo de transcrição (ex.: whisper-1, gpt-4o-transcribe, chirp-3, seed-asr-bigmodel, fun-asr, qwen3-asr-flash). Consulte “Modelos suportados” abaixo.
file*fileapenas multipart — o arquivo de áudio a transcrever. Obrigatório, a menos que input_audio seja fornecido (JSON).
input_audio*objectApenas JSON — { "data": "<base64>", "format": "mp3" }, ou { "url": "<fetchable URL>" } para modelos offline (seed-asr-bigmodel). Use no lugar de file para requisições application/json.
response_formatstringFormato de saída: json (padrão; retorna {text, usage}), text (string de transcrição bruta), verbose_json (segmentos com carimbos de tempo), diarized_json (segmentos rotulados por falante — diarização de falantes). Os valores permitidos dependem do modelo; consulte “Formatos de resposta” abaixo.
languagestringDica ISO-639-1 opcional (ex.: "en") para melhorar a precisão e a latência.
promptstringTexto opcional para orientar o estilo de transcrição / a grafia de nomes próprios.
temperaturenumberTemperatura de amostragem 0–1. Padrão: 0.
streambooleanSe true, retorna eventos SSE de transcrição parcial (suportado em gpt-4o-transcribe e Gemini). Padrão: false.
providerobjectConfiguração de pass-through do provider. Veja Pass-through do provider abaixo.

Modelos suportados

Não sabe qual modelo escolher? Escolha conforme sua necessidade

Você precisaAtive comModelos recomendados
Chinês / cantonês, baixo custo seed-asr-bigmodel fun-asr
Inglês, alta qualidade gpt-4o-transcribe chirp-3
Diarização de falantes — quem disse o quê response_format=diarized_json seed-asr-bigmodel chirp-3 gpt-4o-transcribe-diarize
Marcações de tempo por palavra response_format=verbose_json whisper-1
Legendas em tempo real (enquanto você fala) stream=true gpt-4o-transcribe
Gravações longas / reuniões pass a public URL in input_audio.url seed-asr-bigmodel fun-asr
ModeloProvedor · cobrançaEntradaDiarizaçãoStreamingIdeal para
whisper-1 OpenAI · $0.006/min file Marcações de tempo por palavra (verbose_json); o idioma deve ser ISO-639-1
gpt-4o-transcribe OpenAI · token file Inglês, alta precisão; suporta streaming
gpt-4o-mini-transcribe OpenAI · token file Multilíngue mais barato; suporta streaming
gpt-4o-transcribe-diarize OpenAI · token file Diarização em inglês; known_speaker_names opcional
chirp-3 Google · $0.016/min file Alta qualidade; chamada única ≤60 s
chirp-2 Google · $0.016/min file USM multilíngue; use chirp-3 para diarização
seed-asr-bigmodel BytePlus · $0.002/min URL / file Chinês, gravações longas; o mais barato
fun-asr Alibaba · $0.0021/min URL / file Chinês · cantonês · dialetos; gravações longas
fun-asr-mtl Alibaba · $0.0021/min URL / file Multilíngue + diarização
fun-asr-flash Alibaba · $0.0021/min file Multilíngue rápido; ≤10 MB, síncrono
qwen3-asr-flash Alibaba · $0.0021/min file Multilíngue; ≤5 min/chamada, cobrança exata

Diarization = defina response_format=diarized_json para obter segments[].speaker. Limite de upload padrão 25 MB (ver Formatos de áudio).

Os modelos do Google podem ser servidos via API Gemini ou, com uma chave de conta de serviço BYOK do Vertex, via Google Cloud Vertex AI. A disponibilidade depende dos canais habilitados para o seu espaço de trabalho — chame /v1/models para ver o que você pode usar.

Armadilhas comuns. (1) Streaming (stream=true) funciona apenas em gpt-4o-transcribe / gpt-4o-mini-transcribe — todos os outros modelos retornam 400. (2) input_audio.url (entrada por URL) é suportado somente por seed-asr-bigmodel; todos os demais modelos exigem um upload de file ou base64. (3) O parâmetro language nos modelos da OpenAI (whisper-1, gpt-4o-*) deve ser um código ISO-639-1 como en ou zh — códigos de locale como yue-CN são rejeitados; Chirp / Seed ASR / Qwen aceitam códigos de locale, ou omita language para detecção automática. (4) Se o áudio exceder o limite por requisição de um modelo, divida-o em partes — ou use seed-asr-bigmodel (via URL) para gravações longas (~20 min/requisição). (5) Áudio silencioso / sem fala retorna 200 com uma string vazia {"text":""}, e não um erro.

Formatos de áudio suportados

  • mp3
  • wav
  • ogg
  • flac
  • m4a

Para uploads multipart, o formato é inferido da extensão do nome do arquivo. Para solicitações base64 (JSON), defina input_audio.format explicitamente. Tamanho máximo de upload: 25 MB.

Formatos de resposta

O valor response_format os valores aceitos dependem do modelo. json é o padrão para todos os modelos (retorna { text, usage }); text retorna a string bruta da transcrição.

  • whisper-1json, text, verbose_json
  • gpt-4o-transcribe, gpt-4o-mini-transcribejson, text
  • chirp-3, chirp-2, seed-asr-bigmodel, qwen3-asr-flash, fun-asr-flashjson, text
  • gpt-4o-transcribe-diarize, chirp-3, seed-asr-bigmodel, fun-asr, fun-asr-mtl — also diarized_json (segmentos rotulados por falante; ver abaixo)

verbose_json (timestamps de segmentos) é exclusivo do whisper-1;

Diarização de locutores

Defina response_format=diarized_json para obter segmentos rotulados por falante — a resposta adiciona um array segments em que cada entrada carrega um rótulo speaker além de marcações de tempo start/end (em segundos). Suportado em gpt-4o-transcribe-diarize (OpenAI), chirp-3 (Google), seed-asr-bigmodel (BytePlus — melhor custo-benefício para chinês e gravações longas) e fun-asr / fun-asr-mtl (Alibaba — arquivo de gravação offline, aceita uma URL ou arquivo). Outros modelos ignoram diarized_json e retornam texto simples; chirp-2 o rejeita (use chirp-3).

Os rótulos de falante são nativos do provedor (por exemplo, "0"/"1" para chirp-3 e seed-asr, "A"/"B" para gpt-4o-transcribe-diarize); eles identificam falantes distintos, mas não são identidades reais estáveis. No gpt-4o-transcribe-diarize você pode passar known_speaker_names para orientar a rotulagem.

# Chinese meeting, cheapest diarization (BytePlus seed-asr):
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seed-asr-bigmodel",
    "input_audio": { "url": "https://your-bucket/signed/meeting.wav", "language": "zh" },
    "response_format": "diarized_json"
  }'

# English / highest quality (Google chirp-3, <=60 s per request):
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=chirp-3 \
  -F file=@call.wav \
  -F response_format=diarized_json

Exemplo de resposta

{
  "task": "transcribe",
  "text": "喂 你好 我这边是客服 有什么可以帮您",
  "duration": 6.2,
  "segments": [
    { "id": 0, "start": 0.10, "end": 0.90, "speaker": "0", "text": "喂 你好" },
    { "id": 1, "start": 1.20, "end": 6.20, "speaker": "1", "text": "我这边是客服 有什么可以帮您" }
  ]
}

Solicitação de exemplo (multipart)

curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=gpt-4o-transcribe \
  -F file=@meeting.mp3 \
  -F response_format=json \
  -F language=en

Solicitação de exemplo (JSON base64)

POST /v1/audio/transcriptions
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "model": "gpt-4o-transcribe",
  "input_audio": {
    "data": "UklGRiQAAABXQVZFZm10I...",
    "format": "wav"
  },
  "response_format": "json",
  "language": "en"
}

Exemplo — ASR offline (seed-asr-bigmodel)

seed-asr-bigmodel (ASR offline internacional da BytePlus) aceita duas entradas mutuamente exclusivas: uma input_audio.url acessível (recomendado — sua própria URL de armazenamento de objetos, assinada e com tempo limitado; o áudio nunca toca nosso armazenamento), ou um upload direto de file/bytes (nós o armazenamos temporariamente em um bucket privado e o excluímos logo após a transcrição). Limitações: sem streaming (stream=true retorna 400); uploads de file de até 25 MB (use uma URL para gravações maiores); o processamento por requisição é limitado a ~20 minutos, então divida áudios muito longos. Cobrado pela duração do áudio ($0.002/min).

# ① Quick test — replace ONLY YOUR_API_KEY and run it (uses our hosted sample audio).
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seed-asr-bigmodel",
    "input_audio": {
      "url": "https://synthorai-asr-sample-360831509259.s3.us-west-1.amazonaws.com/seed-asr-sample.wav",
      "language": "zh"
    }
  }'
# → {"text":"..."}

# ② Your own audio file (<=25 MB) — replace key + file path.
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=seed-asr-bigmodel \
  -F language=zh \
  -F file=@/path/to/your-audio.wav

# ③ Your own signed URL (recommended for large files / privacy) — replace key + URL.
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"seed-asr-bigmodel","input_audio":{"url":"https://your-bucket/signed/meeting.wav","language":"zh"}}'

Notas / detalhes importantes: (1) language é opcional — valores comuns são zh (mandarim), yue-CN (cantonês), en-US; omita-o para detecção automática. (2) Ao usar input_audio.url, a URL deve ser publicamente acessível pelo serviço de transcrição — uma URL privada/interna/protegida por autenticação falhará; uma URL de armazenamento de objetos assinada (pre-signed) e com tempo limitado é a forma recomendada. (3) O upload de file e a URL são mutuamente exclusivos; escolha um. (4) Áudio sem fala reconhecível (silêncio) retorna 200 com uma string vazia {"text":""}, e não um erro.

Exemplo — SDK OpenAI Python

O endpoint é compatível com OpenAI, então o SDK oficial da OpenAI funciona diretamente substituindo base_url. Funciona da mesma forma para whisper-1, gpt-4o-transcribe e qualquer modelo de transcrição Gemini — basta alterar model.

from openai import OpenAI

client = OpenAI(
    base_url="https://synthorai.io/v1",
    api_key="YOUR_API_KEY",
)

with open("meeting.mp3", "rb") as f:
    result = client.audio.transcriptions.create(
        model="gpt-4o-transcribe",
        file=f,
        language="en",
        # prompt="Synthorai, BYOK, transcribe",   # optional vocabulary hint
        response_format="json",
    )

print(result.text)
# Token-level usage on gpt-4o-*:
if getattr(result, "usage", None):
    print(result.usage)

Exemplo — SDK OpenAI Node.js

import OpenAI from "openai";
import fs from "node:fs";

const client = new OpenAI({
  baseURL: "https://synthorai.io/v1",
  apiKey: process.env.SYNTHORAI_API_KEY,
});

const result = await client.audio.transcriptions.create({
  model: "gpt-4o-transcribe",
  file: fs.createReadStream("meeting.mp3"),
  language: "en",
  response_format: "json",
});

console.log(result.text);

Streaming (SSE)

Defina stream=true em gpt-4o-transcribe, gpt-4o-mini-transcribe, ou qualquer modelo de transcrição Gemini para receber eventos incrementais à medida que o áudio é decodificado. O Content-Type da resposta é text/event-stream e os eventos terminam com data: [DONE]. whisper-1 não suporta streaming (retorna 400 se stream=true).

Tipos de eventos que você verá para gpt-4o-transcribe:

data: {"type":"transcript.text.delta","delta":"Hello "}

data: {"type":"transcript.text.delta","delta":"world."}

data: {"type":"transcript.text.done","text":"Hello world."}

data: {"type":"usage","usage":{"type":"tokens","input_tokens":689,"output_tokens":287,"total_tokens":976,"input_token_details":{"audio_tokens":689,"text_tokens":0,"cached_tokens":0}}}

data: [DONE]

O streaming do Gemini usa os mesmos nomes de eventos SSE, e o gateway emite o mesmo objeto canônico usage documentado em Exemplo de resposta— idêntico entre OpenAI e Gemini — para que o código do cliente seja portável entre providers. O evento final usage sempre carrega o input_token_details detalhamento completo para uma cobrança precisa à tarifa de áudio.

Erros

Todos os erros seguem o envelope da OpenAI: { error: { message, type, code, param? } }. Casos comuns:

  • 400 model_not_found — o modelo não tem capacidade de transcrição nos channels deste workspace.
  • 400 byok_strict_no_key — o workspace é BYOK estrito (byok_fallback_to_pool=false) e não tem chave de vault para o provedor resolvido.
  • 400 content_policy_violation — o campo prompt acionou uma regra de guardrail (ex.: vazamento de chave BYOK).
  • 402 quota_exceeded — o custo estimado excede a cota restante do espaço de trabalho. BYOK é isento.
  • 408 — o corpo da requisição não terminou de ser enviado dentro do tempo de leitura do servidor. Comum com áudio grande em conexão lenta; tente novamente ou envie um arquivo menor.
  • 413 — o áudio excede o limite de 25 MB.
  • 502 upstream_error — falha de rede upstream ou resposta não-2xx do provedor do modelo.

Exemplo de resposta

{
  "text": "Thanks for joining today's call. Let's get started.",
  "usage": {
    "type": "tokens",
    "input_tokens": 689,
    "output_tokens": 287,
    "total_tokens": 976,
    "input_token_details": {
      "audio_tokens": 689,
      "text_tokens": 0,
      "cached_tokens": 0
    }
  }
}

Objeto usage uniforme. Todo modelo cobrado por token (gpt-4o-*, Gemini, Vertex) retorna exatamente este formato — todos os campos sempre presentes, preenchidos com zero quando um provedor não informa uma subcontagem — para que o mesmo código cliente leia o uso em todos os provedores. Como a entrada de transcrição é inteiramente áudio, Gemini/Vertex informam input_token_details.audio_tokens == input_tokens (sem divisão de texto); a OpenAI informa sua divisão nativa de áudio/texto. cached_tokens é a parte da entrada servida a partir de um cache do lado do provedor.

whisper-1 é a única exceção: é cobrado por duração de áudio, não por tokens, então sua resposta não traz objeto usage de tokens. Com response_format=text o corpo da resposta é a string bruta da transcrição em vez de um objeto JSON.