Respawn Tech Dev

Áudio

Transcrição, voz sintética, efeitos e músicas, análise, conversão, resumo, tradução e revoice de áudio, por REST ou MCP, com jobs assíncronos e preço por minuto.

Transcreva fala em texto, SRT ou WebVTT (com quem falou), gere voz a partir de texto, crie efeitos sonoros e músicas, analise e converta arquivos, resuma, traduza e fale uma gravação de novo com outra voz. Tudo é assíncrono: o pedido cobra na hora, devolve um job e você consulta o resultado, entregue por link assinado que expira. Também está nas tools MCP `audio_*` e `voice_*`.

Base path
/v1/tools/audio
Escopos
tools:audio:transcribetools:audio:readtools:audio:speaktools:audio:processtools:manage

Visão geral

Toda operação de áudio é assíncrona e cobrada na hora:

  1. POST na operação → 202 Accepted com job_id, status: pending e poll_after_seconds.
  2. Um worker processa em background.
  3. Consulte GET /jobs/{id} até o status ser completed (ou failed, e a cobrança é devolvida). Pronto, a resposta traz o resultado e um link assinado que expira.

Os mesmos casos de uso estão no MCP como as tools audio_* (toolset audio); a REST e o MCP compartilham formatos, preços e limites.

Cobrança ao aceitar o job

Os créditos são debitados quando o job é aceito. Falha do motor, etapa que não foi necessária e preço calculado a mais são devolvidos automaticamente; nada é cobrado se o pedido for recusado antes (audio.too_long, audio.price_above_max…).

OperaçãoRota
Transcrever áudioPOST/transcribe
Gerar fala a partir de textoPOST/speak
Listar as vozesGET/voices
Gerar efeito sonoro ou músicaPOST/generate
Analisar áudioPOST/analyze
Converter ou normalizar áudioPOST/convert
Resumir áudioPOST/summarize
Traduzir áudioPOST/translate
Falar a gravação de novo com outra vozPOST/revoice
Listar jobs de áudioGET/jobs
Status e resultado do jobGET/jobs/{id}

Entrada do áudio

As operações que recebem um áudio pedem exatamente um destes campos:

CampoO que é
audio_urlURL pública http(s) do arquivo. Endereços de rede interna ou privada são recusados (audio.input_blocked) e o download tem limite de 30 segundos
audio_base64O áudio inline em base64, até 10 MB decodificado
file_idId de um arquivo de áudio já enviado para a conta

Formatos aceitos: mp3, wav, ogg, m4a, flac e webm. O limite é de 60 minutos de áudio e 25 MB por arquivo por chamada. Em summarize e translate você pode mandar, no lugar do áudio, o job_id de uma transcrição já pronta: a transcrição é reaproveitada e só a operação nova é cobrada.

Todas as rotas de operação aceitam max_credits (em unidades; 10.000 unidades = 1 crédito): se o preço passar disso, o pedido é recusado com audio.price_above_max e nada é cobrado. O header Idempotency-Key torna a repetição segura: a mesma chave devolve o primeiro job em vez de cobrar de novo.

Custos

Transcrição e texto — Por minuto iniciado de áudio. Um áudio cuja duração não dá para ler do cabeçalho é cobrado pelo teto (60 minutos) e a diferença é devolvida no fim.

ItemCréditosNotas
Transcrição (por minuto)1,5—
Quem falou, diarize (por minuto)+0,5—
Resumo (por minuto)0,5Mais a transcrição quando parte de um áudio novo; com job_id de uma transcrição pronta, só o resumo
Tradução (por minuto)1,0Mais a transcrição quando parte de um áudio novo; com job_id de uma transcrição pronta, só a tradução

Voz e sons

ItemCréditosNotas
Fala com voz do catálogo (por 1.000 caracteres iniciados)3,0—
Fala com voz clonada (por 1.000 caracteres iniciados)9,0—
Efeito sonoro ou música (por segundo gerado)0,2—
Criar uma voz clonada (voice_create, só no MCP)5,0Devolvido se a amostra for recusada

Análise e conversão

ItemCréditos
Análise (por chamada)0,1
Conversão ou normalização (por minuto iniciado)0,1

Falar de novo (revoice) — Cada etapa é cobrada pelo preço do serviço dela e conferida no fim: a tradução que não foi necessária e a etapa que falhou são devolvidas. O `dry_run` traz o preço de cada etapa.

ItemPreçoNotas
Transcrição + (tradução) + falaSoma das três etapasA fala é estimada em 1.200 caracteres por minuto e cobrada sobre o texto real

O "minuto iniciado" arredonda para cima. Um áudio cuja duração não dá para ler do cabeçalho é cobrado pelo teto de 60 minutos e a diferença volta no fim do job. Consultas aos jobs seguem a franquia diária. O preço exato de uma chamada sai do dry-run.

Dry-run

Com ?dry_run=true na query (nas rotas de áudio é a query, não o header X-Dry-Run), as operações pagas respondem 200 com o preço e não cobram nem criam job:

{
  "success": true,
  "data": {
    "service_code": "audio_transcribe_minute",
    "units": 3,
    "rate": 15000,
    "total_units": 45000,
    "duration_ms": 125000,
    "duration_known": true,
    "parts": [{ "service_code": "audio_transcribe_minute", "units": 3, "rate": 15000, "total": 45000 }]
  }
}

rate e total_units estão em unidades (10.000 unidades = 1 crédito); parts detalha cada serviço cobrado. Em speak, o orçamento traz chars, voice, language e format.

Operações

Transcrever áudio

POST/v1/tools/audio/transcribe
Custo
Por minuto iniciado de áudio
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:transcribetools:manage

format: text (padrão), srt ou vtt. language é opcional (código ISO 639-1; sem ele o idioma é detectado). Com diarize: true (ou speakers, o número conhecido de falantes) cada trecho diz quem falou (Speaker 1, Speaker 2…), por um adicional por minuto.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/transcribe' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "audio_url": "https://example.com/episodio-12.mp3", "format": "text", "language": "pt" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/transcribe', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "audio_url": "https://example.com/episodio-12.mp3", "format": "text", "language": "pt" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/transcribe",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "audio_url": "https://example.com/episodio-12.mp3", "format": "text", "language": "pt" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/transcribe');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "audio_url": "https://example.com/episodio-12.mp3", "format": "text", "language": "pt" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/transcribe", strings.NewReader(`{ "audio_url": "https://example.com/episodio-12.mp3", "format": "text", "language": "pt" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "transcribe",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Gerar fala a partir de texto

POST/v1/tools/audio/speak
Custo
Por 1.000 caracteres iniciados
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:speaktools:manage

text aceita até 5.000 caracteres (acima disso o pedido é recusado antes de cobrar). voice é um id do catálogo ou uma voz clonada da conta (vc_…, só no MCP); sem voice, vale a voz padrão do language (pt-BR, en-US, en-GB, es-ES, fr-FR ou it-IT). format: mp3 (padrão) ou wav; speed: 0,5 a 2.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/speak' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "text": "Olá! Seu pedido saiu para entrega.", "voice": "pt-BR-dora", "format": "mp3", "speed": 1 }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/speak', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "text": "Olá! Seu pedido saiu para entrega.", "voice": "pt-BR-dora", "format": "mp3", "speed": 1 }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/speak",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "text": "Olá! Seu pedido saiu para entrega.", "voice": "pt-BR-dora", "format": "mp3", "speed": 1 },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/speak');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "text": "Olá! Seu pedido saiu para entrega.", "voice": "pt-BR-dora", "format": "mp3", "speed": 1 }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/speak", strings.NewReader(`{ "text": "Olá! Seu pedido saiu para entrega.", "voice": "pt-BR-dora", "format": "mp3", "speed": 1 }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "speak",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z",
    "voice": "pt-BR-dora",
    "language": "pt-BR",
    "format": "mp3"
  }
}
GET/v1/tools/audio/voices
Custo
Grátis
Dry-run
Não
Autenticação
qualquer um detools:audio:readtools:audio:transcribetools:audio:speaktools:audio:processtools:manage

Catálogo fechado de vozes do speak e do revoice. language filtra por idioma. Não é cobrado.

curl -sS -X GET 'https://api.respawntech.dev/v1/tools/audio/voices?language=pt-BR' \
  -H "X-API-Token: $RESPAWN_API_TOKEN"
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/voices?language=pt-BR', {
  method: 'GET',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
  },
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.get(
    "https://api.respawntech.dev/v1/tools/audio/voices?language=pt-BR",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/voices?language=pt-BR');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/audio/voices?language=pt-BR", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 200

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "voices": [
      {
        "id": "pt-BR-dora",
        "name": "Dora",
        "language": "pt-BR",
        "gender": "female"
      },
      {
        "id": "pt-BR-alex",
        "name": "Alex",
        "language": "pt-BR",
        "gender": "male"
      }
    ],
    "default_voice": "pt-BR-dora"
  }
}

Gerar efeito sonoro ou música

POST/v1/tools/audio/generate
Custo
Por segundo gerado
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:speaktools:manage

kind: effect (1 a 10 segundos, padrão 5 s) ou music (instrumental, 1 a 45 segundos, padrão 30 s). O áudio sai com exatamente duration_seconds. Não há fala nem canto, e descrições que imitam artistas, vozes ou obras existentes são recusadas antes de cobrar (audio.input_blocked). seed repete um som: o mesmo pedido com a seed que um job informou gera o mesmo áudio. A geração leva alguns minutos.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/generate' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "kind": "effect", "prompt": "porta de madeira rangendo devagar", "duration_seconds": 4, "format": "mp3" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/generate', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "kind": "effect", "prompt": "porta de madeira rangendo devagar", "duration_seconds": 4, "format": "mp3" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/generate",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "kind": "effect", "prompt": "porta de madeira rangendo devagar", "duration_seconds": 4, "format": "mp3" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/generate');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "kind": "effect", "prompt": "porta de madeira rangendo devagar", "duration_seconds": 4, "format": "mp3" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/generate", strings.NewReader(`{ "kind": "effect", "prompt": "porta de madeira rangendo devagar", "duration_seconds": 4, "format": "mp3" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "generate",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Analisar áudio

POST/v1/tools/audio/analyze
Custo
Preço fixo por chamada
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:processtools:manage

Sem IA de transcrição: devolve em analysis a duração, o formato e codec, bitrate, taxa de amostragem, canais, loudness integrado (LUFS), pico real, faixa de loudness, os trechos de silêncio (start_ms/end_ms) e o idioma falado. Preço fixo por chamada.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/analyze' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "audio_url": "https://example.com/episodio-12.mp3" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/analyze', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "audio_url": "https://example.com/episodio-12.mp3" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/analyze",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "audio_url": "https://example.com/episodio-12.mp3" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/analyze');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "audio_url": "https://example.com/episodio-12.mp3" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/analyze", strings.NewReader(`{ "audio_url": "https://example.com/episodio-12.mp3" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "analyze",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Converter ou normalizar áudio

POST/v1/tools/audio/convert
Custo
Por minuto iniciado de áudio
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:processtools:manage

format (obrigatório): mp3, wav, ogg, m4a ou flac. bitrate_kbps (32 a 320) vale só para formatos com perda. normalize: true nivela o loudness em -14 LUFS (padrão de streaming, -1,5 dBTP). As tags de metadados são removidas.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/convert' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "audio_url": "https://example.com/episodio-12.wav", "format": "mp3", "bitrate_kbps": 128, "normalize": true }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/convert', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "audio_url": "https://example.com/episodio-12.wav", "format": "mp3", "bitrate_kbps": 128, "normalize": true }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/convert",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "audio_url": "https://example.com/episodio-12.wav", "format": "mp3", "bitrate_kbps": 128, "normalize": True },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/convert');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "audio_url": "https://example.com/episodio-12.wav", "format": "mp3", "bitrate_kbps": 128, "normalize": true }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/convert", strings.NewReader(`{ "audio_url": "https://example.com/episodio-12.wav", "format": "mp3", "bitrate_kbps": 128, "normalize": true }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "convert",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Resumir áudio

POST/v1/tools/audio/summarize
Custo
Por minuto iniciado (mais a transcrição de um áudio novo)
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:transcribetools:manage

Mande o job_id de uma transcrição pronta (o áudio não é processado de novo) ou um áudio novo (transcrito primeiro e cobrado junto). O resultado vem em summary: o resumo e os tópicos em ordem (title, start_ms, points), mais um Markdown para baixar. O texto da transcrição (nunca o áudio) é enviado ao modelo de linguagem da plataforma.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/summarize' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "output_language": "pt-BR" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/summarize', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "output_language": "pt-BR" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/summarize",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "output_language": "pt-BR" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/summarize');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "output_language": "pt-BR" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/summarize", strings.NewReader(`{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "output_language": "pt-BR" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "summarize",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Traduzir áudio

POST/v1/tools/audio/translate
Custo
Por minuto iniciado (mais a transcrição de um áudio novo)
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:transcribetools:manage

target_language é obrigatório. A tradução sai em texto, SRT ou VTT com os tempos originais (e os falantes, se a transcrição tinha diarize); source_language informa de qual idioma ela veio. Não gera áudio dublado: para isso, use o revoice.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/translate' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "target_language": "en", "format": "srt" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/translate', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "target_language": "en", "format": "srt" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/translate",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "target_language": "en", "format": "srt" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/translate');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "target_language": "en", "format": "srt" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/translate", strings.NewReader(`{ "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64", "target_language": "en", "format": "srt" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "translate",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Falar a gravação de novo com outra voz

POST/v1/tools/audio/revoice
Custo
Soma das etapas (transcrição, tradução e fala)
Dry-run
Suportado (?dry_run=true)
Autenticação
qualquer um detools:audio:speaktools:manage

Num só job: transcreve a gravação, traduz o texto quando a voz fala outro idioma e sintetiza o resultado. Informe voice_id (do catálogo) ou language (usa a voz padrão dele). O áudio novo não mantém o tempo nem o ritmo do original (sem sincronia labial), e só vozes do catálogo ou clonadas da própria conta valem: nada de imitar uma pessoa real. O resultado traz o texto falado (transcript e text_download_url) e o que cada etapa custou em revoice.stages.

curl -sS -X POST 'https://api.respawntech.dev/v1/tools/audio/revoice' \
  -H "X-API-Token: $RESPAWN_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "audio_url": "https://example.com/aviso.mp3", "voice_id": "pt-BR-alex", "format": "mp3" }'
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/revoice', {
  method: 'POST',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ "audio_url": "https://example.com/aviso.mp3", "voice_id": "pt-BR-alex", "format": "mp3" }),
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.post(
    "https://api.respawntech.dev/v1/tools/audio/revoice",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    json={ "audio_url": "https://example.com/aviso.mp3", "voice_id": "pt-BR-alex", "format": "mp3" },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/revoice');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
{ "audio_url": "https://example.com/aviso.mp3", "voice_id": "pt-BR-alex", "format": "mp3" }
JSON,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/audio/revoice", strings.NewReader(`{ "audio_url": "https://example.com/aviso.mp3", "voice_id": "pt-BR-alex", "format": "mp3" }`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 202

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "revoice",
    "status": "pending",
    "poll_after_seconds": 10,
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Listar jobs

GET/v1/tools/audio/jobs
Custo
Franquia diária, depois 0,005 crédito/leitura via API
Dry-run
Suportado (X-Dry-Run: true)
Autenticação
qualquer um detools:audio:readtools:audio:transcribetools:audio:speaktools:audio:processtools:manage

Os jobs mais recentes primeiro, com limit (padrão 20, até 100) e offset. A lista traz só o status; o resultado e o link ficam em GET /jobs/{id}. Jobs e arquivos são apagados depois da retenção (24 horas).

curl -sS -X GET 'https://api.respawntech.dev/v1/tools/audio/jobs?limit=20&offset=0' \
  -H "X-API-Token: $RESPAWN_API_TOKEN"
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/jobs?limit=20&offset=0', {
  method: 'GET',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
  },
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.get(
    "https://api.respawntech.dev/v1/tools/audio/jobs?limit=20&offset=0",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/jobs?limit=20&offset=0');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/audio/jobs?limit=20&offset=0", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 200

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "jobs": [
      {
        "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
        "kind": "transcribe",
        "status": "completed",
        "duration_ms": 125000,
        "cost_units": 30000,
        "created_at": "2026-10-12T12:00:00Z",
        "expires_at": "2026-10-13T12:00:00Z"
      }
    ],
    "total": 1
  }
}

Status, resultado e download

GET/v1/tools/audio/jobs/{id}
Custo
Franquia diária, depois 0,01 crédito/leitura via API
Dry-run
Suportado (X-Dry-Run: true)
Autenticação
qualquer um detools:audio:readtools:audio:transcribetools:audio:speaktools:audio:processtools:manage

Não há rota de download separada: o resultado e o arquivo vêm deste endpoint. Com status: completed, a resposta traz o conteúdo pelo tipo de job — transcript (também inline até 32 KB; truncated: true avisa o corte) para transcrição e tradução, summary, analysis, conversion, generation ou revoice — e download_url com download_expires_at. O link é assinado e expira: consulte de novo para receber um link novo. Em failed, o error_code explica o motivo e a cobrança é devolvida. A leitura é medida na franquia diária.

status: pending, processing, completed ou failed.

curl -sS -X GET 'https://api.respawntech.dev/v1/tools/audio/jobs/550e8400-e29b-41d4-a716-446655440000' \
  -H "X-API-Token: $RESPAWN_API_TOKEN"
const response = await fetch('https://api.respawntech.dev/v1/tools/audio/jobs/550e8400-e29b-41d4-a716-446655440000', {
  method: 'GET',
  headers: {
    'X-API-Token': process.env.RESPAWN_API_TOKEN,
  },
});

if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());
import os
import requests

response = requests.get(
    "https://api.respawntech.dev/v1/tools/audio/jobs/550e8400-e29b-41d4-a716-446655440000",
    headers={
        "X-API-Token": os.environ["RESPAWN_API_TOKEN"],
    },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(response.json()["error"]["code"])
print(response.json())
<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/audio/jobs/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/audio/jobs/550e8400-e29b-41d4-a716-446655440000", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))

	client := &http.Client{Timeout: 30 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode >= 400 {
		panic(string(data))
	}
	fmt.Println(string(data))
}

Resposta 200

{
  "success": true,
  "trace_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "job_id": "5b1d8c2e-6f4a-4e7b-9c3d-2a8e1f0b7d64",
    "kind": "transcribe",
    "status": "completed",
    "duration_ms": 125000,
    "cost_units": 30000,
    "language": "pt",
    "format": "text",
    "transcript": "Olá, pessoal, bem-vindos ao episódio de hoje. Vamos falar de como automatizar relatórios.",
    "segments": 2,
    "download_url": "https://files.respawntech.dev/audio/5b1d8c2e.txt?signature=…",
    "download_expires_at": "2026-10-12T12:15:00Z",
    "created_at": "2026-10-12T12:00:00Z",
    "expires_at": "2026-10-13T12:00:00Z"
  }
}

Vozes clonadas e consentimento (só MCP)

Enquanto não existir uma rota REST, a clonagem de voz está somente nas tools MCP voice_create, voice_list e voice_delete (scope tools:audio:speak). A voz clonada serve só à conta que a criou, em audio_speak (voice: "vc_…", preço de voz clonada) e em audio_revoice (voice_id).

  • voice_create clona a voz do titular da conta a partir de uma amostra de 10 a 60 segundos. O consentimento é obrigatório: chame primeiro com dry_run para ler consent_terms, consent_version e consent_phrase; grave a amostra com você sozinho lendo a frase em voz alta; então chame com consent.accepted: true e a consent_version. Amostras sem a frase, com mais de uma voz ou fora da duração são recusadas e o valor é devolvido (audio.voice_sample_rejected). Sem o aceite, a resposta é audio.consent_required. É assíncrono: acompanhe com voice_list até a voz ficar completed.
  • voice_list lista as vozes da conta (voice_id, nome, idioma, status, validade). Grátis.
  • voice_delete apaga a voz de verdade: a amostra criptografada e o registro de consentimento são destruídos e a voz para de funcionar na hora (jobs na fila nela falham e são devolvidos). Grátis.

Uso responsável

  • Só a sua voz, com o seu consentimento. Clonar a voz de outra pessoa, mesmo com a gravação em mãos, não é permitido; a verificação da frase falada e de um único falante existe para impedir isso.
  • Nada de imitação. Nem a fala, nem o revoice, nem a geração de sons aceitam imitar artistas, vozes ou obras existentes.
  • Limites: até 3 vozes clonadas por conta, 5 criações por dia e 60 usos por hora (audio.voice_limit, audio.voice_rate_limited).
  • Dados guardados: a amostra fica criptografada por até 30 dias ou até o voice_delete; cada criação, recusa, uso e exclusão é auditado, sem conteúdo de voz. O áudio de entrada e de saída dos demais jobs expira em 24 horas.
  • Aviso ao ouvinte: se você publica áudio sintético, avise que a voz é gerada, principalmente quando for uma voz clonada.

Scopes

ScopeOperações
tools:audio:transcribetranscribe, summarize, translate
tools:audio:speakspeak, generate, revoice (no MCP, também voice_create e voice_delete)
tools:audio:processanalyze, convert
tools:audio:readvoices, jobs, jobs/{id} (os três scopes acima também leem os próprios jobs)

tools:manage cobre tudo. A lista completa fica em Autenticação.

Erros

audio.* na resposta ou, em jobs que falham depois de aceitos, no error_code do job.

CódigoHTTPQuando
audio.disabled403Áudio ainda não liberado para a conta.
audio.input_invalid400Corpo inválido, ou áudio informado de forma errada (mande exatamente um entre audio_url, audio_base64 e file_id).
audio.input_blocked400A URL do áudio aponta para um endereço não permitido (rede interna ou privada), ou a descrição de audio_generate pede imitação de artistas, vozes ou obras. Nada é cobrado.
audio.too_long400Áudio acima de 60 minutos, ou texto acima de 5.000 caracteres: recusado antes de cobrar.
audio.input_too_large413Arquivo de áudio acima de 25 MB (ou 10 MB em audio_base64).
audio.format_unsupported415Formato de áudio não suportado; use mp3, wav, ogg, m4a, flac ou webm.
audio.input_fetch_failed502Não foi possível baixar o áudio da audio_url.
audio.provider_failed502O motor de áudio falhou; a cobrança é devolvida.
audio.input_timeout504O download do áudio passou de 30 segundos.
audio.price_above_max409O preço passa de max_credits; nada é cobrado.
audio.pricing_unavailable503Preço do serviço de áudio indisponível no momento; tente de novo.
audio.not_found404Job de áudio inexistente, de outra conta ou já expirado.
audio.voice_unknown400Voz inexistente ou apagada: use um id de GET /audio/voices ou uma voz clonada da conta que já esteja pronta.
audio.consent_required400voice_create sem o consentimento aceito, ou com versão dos termos desatualizada (leia os termos com dry_run).
audio.voice_sample_rejected422Amostra recusada: sem a frase de consentimento lida em voz alta, com mais de uma voz ou fora de 10 a 60 segundos. O valor é devolvido.
audio.voice_limit409A conta já tem o máximo de 3 vozes clonadas; apague uma com voice_delete.
audio.voice_rate_limited429Limite de criações de voz por dia (5) ou de usos por hora (60) atingido.

Atualizado em