---
name: lero-api
description: Integra a API de voz do Lero (texto em fala em português do Brasil, com sotaque do Rio, de São Paulo ou de Niterói, e transcrição de áudio em português do Brasil) num projeto. Use quando o pedido for gerar fala, áudio ou MP3 com o Lero, transcrever áudio ou vídeo, gerar legenda (SRT ou VTT), colocar a voz do Lero no produto ou chamar app.lero.studio/api/v1.
---

# API do Lero

Referência completa: https://lero.studio/docs/llms-full.txt. Contrato: https://lero.studio/docs/openapi.json.

Você vai integrar a API de voz do Lero no meu projeto. Siga estas instruções.

## O que é o Lero

O Lero transforma texto em fala em português do Brasil, com sotaque. Você manda o texto e a voz e recebe um MP3. Vozes: `rio` (Rio de Janeiro), `sp` (São Paulo), `niteroi` (Niterói). Model: `Lero v1`.

O Lero também transcreve áudio em português do Brasil (Speech-to-Text): você manda o arquivo ou um link e recebe o texto, as frases com o tempo de cada uma ou a legenda pronta (SRT ou VTT).

## Leia antes de escrever código

1. https://lero.studio/docs/llms-full.txt: a referência completa em Markdown.
2. https://lero.studio/docs/openapi.json: o contrato OpenAPI 3.1 das rotas.

Siga o contrato. Não invente rota, campo nem código de erro.

## Conexão

- Base URL: https://app.lero.studio/api/v1
- Toda request leva o header `Authorization: Bearer <chave>`.
- Leia a chave da variável de ambiente `LERO_API_KEY`. Nunca escreva a chave no código.
- Chame a API só do servidor. Nunca do navegador nem de um app de celular: quem tiver a chave gasta os créditos.

## Rotas

1. `POST /v1/tts` com `{"texto": "...", "voz": "rio"}`: devolve o MP3 (`audio/mpeg`). Com `Accept: application/json` (sem `*/*`), devolve JSON com o áudio em base64 no campo `audio`.
2. `POST /v1/stt` com o arquivo no campo `audio` em `multipart/form-data` (até 4 MB), ou JSON com `url` (link https público, até 500 MB): devolve JSON com `texto` e `segmentos` (as frases com `inicio` e `fim` em segundos). Com `formato` `texto`, `srt` ou `vtt`, devolve o arquivo direto. Opcionais: `timestamps` (`palavra`), `palavras_chave`, `formatar`. Só se o pedido envolver transcrição, ditado ou legenda.
3. `GET /v1/voices`: a lista das vozes. Grátis.
4. `GET /v1/balance`: os créditos da conta e o plano. Grátis.
5. Conversational Agent (voz ao vivo por WebRTC): `GET /v1/agents` e `POST /v1/agents/conversation`. Só se o pedido for um agente de voz ao vivo; siga a seção "Conversational Agent: passo a passo" do llms-full.txt.

## Regras

- Fala: 1 crédito por caractere do texto, cobrado antes de gerar e devolvido se a geração falhar.
- Fala: até 500 caracteres por pedido. Para um texto maior, divida em frases (nunca no meio de uma palavra) e junte os MP3 na ordem.
- Transcrição: 150 créditos por minuto de áudio, cobrados só quando dá certo. Até 2 h por pedido. Arquivo maior que 4 MB vai por `url`.
- Até 60 pedidos por minuto por conta. Se vier `429` ou `503`, espere os segundos do header `Retry-After` e tente de novo.
- A fala leva alguns segundos e a transcrição, alguns minutos (1 h de áudio em uns 2 min): use timeout de 300 s.
- Trate os erros pelo campo `erro` (código fixo), nunca pelo texto da `mensagem`.
- Guarde o MP3 e a transcrição se for usar de novo: cada pedido gasta créditos, e o Lero não guarda o áudio nem o texto.
- Guarde o `X-Pedido-Id` nos logs, para o suporte.

## Entrega

- Um cliente da API com timeout, espera no `Retry-After` e tratamento de erro pelo `erro`.
- Testes com respostas simuladas a partir dos exemplos do `openapi.json`.
- Um resumo curto do que foi feito e de como rodar.

## Exemplo

```javascript
import { writeFile } from "node:fs/promises";

const res = await fetch("https://app.lero.studio/api/v1/tts", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.LERO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ texto: "Fala, tudo bem? Aqui é o Lero, direto do Rio.", voz: "rio" }),
});
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).erro}`);
await writeFile("fala.mp3", Buffer.from(await res.arrayBuffer()));
```

## Exemplo: transcrição

```javascript
import { readFile, writeFile } from "node:fs/promises";

const headers = { "Authorization": `Bearer ${process.env.LERO_API_KEY}` };

// arquivo local (até 4 MB)
const form = new FormData();
form.append("audio", new Blob([await readFile("reuniao.mp3")], { type: "audio/mpeg" }), "reuniao.mp3");
form.append("palavras_chave", "Lero,Unflat,CNPJ");
const res = await fetch("https://app.lero.studio/api/v1/stt", {
  method: "POST",
  headers,
  body: form,
  signal: AbortSignal.timeout(300_000),
});
const t = await res.json();
if (!res.ok) throw new Error(`${res.status} ${t.erro}`);
console.log(t.texto);
for (const s of t.segmentos) console.log(s.inicio, s.fim, s.texto);

// link https público (até 500 MB) e a legenda pronta
const srt = await fetch("https://app.lero.studio/api/v1/stt", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://exemplo.com/reuniao.mp3", formato: "srt" }),
  signal: AbortSignal.timeout(300_000),
});
if (!srt.ok) throw new Error(`${srt.status} ${(await srt.json()).erro}`);
await writeFile("legenda.srt", await srt.text());
```
