{
  "openapi": "3.1.0",
  "info": {
    "title": "Lero API",
    "version": "1.0.0",
    "summary": "Lero turns text into speech in Brazilian Portuguese, with a regional accent. The Lero API takes the text and the voice and returns an MP3, with the voices rio (Rio de Janeiro), sp (São Paulo) and niteroi (Niterói). Speech-to-Text transcribes Brazilian Portuguese audio, with timestamps for each sentence and ready subtitles. The Conversational Agent is a live voice agent over WebRTC, with your system prompt and knowledge base. The Lero MCP puts this voice inside Claude Code, Codex, Cursor and Claude Desktop.",
    "description": "Text to speech (1 credit per character) and audio transcription (150 credits per minute of audio) in Brazilian Portuguese. Docs: https://lero.studio/docs/en",
    "contact": {
      "name": "Lero",
      "email": "oi@lero.studio",
      "url": "https://lero.studio/docs/en"
    }
  },
  "servers": [
    {
      "url": "https://app.lero.studio/api/v1"
    }
  ],
  "security": [
    {
      "chave": []
    },
    {
      "chaveHeader": []
    }
  ],
  "paths": {
    "/tts": {
      "post": {
        "operationId": "criarFala",
        "summary": "Generate speech",
        "description": "Turns the text into speech and returns the MP3 (`audio/mpeg`). Costs 1 credit per character of the text, charged before generating and refunded if generation fails.\n\nPrefer JSON? Send `Accept: application/json` (without `*/*`) and the audio comes as base64 in the `audio` field.",
        "tags": [
          "Text-to-Speech (TTS)"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FalaPedido"
              },
              "example": {
                "texto": "Fala, tudo bem? Aqui é o Lero, direto do Rio.",
                "voz": "rio"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The speech MP3. With `Accept: application/json` (without `*/*`), JSON with the audio as base64.",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "X-Creditos-Custo": {
                "$ref": "#/components/headers/X-Creditos-Custo"
              },
              "X-Creditos-Restantes": {
                "$ref": "#/components/headers/X-Creditos-Restantes"
              },
              "X-Duracao": {
                "$ref": "#/components/headers/X-Duracao"
              }
            },
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/mpeg"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FalaJson"
                },
                "example": {
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b",
                  "custo": 45,
                  "saldo": 1499955,
                  "model": "Lero v1",
                  "voz": "rio",
                  "duracao": 3.12,
                  "formato": "mp3",
                  "audio": "SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjYx..."
                }
              }
            }
          },
          "400": {
            "description": "`texto_invalido`, `voz_invalida`, `modelo_invalido`, `pedido_invalido`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "texto_invalido",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "402": {
            "description": "`sem_credito`, `teto_da_chave`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_credito",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "403": {
            "description": "`plano`, `escopo`, `bloqueado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "plano",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "429": {
            "description": "`muitos_pedidos`, `simultaneas`, `ocupado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "muitos_pedidos",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "500": {
            "description": "`interno`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "interno",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "502": {
            "description": "`falhou`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "falhou",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "503": {
            "description": "`carregando`, `motor_desligado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "carregando",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "504": {
            "description": "`demorou`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "demorou",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    },
    "/stt": {
      "post": {
        "operationId": "transcrever",
        "summary": "Transcribe audio",
        "description": "Turns audio into text, in spoken Brazilian Portuguese: slang, acronyms, numbers and names come out right. Returns the text with paragraphs and the sentences with start and end times; on request, the time of each word or ready subtitles (SRT or VTT).\n\nSend the file in the `audio` field as `multipart/form-data` (up to 4 MB), or a public https link in `url` (up to 500 MB; a signed S3, GCS or R2 link works). Files over 4 MB go by `url`, in a JSON body with the same options. Formats: MP3, WAV, M4A, OGG, OPUS, WEBM, FLAC and MP4 video (Lero uses the video's audio).\n\nCosts 150 credits per minute of audio (2.5 per second), billed by the second and rounded up, only when the transcription succeeds: if it fails, nothing is charged. The whole file duration counts, silence included. Example: 11 min of audio cost 1,650 credits.\n\nUp to 2 h of audio per request. Transcription runs at about 30 times real time (1 h of audio in about 2 min): use a 300 s timeout. Lero does not keep the audio or the transcript: it deletes both when it responds.\n\n| `formato` | response |\n|---|---|\n| `json` (default) | JSON with the text, the sentences and the cost (on the side) |\n| `texto` | `text/plain`: just the text, with paragraphs |\n| `srt` | `application/x-subrip`: SRT subtitles |\n| `vtt` | `text/vtt`: WebVTT subtitles |\n\nIn the JSON, `texto` has paragraphs (`\\n\\n`) at long pauses and `segmentos` has the sentences, with `inicio` and `fim` in seconds. With `timestamps=palavra`, each sentence also carries `palavras`: `[{inicio, fim, palavra}]`. `formatado` is `true` when the punctuation and capitalization pass covered the whole text. The `texto`, `srt` and `vtt` formats come in UTF-8.",
        "tags": [
          "Speech-to-Text (STT)"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TranscricaoArquivo"
              },
              "encoding": {
                "audio": {
                  "contentType": "audio/*, video/mp4, application/octet-stream"
                }
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TranscricaoUrl"
              },
              "example": {
                "url": "https://example.com/meeting.mp3",
                "formato": "srt"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The transcription. `formato=json` (default): the JSON. `texto`, `srt` and `vtt`: the file itself, in UTF-8.",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "X-Creditos-Custo": {
                "$ref": "#/components/headers/X-Creditos-Custo"
              },
              "X-Creditos-Restantes": {
                "$ref": "#/components/headers/X-Creditos-Restantes"
              },
              "X-Duracao": {
                "$ref": "#/components/headers/X-Duracao"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transcricao"
                },
                "example": {
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b",
                  "custo": 1650,
                  "saldo": 1498350,
                  "model": "Lero v1",
                  "idioma": "pt-BR",
                  "duracao": 659.4,
                  "formatado": true,
                  "texto": "Bom dia, pessoal. Hoje a pauta é o lançamento da campanha de verão.\n\nPerfeito. Então...",
                  "segmentos": [
                    {
                      "inicio": 0.0,
                      "fim": 3.2,
                      "texto": "Bom dia, pessoal."
                    },
                    {
                      "inicio": 3.4,
                      "fim": 7.9,
                      "texto": "Hoje a pauta é o lançamento da campanha de verão."
                    }
                  ]
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Bom dia, pessoal. Hoje a pauta é o lançamento da campanha de verão.\n\nPerfeito. Então..."
              },
              "application/x-subrip": {
                "schema": {
                  "type": "string"
                },
                "example": "1\n00:00:00,000 --> 00:00:03,200\nBom dia, pessoal.\n\n2\n00:00:03,400 --> 00:00:07,900\nHoje a pauta é o lançamento da campanha de verão.\n"
              },
              "text/vtt": {
                "schema": {
                  "type": "string"
                },
                "example": "WEBVTT\n\n00:00:00.000 --> 00:00:03.200\nBom dia, pessoal.\n\n00:00:03.400 --> 00:00:07.900\nHoje a pauta é o lançamento da campanha de verão.\n"
              }
            }
          },
          "400": {
            "description": "`audio_invalido`, `url_invalida`, `formato_invalido`, `idioma_invalido`, `modelo_invalido`, `pedido_invalido`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "audio_invalido",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "402": {
            "description": "`sem_credito`, `teto_da_chave`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_credito",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "403": {
            "description": "`plano`, `escopo`, `bloqueado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "plano",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "413": {
            "description": "`audio_grande`, `audio_longo`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "audio_grande",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "429": {
            "description": "`muitos_pedidos`, `simultaneas`, `ocupado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "muitos_pedidos",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "500": {
            "description": "`interno`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "interno",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "502": {
            "description": "`falhou`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "falhou",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "503": {
            "description": "`motor_desligado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "motor_desligado",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "504": {
            "description": "`demorou`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "demorou",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    },
    "/voices": {
      "get": {
        "operationId": "listarVozes",
        "summary": "List voices",
        "description": "The list of voices, with id and name. Free.",
        "tags": [
          "Voices"
        ],
        "responses": {
          "200": {
            "description": "The voices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vozes"
                },
                "example": {
                  "vozes": [
                    {
                      "id": "rio",
                      "nome": "Rio de Janeiro"
                    },
                    {
                      "id": "sp",
                      "nome": "São Paulo"
                    },
                    {
                      "id": "niteroi",
                      "nome": "Niterói"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "403": {
            "description": "`plano`, `bloqueado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "plano",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "verSaldo",
        "summary": "Credits left",
        "description": "The account credits right now, with this month's allowance, and the plan. Free.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "The balance and the plan.",
            "headers": {
              "X-Creditos-Restantes": {
                "$ref": "#/components/headers/X-Creditos-Restantes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Saldo"
                },
                "example": {
                  "saldo": 1499955,
                  "plano": "Dev"
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "403": {
            "description": "`plano`, `bloqueado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "plano",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    },
    "/agents": {
      "get": {
        "operationId": "listarAgentes",
        "summary": "List versions and LLMs",
        "description": "Conversational Agent discovery: the agent versions your key can use, the LLMs, the voices and the recommended setup. Call it before opening a call: the list changes. Free.",
        "tags": [
          "Conversational Agent"
        ],
        "responses": {
          "200": {
            "description": "The current options.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agentes"
                },
                "example": {
                  "ligado": true,
                  "recomendado": {
                    "versao": "v0.4",
                    "llm": "oss120b",
                    "voz": "rio"
                  },
                  "versoes": [
                    {
                      "id": "v0.4",
                      "nome": "Agente v0.4",
                      "lingua": "pt",
                      "vozes": true
                    }
                  ],
                  "llms": [
                    {
                      "id": "oss120b",
                      "nome": "..."
                    }
                  ],
                  "vozes": [
                    "rio",
                    "sp",
                    "niteroi"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    },
    "/agents/conversation": {
      "post": {
        "operationId": "abrirConversa",
        "summary": "Open a call (WebRTC)",
        "description": "Live call signaling: you send the SDP offer of your WebRTC client and get the SDP answer. After that, audio and the `chat` data channel flow peer-to-peer between your client and the agent (streaming STT, LLM and TTS, with barge-in and turn detection). Without `versao`, `llm` and `voz`, the recommended setup applies. With `instrucoes`, the agent becomes yours: the system prompt replaces the Lero persona. Step by step in [Conversational Agent: step by step](#agente-guia).",
        "tags": [
          "Conversational Agent"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConversaPedido"
              },
              "example": {
                "type": "offer",
                "sdp": "v=0\r\no=- ...",
                "versao": "v0.4",
                "llm": "oss120b",
                "voz": "rio"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The SDP answer: apply it with `setRemoteDescription`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversaResposta"
                },
                "example": {
                  "type": "answer",
                  "sdp": "v=0\r\no=- ..."
                }
              }
            }
          },
          "400": {
            "description": "`voz_invalida`, `pedido_invalido`, `oferta_invalida`, `versao_invalida`, `llm_invalido`, `roteiro_invalido`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "voz_invalida",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "401": {
            "description": "`sem_chave`, `chave_invalida`, `chave_vencida`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_chave",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "502": {
            "description": "`sem_bot`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "sem_bot",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          },
          "503": {
            "description": "`desligado`",
            "headers": {
              "X-Pedido-Id": {
                "$ref": "#/components/headers/X-Pedido-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                },
                "example": {
                  "erro": "desligado",
                  "mensagem": "...",
                  "pedido": "3f9c1e0a7b2d4c6e8a1b3d5f7e9c0a2b"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "chave": {
        "type": "http",
        "scheme": "bearer",
        "description": "The `lero_...` key in the Authorization header."
      },
      "chaveHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "The same key, in the X-Api-Key header."
      }
    },
    "headers": {
      "X-Pedido-Id": {
        "description": "The request id. Send it if you need support.",
        "schema": {
          "type": "string"
        }
      },
      "X-Creditos-Custo": {
        "description": "The credits charged for this request.",
        "schema": {
          "type": "integer"
        }
      },
      "X-Creditos-Restantes": {
        "description": "The account balance after the request.",
        "schema": {
          "type": "integer"
        }
      },
      "X-Duracao": {
        "description": "The audio duration, in seconds.",
        "schema": {
          "type": "number"
        }
      },
      "Retry-After": {
        "description": "How many seconds to wait before trying again.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "FalaPedido": {
        "type": "object",
        "required": [
          "texto",
          "voz"
        ],
        "properties": {
          "texto": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "What Lero will say, 1 to 500 characters. Leading and trailing spaces do not count."
          },
          "voz": {
            "type": "string",
            "enum": [
              "rio",
              "sp",
              "niteroi"
            ],
            "description": "The voice: `rio` (Rio de Janeiro), `sp` (São Paulo) or `niteroi` (Niterói)."
          },
          "model": {
            "type": "string",
            "const": "Lero v1",
            "description": "`Lero v1`, the only speech model for now."
          }
        }
      },
      "FalaJson": {
        "type": "object",
        "required": [
          "pedido",
          "custo",
          "model",
          "voz",
          "duracao",
          "formato",
          "audio"
        ],
        "properties": {
          "pedido": {
            "type": "string",
            "description": "The request id."
          },
          "custo": {
            "type": "integer",
            "description": "Credits charged."
          },
          "saldo": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The balance after the request."
          },
          "model": {
            "type": "string",
            "const": "Lero v1"
          },
          "voz": {
            "type": "string",
            "enum": [
              "rio",
              "sp",
              "niteroi"
            ]
          },
          "duracao": {
            "type": "number",
            "description": "Seconds of audio."
          },
          "formato": {
            "type": "string",
            "const": "mp3"
          },
          "audio": {
            "type": "string",
            "contentEncoding": "base64",
            "contentMediaType": "audio/mpeg"
          }
        }
      },
      "TranscricaoArquivo": {
        "type": "object",
        "oneOf": [
          {
            "required": [
              "audio"
            ]
          },
          {
            "required": [
              "url"
            ]
          }
        ],
        "properties": {
          "audio": {
            "type": "string",
            "format": "binary",
            "contentMediaType": "application/octet-stream",
            "description": "The audio file, up to 4 MB: MP3, WAV, M4A, OGG, OPUS, WEBM, FLAC or MP4 video. Send `audio` or `url`, never both."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "description": "Public https link to the audio, up to 500 MB; Lero downloads it. For files over 4 MB, use `url` (a signed S3, GCS, R2 etc. link works)."
          },
          "palavras_chave": {
            "type": "string",
            "description": "Keyterms: up to 50 names, brands, acronyms and terms to recognize and keep spelled as given, e.g. `[\"Lero\", \"Unflat\", \"CNPJ\"]`. In multipart, as a comma-separated list: `Lero,Unflat,CNPJ`."
          },
          "formato": {
            "type": "string",
            "enum": [
              "json",
              "texto",
              "srt",
              "vtt"
            ],
            "default": "json",
            "description": "`json` (default), `texto` (text/plain), `srt` or `vtt` (ready subtitles)."
          },
          "timestamps": {
            "type": "string",
            "enum": [
              "frase",
              "palavra"
            ],
            "default": "frase",
            "description": "`frase` (sentence, default) or `palavra` (word): each segment gets `palavras`, with the start and end of each word. Only with `json`."
          },
          "formatar": {
            "type": "boolean",
            "default": true,
            "description": "The punctuation and capitalization pass, default `true`. With `false`, it returns faster, with the recognizer's punctuation; same price."
          },
          "idioma": {
            "type": "string",
            "enum": [
              "pt-BR"
            ],
            "default": "pt-BR",
            "description": "`pt-BR`, the only one for now."
          },
          "model": {
            "type": "string",
            "const": "Lero v1",
            "description": "`Lero v1`, the only transcription model for now."
          }
        }
      },
      "TranscricaoUrl": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "description": "Public https link to the audio, up to 500 MB; Lero downloads it. For files over 4 MB, use `url` (a signed S3, GCS, R2 etc. link works)."
          },
          "palavras_chave": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "type": "string"
            },
            "description": "Keyterms: up to 50 names, brands, acronyms and terms to recognize and keep spelled as given, e.g. `[\"Lero\", \"Unflat\", \"CNPJ\"]`. In multipart, as a comma-separated list: `Lero,Unflat,CNPJ`."
          },
          "formato": {
            "type": "string",
            "enum": [
              "json",
              "texto",
              "srt",
              "vtt"
            ],
            "default": "json",
            "description": "`json` (default), `texto` (text/plain), `srt` or `vtt` (ready subtitles)."
          },
          "timestamps": {
            "type": "string",
            "enum": [
              "frase",
              "palavra"
            ],
            "default": "frase",
            "description": "`frase` (sentence, default) or `palavra` (word): each segment gets `palavras`, with the start and end of each word. Only with `json`."
          },
          "formatar": {
            "type": "boolean",
            "default": true,
            "description": "The punctuation and capitalization pass, default `true`. With `false`, it returns faster, with the recognizer's punctuation; same price."
          },
          "idioma": {
            "type": "string",
            "enum": [
              "pt-BR"
            ],
            "default": "pt-BR",
            "description": "`pt-BR`, the only one for now."
          },
          "model": {
            "type": "string",
            "const": "Lero v1",
            "description": "`Lero v1`, the only transcription model for now."
          }
        }
      },
      "Transcricao": {
        "type": "object",
        "required": [
          "pedido",
          "custo",
          "model",
          "idioma",
          "duracao",
          "formatado",
          "texto",
          "segmentos"
        ],
        "properties": {
          "pedido": {
            "type": "string",
            "description": "The request id."
          },
          "custo": {
            "type": "integer",
            "description": "Credits charged."
          },
          "saldo": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The balance after the request."
          },
          "model": {
            "type": "string",
            "const": "Lero v1"
          },
          "idioma": {
            "type": "string",
            "const": "pt-BR"
          },
          "duracao": {
            "type": "number",
            "description": "Seconds of audio, the cost basis."
          },
          "formatado": {
            "type": "boolean",
            "description": "`true` when the punctuation and capitalization pass covered the whole text."
          },
          "texto": {
            "type": "string",
            "description": "The full text, with paragraphs (`\\n\\n`) at long pauses."
          },
          "segmentos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Segmento"
            }
          }
        }
      },
      "Segmento": {
        "type": "object",
        "required": [
          "inicio",
          "fim",
          "texto"
        ],
        "properties": {
          "inicio": {
            "type": "number",
            "description": "Start, in seconds."
          },
          "fim": {
            "type": "number",
            "description": "End, in seconds."
          },
          "texto": {
            "type": "string",
            "description": "The sentence."
          },
          "palavras": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Palavra"
            },
            "description": "Only with `timestamps=palavra`."
          }
        }
      },
      "Palavra": {
        "type": "object",
        "required": [
          "inicio",
          "fim",
          "palavra"
        ],
        "properties": {
          "inicio": {
            "type": "number"
          },
          "fim": {
            "type": "number"
          },
          "palavra": {
            "type": "string"
          }
        }
      },
      "Voz": {
        "type": "object",
        "required": [
          "id",
          "nome"
        ],
        "properties": {
          "id": {
            "type": "string",
            "enum": [
              "rio",
              "sp",
              "niteroi"
            ]
          },
          "nome": {
            "type": "string"
          }
        }
      },
      "Vozes": {
        "type": "object",
        "required": [
          "vozes"
        ],
        "properties": {
          "vozes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Voz"
            }
          }
        }
      },
      "Saldo": {
        "type": "object",
        "required": [
          "saldo",
          "plano"
        ],
        "properties": {
          "saldo": {
            "type": "integer",
            "description": "Account credits right now."
          },
          "plano": {
            "type": "string",
            "enum": [
              "Grátis",
              "Starter",
              "Creator",
              "Dev"
            ]
          }
        }
      },
      "Agentes": {
        "type": "object",
        "required": [
          "ligado",
          "recomendado",
          "versoes",
          "llms",
          "vozes"
        ],
        "properties": {
          "ligado": {
            "type": "boolean"
          },
          "recomendado": {
            "type": "object",
            "properties": {
              "versao": {
                "type": "string"
              },
              "llm": {
                "type": "string"
              },
              "voz": {
                "type": "string"
              }
            }
          },
          "versoes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "nome",
                "lingua",
                "vozes"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "nome": {
                  "type": "string"
                },
                "lingua": {
                  "type": "string",
                  "enum": [
                    "pt",
                    "en"
                  ]
                },
                "vozes": {
                  "type": "boolean"
                }
              }
            }
          },
          "llms": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "nome"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "nome": {
                  "type": "string"
                }
              }
            }
          },
          "vozes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "rio",
                "sp",
                "niteroi"
              ]
            }
          }
        }
      },
      "ConversaPedido": {
        "type": "object",
        "required": [
          "type",
          "sdp"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "offer"
          },
          "sdp": {
            "type": "string",
            "maxLength": 20000,
            "description": "The full SDP offer, with complete ICE (non-trickle), up to 20,000 characters."
          },
          "versao": {
            "type": "string",
            "description": "The agent version, an id from `GET /v1/agents`. Recommended: `v0.4`."
          },
          "llm": {
            "type": "string",
            "description": "The LLM, an id from `GET /v1/agents`. Recommended: `oss120b`."
          },
          "voz": {
            "type": "string",
            "enum": [
              "rio",
              "sp",
              "niteroi"
            ],
            "description": "`rio`, `sp` or `niteroi`. Ignored on single-voice versions (`vozes: false`)."
          },
          "instrucoes": {
            "type": "string",
            "maxLength": 30000,
            "description": "System prompt, up to 30,000 characters. Replaces the Lero persona; voice rules (no markdown, code or URLs in speech) are appended."
          },
          "conhecimento": {
            "description": "Knowledge base (RAG): text or `[{titulo, texto}]`, up to 50 items and 60,000 characters. The agent consults it and never reads it aloud.",
            "oneOf": [
              {
                "type": "string",
                "maxLength": 60000
              },
              {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "object",
                  "required": [
                    "texto"
                  ],
                  "properties": {
                    "titulo": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "texto": {
                      "type": "string"
                    }
                  }
                }
              }
            ]
          },
          "abertura": {
            "type": "string",
            "maxLength": 2000,
            "description": "First message: how the agent opens the call. An instruction, not the literal sentence."
          },
          "palavras": {
            "type": "array",
            "maxItems": 40,
            "items": {
              "type": "string",
              "maxLength": 40
            },
            "description": "STT keywords: up to 40 names and terms to recognize."
          },
          "silencio_s": {
            "description": "Silence prompts. Off with `instrucoes`; `[20, 40, 60]` turns them on (2 nudges, then goodbye).",
            "oneOf": [
              {
                "type": "boolean",
                "const": false
              },
              {
                "type": "array",
                "maxItems": 3,
                "items": {
                  "type": "number",
                  "minimum": 2,
                  "maximum": 600
                }
              }
            ]
          },
          "pesquisa": {
            "type": "boolean",
            "description": "Web search tool. Off with `instrucoes`."
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 60,
            "maximum": 1000,
            "description": "Max length of each reply, 60 to 1000 (default 260)."
          }
        }
      },
      "ConversaResposta": {
        "type": "object",
        "required": [
          "type",
          "sdp"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "answer"
          },
          "sdp": {
            "type": "string"
          }
        }
      },
      "Erro": {
        "type": "object",
        "required": [
          "erro",
          "mensagem"
        ],
        "properties": {
          "erro": {
            "type": "string",
            "enum": [
              "texto_invalido",
              "voz_invalida",
              "audio_invalido",
              "url_invalida",
              "formato_invalido",
              "idioma_invalido",
              "modelo_invalido",
              "pedido_invalido",
              "sem_chave",
              "chave_invalida",
              "chave_vencida",
              "sem_credito",
              "teto_da_chave",
              "plano",
              "escopo",
              "bloqueado",
              "audio_grande",
              "audio_longo",
              "muitos_pedidos",
              "simultaneas",
              "ocupado",
              "carregando",
              "motor_desligado",
              "falhou",
              "demorou",
              "interno",
              "oferta_invalida",
              "versao_invalida",
              "llm_invalido",
              "roteiro_invalido",
              "sem_bot",
              "desligado"
            ],
            "description": "Stable error code."
          },
          "mensagem": {
            "type": "string",
            "description": "Text for humans (may change)."
          },
          "pedido": {
            "type": "string",
            "description": "The request id (speech and transcription routes)."
          },
          "campo": {
            "type": "string",
            "description": "The wrong field, on 400 errors."
          },
          "custo": {
            "type": "integer",
            "description": "On transcription `sem_credito`: the credits the audio needs."
          },
          "saldo": {
            "type": "integer",
            "description": "On transcription `sem_credito`: the account balance."
          },
          "duracao": {
            "type": "number",
            "description": "On transcription `sem_credito` and `audio_longo`: the audio length in seconds."
          },
          "cobrado": {
            "type": "integer",
            "description": "Credits charged for a failed request (0 when refunded)."
          }
        }
      }
    }
  }
}
