{"openapi":"3.0.3","info":{"title":"W Studio API","version":"2.4.0","description":"API REST para gerar audio (motores Ultra, Ultra V3, Clone Fast, Clone Ultra, Neural e Padrao HD), musica e imagens via Image Studio. Use uma das API keys criadas no dashboard em \"API & Integracoes\" (formato `wsv_live_xxx`) e envie no header `Authorization: Bearer <key>`. Rate limit: 10 requisicoes a cada 90 segundos por chave."},"servers":[{"url":"https://wstudios.app","description":"Servidor atual"}],"tags":[{"name":"Conta","description":"Informacoes da conta autenticada"},{"name":"Vozes","description":"Catalogo consolidado de vozes disponiveis"},{"name":"TTS","description":"Geracao de fala (text-to-speech)"},{"name":"Audio","description":"Download de audios gerados"},{"name":"Historico","description":"Historico de chamadas"},{"name":"Musica","description":"Geracao de musica"},{"name":"Novidades","description":"Novidades da API: aviso automatico no campo notices de toda resposta"}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"API key do cliente no formato `wsv_live_xxx`. Exemplo: `Authorization: Bearer wsv_live_abc123...`. Crie uma chave em /api-dashboard."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Mensagem de erro legivel"},"code":{"type":"string","nullable":true,"example":"VOICE_ID_OUTDATED"},"provider":{"type":"string","nullable":true,"example":"voice"},"provider_status":{"type":"integer","nullable":true,"example":404},"retryable":{"type":"boolean","nullable":true,"example":false},"voices_url":{"type":"string","nullable":true,"example":"/api/v1/voices"}},"required":["error"]},"Account":{"type":"object","properties":{"id":{"type":"integer","example":42},"email":{"type":"string","format":"email","example":"cliente@example.com"},"display_name":{"type":"string","example":"Joao da Silva"},"credits":{"type":"integer","description":"Creditos disponiveis","example":1500},"plan":{"type":"string","enum":["standard","premium","admin"],"example":"standard"},"rate_limit":{"type":"string","example":"10/90s","description":"Limite da API key. Cliente Premium retorna unlimited."},"created_at":{"type":"string","format":"date-time","nullable":true}},"required":["id","email","credits","plan"]},"Model":{"type":"object","properties":{"model_id":{"type":"string","enum":["eleven_v4","eleven_v4_turbo","neural-v1","padrao-hd","ultra-v2","ultra-v3","clone-fast-v2","clone-ultra-max"],"example":"clone-fast-v2"},"provider":{"type":"string","enum":["ultra","ultra-v3","ultra-v4","padrao","neural","clone-fast","clone-ultra"],"example":"clone-fast"},"name":{"type":"string","example":"Clone Fast"},"description":{"type":"string"},"max_text_length":{"type":"integer","example":200000},"supports_voice_clone":{"type":"boolean","example":true},"provider_aliases":{"type":"array","items":{"type":"string"}}},"required":["model_id","provider","name"]},"Voice":{"type":"object","properties":{"id":{"type":"string","example":"pt-BR-FranciscaNeural"},"name":{"type":"string","example":"Francisca"},"provider":{"type":"string","enum":["ultra","ultra-v3","ultra-v4","padrao","neural","clone-fast","clone-ultra"],"example":"neural"},"model_id":{"type":"string","enum":["eleven_v4","eleven_v4_turbo","neural-v1","padrao-hd","ultra-v2","ultra-v3","clone-fast-v2","clone-ultra-max"],"example":"neural-v1"},"language":{"type":"string","example":"pt-BR"},"locale":{"type":"string","nullable":true,"example":"pt-br"},"gender":{"type":"string","enum":["male","female","neutral",""],"example":"female"},"age":{"type":"string","nullable":true,"example":"young"},"accent":{"type":"string","nullable":true,"example":"Brazilian"},"category":{"type":"string","nullable":true,"example":"professional"},"description":{"type":"string","nullable":true},"use_case":{"type":"string","nullable":true,"example":"narration"},"catalog_voice_id":{"type":"string","nullable":true,"description":"ID oficial da voz no catálogo. Para gerar áudio, envie o campo id desta resposta como voice_id."},"preview_url":{"type":"string","format":"uri","nullable":true,"description":"Preview da voz. Para clone privado, URL assinada e temporária."},"is_clone":{"type":"boolean","description":"Presente quando a voz foi clonada pela própria conta ou é global.","example":false},"clone_code":{"type":"string","nullable":true,"example":"MMX-A1B2C3D4"},"preview_text":{"type":"string","nullable":true,"description":"Texto usado no preview persistente da voz clonada."}},"required":["id","name","provider"]},"TtsRequest":{"type":"object","description":"Parametros da geracao de fala","properties":{"text":{"type":"string","minLength":1,"maxLength":200000,"description":"Texto a ser sintetizado. Aceita o roteiro inteiro (ate 200.000 caracteres; Edge ate 1.000.000).","example":"Ola! Este e um teste de geracao de voz."},"voice_id":{"type":"string","description":"ID da voz (use GET /api/v1/voices para listar)","example":"pt-BR-FranciscaNeural"},"provider":{"type":"string","enum":["ultra","ultra-v3","ultra-v4","padrao","neural","clone-fast","clone-ultra"],"description":"Use exatamente o provider devolvido junto da voz em GET /api/v1/voices (ultra, ultra-v3, padrao, neural, clone-fast ou clone-ultra).","example":"neural"},"language":{"type":"string","description":"Idioma BCP-47 opcional (default: detecta do voice_id)","example":"pt-BR"},"speed":{"type":"number","minimum":0.5,"maximum":2,"description":"Velocidade da fala (1.0 = normal)","example":1},"model_id":{"type":"string","enum":["eleven_v4","eleven_v4_turbo","neural-v1","padrao-hd","ultra-v2","ultra-v3","clone-fast-v2","clone-ultra-max"],"description":"Opcional. Quando informado, precisa ser o model_id do mesmo provider em GET /api/v1/models.","example":"eleven_v3"},"stability":{"type":"number","minimum":0,"maximum":1,"description":"Opcional para ultra-v3.","example":0.5},"similarity_boost":{"type":"number","minimum":0,"maximum":1,"description":"Opcional para ultra-v3.","example":0.75},"style":{"type":"number","minimum":0,"maximum":1,"description":"Opcional para ultra-v3.","example":0},"use_speaker_boost":{"type":"boolean","description":"Opcional para ultra-v3.","example":true},"title":{"type":"string","maxLength":255,"description":"Titulo opcional para o audio gerado","example":"Teste de TTS"}},"required":["text","voice_id","provider"]},"TtsResponse":{"type":"object","properties":{"id":{"type":"string","description":"ID da task de geracao (use em /api/v1/audio/{id})","example":"tts_1734567890_abc"},"status":{"type":"string","enum":["doing","done","failed"],"example":"doing"},"url":{"type":"string","nullable":true,"description":"URL do audio (somente quando status=done)","example":"/generated/audio_abc.mp3"},"duration_seconds":{"type":"number","nullable":true,"example":3.2},"credits_used":{"type":"integer","example":10},"credits_remaining":{"type":"integer","example":1490}},"required":["id","status","credits_used","credits_remaining"]},"InsufficientCredits":{"type":"object","properties":{"error":{"type":"string","example":"Saldo insuficiente"},"credits_needed":{"type":"integer","example":10},"credits_available":{"type":"integer","example":0}}},"HistoryItem":{"type":"object","properties":{"id":{"type":"integer","example":1234},"task_id":{"type":"string","example":"tts_1734567890_abc"},"provider":{"type":"string","example":"neural"},"voice_id":{"type":"string","example":"pt-BR-FranciscaNeural"},"text_preview":{"type":"string","maxLength":200,"example":"Ola! Este e um teste..."},"credits_used":{"type":"integer","example":10},"duration_ms":{"type":"integer","example":1234},"status":{"type":"string","enum":["done"],"example":"done"},"created_at":{"type":"string","format":"date-time"}}}},"responses":{"Unauthorized":{"description":"API key ausente, invalida ou revogada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"API key invalida ou revogada"}}}},"RateLimited":{"description":"Limite de 60 requisicoes/min por chave excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Limite de requisicoes excedido. Tente novamente em 1 minuto."}}}}}},"security":[{"BearerAuth":[]}],"paths":{"/api/v1/account":{"get":{"tags":["Conta"],"summary":"Get account info","description":"Retorna informacoes da conta associada a API key (id, email, creditos, plano).","operationId":"getAccount","responses":{"200":{"description":"Conta encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"},"example":{"id":42,"email":"cliente@example.com","display_name":"Joao da Silva","credits":1500,"plan":"standard","created_at":"2025-01-15T10:30:00.000Z"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Usuario nao encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"description":"Erro interno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/models":{"get":{"tags":["Vozes"],"summary":"List supported voice models","description":"Lista as seis opções de geração expostas pela API e indica o provider a ser usado ao escolher uma voz.","operationId":"listModels","responses":{"200":{"description":"Modelos disponíveis","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"models":{"type":"array","items":{"$ref":"#/components/schemas/Model"}},"providers":{"type":"array","items":{"type":"object"}},"voices_url":{"type":"string","example":"/api/v1/voices"}},"required":["success","models"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/voices":{"get":{"tags":["Vozes"],"summary":"List available voices","description":"Lista as vozes disponíveis para geração no W Studios, com o id de geração e o catalog_voice_id oficial. Os motores são anunciados por nomes neutros (ultra, ultra-v3, padrao, neural, clone-fast, clone-ultra). Para a biblioteca V3 paginada, use provider=ultra-v3. Vozes clonadas retornam somente para o dono da API key, administradores ou quando globais.","operationId":"listVoices","parameters":[{"name":"provider","in":"query","required":false,"schema":{"type":"string","enum":["ultra","ultra-v3","ultra-v4","padrao","neural","clone-fast","clone-ultra"]},"description":"Filtra por provider. Use ultra-v3 para a biblioteca premium paginada; clone-fast/clone-ultra retornam também as vozes clonadas próprias e globais."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":24}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"language","in":"query","required":false,"schema":{"type":"string"}},{"name":"locale","in":"query","required":false,"schema":{"type":"string"}},{"name":"gender","in":"query","required":false,"schema":{"type":"string"}},{"name":"age","in":"query","required":false,"schema":{"type":"string"}},{"name":"accent","in":"query","required":false,"schema":{"type":"string"}},{"name":"category","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Lista de vozes","content":{"application/json":{"schema":{"type":"object","properties":{"voices":{"type":"array","items":{"$ref":"#/components/schemas/Voice"}},"pagination":{"type":"object","nullable":true,"description":"Presente no catalogo paginado ultra-v3."},"pricing":{"type":"object","nullable":true,"description":"Preco atual do catalogo solicitado."}},"required":["voices"]},"example":{"voices":[{"id":"pt-BR-FranciscaNeural","name":"Francisca","provider":"edge","language":"pt-BR","gender":"female","preview_url":"https://example.com/preview.mp3"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"description":"Erro interno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tts/estimate":{"post":{"tags":["TTS"],"summary":"Estimar V4/V4 Turbo beta sem gerar","description":"Mesmo corpo do TTS V4. Até 50000 caracteres; partes até 5000. Preço V4 4/promo2 e Turbo8/promo6 por caractere, até 30/10/2026 America/Sao_Paulo inclusive.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","voice_id","model_id"],"properties":{"text":{"type":"string","maxLength":50000},"voice_id":{"type":"string"},"model_id":{"type":"string","enum":["eleven_v4","eleven_v4_turbo"]},"provider":{"type":"string","enum":["ultra-v4"]},"voice_settings":{"type":"object"}}}}}},"responses":{"200":{"description":"Estimativa, partes, beta e preço congelado somente no aceite"},"400":{"description":"Entrada inválida"},"401":{"description":"Bearer obrigatório"}}}},"/api/v1/tts":{"post":{"tags":["TTS"],"summary":"Generate speech","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string","maxLength":180},"description":"Obrigatório para V4: identidade por usuário/roteiro; replay sem novo débito, divergência 409."}],"description":"Cria uma task de geracao de fala. Pode retornar `status: \"done\"` sincrono (Edge local) ou `status: \"doing\"` (Ultra/Ultra V3/Clone) — neste caso, faca polling em GET /api/v1/audio/{id}. Adição beta: provider ultra-v4, model_id eleven_v4 ou eleven_v4_turbo; text até 50000 caracteres, voz oficial V4 e Idempotency-Key obrigatório. Um ID/MP3 final, intervalo interno 0.5s. V4 4 créditos/caractere (promo2), Turbo8 (promo6) até 30/10/2026 inclusive America/Sao_Paulo. Sem mudança nos modelos/defaults antigos. V4 usa fila dedicada persistente: waiting/doing/done/failed; até 50000 caracteres por pedido, partes internas até 5000, um ID e um MP3. Idempotency-Key obrigatório no V4; replay igual retorna o pedido existente, payload diferente 409. Aceite ambíguo não é reenviado automaticamente. Não há SLA nem posição pública de fila. Consulte o áudio com espera entre tentativas; respeite 429/Retry-After. Estime antes de gerar; preço vigente fica congelado no aceite.\n\n### V4: IDs oficiais, erros e retomada segura\nPara `provider: ultra-v4`, use `model_id: eleven_v4` ou `eleven_v4_turbo` e `voice_id` oficial ElevenLabs: exatamente 20 caracteres alfanuméricos. Consulte `GET /api/v1/voices?provider=ultra-v4` com a mesma API key. IDs internos/UUID só são traduzidos quando o catálogo existente identifica um único ID oficial; sem correspondência inequívoca são recusados antes de criar tarefa/debitar. Não copie UUIDs de outros motores. Limite: 50.000 caracteres por roteiro, dividido internamente em partes de até 5.000.\n\n- HTTP 400 `INVALID_VOICE_ID` / `INVALID_MODEL_ID`: corrija o corpo; nenhuma tarefa ou cobrança criada.\n- HTTP 400 `VOICE_ID_UNAVAILABLE`: voz não disponível no motor; sem retry automático. Atualize o catálogo/escolha outra voz.\n- HTTP 503 `UPSTREAM_CREDITS`: saldo do motor indisponível; contate suporte (não é o seu saldo WStudios).\n- `UPSTREAM_BUSY`: rejeição HTTP 429 ou 503 claramente por limite/concorrência: envio inicial + no máximo 3 retentativas, esperas 2s/5s/10s.\n- `UPSTREAM_TRANSIENT`: outra resposta HTTP não-2xx; parte volta para fila e outro tick tenta novamente (30s), até 4 envios ou 6 ciclos de consulta por parte persistidos no banco. Uma única falha transitória não encerra o roteiro.\n- HTTP 409 `AMBIGUOUS_SUBMIT`: timeout/queda sem resposta ou aceite sem identidade; pode ter sido aceito. Não crie nova chave nem reenvie automaticamente; contate suporte. Replay também é bloqueado.\n- HTTP 409 `RETRY_EXHAUSTED`: teto persistido atingido; contate suporte.\n- HTTP 409 `IDEMPOTENCY_CONFLICT`: mesma chave com conteúdo divergente.\n\nConsulte `GET /api/v1/audio/:id`: 202 ainda pendente (pode incluir `code`, `reason`, `retryable`); erro terminal inclui código acionável, motivo, `provider_status`, `refunded`. Em falha recuperável, reenviar exatamente o mesmo corpo e a mesma `Idempotency-Key` retoma o mesmo job, partes prontas e IDs upstream conhecidos, sem nova cobrança ou repetição de partes. Mudança de corpo mantém 409. Pedidos de aceite ambíguo e limite esgotado NÃO são retomados. Estorno já aplicado não é removido, repetido ou cobrado de novo. Não rode polling de falha terminal indefinidamente.\n","operationId":"generateSpeech","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsRequest"},"example":{"text":"Ola! Este e um teste de geracao de voz.","voice_id":"pt-BR-FranciscaNeural","provider":"edge","speed":1}}}},"responses":{"200":{"description":"Task criada (pode ja estar concluida)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsResponse"},"example":{"id":"tts_1734567890_abc","status":"doing","url":null,"duration_seconds":null,"credits_used":0,"credits_remaining":1500}}}},"400":{"description":"Parametros invalidos (text vazio, provider desconhecido, etc.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"text obrigatorio; provider invalido"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Saldo insuficiente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCredits"},"example":{"error":"Saldo insuficiente","credits_needed":10,"credits_available":0}}}},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"description":"O provedor externo recusou ou não conseguiu iniciar a geração. O corpo informa code e retryable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provedor temporariamente indisponível ou não configurado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/audio/{id}":{"get":{"tags":["Audio"],"summary":"Download generated audio","description":"Faz streaming do audio gerado (audio/mpeg por padrao). Para tasks ainda em processamento, retorna 202 com o status atual.","operationId":"downloadAudio","parameters":[{"name":"id","in":"path","required":true,"description":"ID da task (campo `id` retornado por POST /api/v1/tts)","schema":{"type":"string","example":"tts_1734567890_abc"}}],"responses":{"200":{"description":"Audio (binario)","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}},"audio/ogg":{"schema":{"type":"string","format":"binary"}},"audio/mp4":{"schema":{"type":"string","format":"binary"}}}},"202":{"description":"Audio ainda nao esta pronto (status=doing)","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"doing"},"message":{"type":"string","example":"Audio ainda nao esta pronto"}}}}}},"400":{"description":"ID invalido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Audio nao encontrado ou arquivo removido do disco","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Geração falhou (terminal; antes usava 502). Campos antigos preservados.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["failed"]},"error":{"type":"string"},"code":{"type":"string","example":"GENERATION_FAILED"},"retryable":{"type":"boolean"},"reason":{"type":"string","nullable":true},"provider":{"type":"string"},"refunded":{"type":"boolean"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"description":"Falha real de comunicação/download com upstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/history":{"get":{"tags":["Historico"],"summary":"List call history","description":"Lista as ultimas chamadas bem-sucedidas da API. Default: TTS (POST /api/v1/tts com 200). Ordenado por mais recente.","operationId":"listHistory","parameters":[{"name":"kind","in":"query","required":false,"description":"Tipo de historico: tts","schema":{"type":"string","enum":["tts"],"default":"tts"}},{"name":"limit","in":"query","required":false,"description":"Quantidade maxima de itens (1-200, default 50)","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","required":false,"description":"Offset de paginacao (default 0)","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Lista de chamadas","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/HistoryItem"}},"total":{"type":"integer","example":87},"limit":{"type":"integer","example":50},"offset":{"type":"integer","example":0}},"required":["items","total","limit","offset"]},"example":{"items":[{"id":1234,"task_id":"tts_1734567890_abc","provider":"edge","voice_id":"pt-BR-FranciscaNeural","text_preview":"Ola! Este e um teste...","credits_used":10,"duration_ms":1234,"status":"done","created_at":"2025-01-15T10:35:00.000Z"}],"total":87,"limit":50,"offset":0}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"description":"Erro interno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/music":{"post":{"tags":["Musica"],"summary":"Gerar musica","description":"Gera musica com o motor de musica do W Studios. Aceita dois formatos de entrada: por descricao (campo idea, opcionalmente instrumental: true) ou com letra (lyrics, opcionalmente tags de estilo). Custo: 3.000 creditos por envio. Fluxo assincrono: a resposta devolve id + status; acompanhe em GET /api/v1/audio/{id} a cada ~15 segundos (limite de 10 requisicoes a cada 90 segundos por chave) e, quando o status for done, esse mesmo endpoint devolve o arquivo de audio. Falha no provedor devolve os creditos automaticamente.","operationId":"generateMusic","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"idea":{"type":"string","maxLength":500,"description":"Descricao da musica (uma das duas entradas possiveis)."},"lyrics":{"type":"string","maxLength":5000,"description":"Letra da musica (alternativa a idea)."},"tags":{"type":"string","maxLength":1000,"description":"Estilo/estrutura da musica."},"instrumental":{"type":"boolean","default":false,"description":"Sem voz. Nao aceita lyrics junto."},"title":{"type":"string","maxLength":80,"description":"Nome da faixa."},"vocal_gender":{"type":"string","enum":["m","f"],"description":"Genero da voz."},"provider":{"type":"string","enum":["musica"],"default":"musica","description":"Motor de musica. Valor publico: musica."},"model":{"type":"string","description":"Aceito por compatibilidade."},"receive_url":{"type":"string","description":"URL de callback opcional (o webhook do painel continua valendo)."}}},"example":{"idea":"Sertanejo universitario animado sobre estrada e liberdade","title":"Estrada"}}}},"responses":{"200":{"description":"Tarefa criada (assincrona)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","example":"doing"},"provider":{"type":"string","example":"musica"},"versions":{"type":"integer"},"url":{"type":"string","nullable":true},"credits_used":{"type":"integer"},"credits_remaining":{"type":"integer","nullable":true},"has_srt":{"type":"boolean"},"srt_url":{"type":"string","nullable":true},"notices":{"type":"array","items":{"$ref":"#/components/schemas/ApiNotice"},"description":"Novidades da API (aparece uma vez por chave)."}}},"example":{"id":"task_1734567890_abc","status":"doing","provider":"musica","versions":1,"url":null,"credits_used":2500,"credits_remaining":7500,"has_srt":false,"srt_url":null}}}},"400":{"description":"Payload invalido (sem idea/lyrics, instrumental com letra, provider desconhecido)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Creditos insuficientes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"description":"Falha no provedor (creditos devolvidos automaticamente)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/voice-clone":{"post":{"tags":["Vozes"],"summary":"Clonar voz","description":"Cria uma voz clonada a partir de um MP3. A voz fica disponivel imediatamente no catalogo (GET /api/v1/voices, provider clone-fast ou clone-ultra) e pode ser usada em POST /api/v1/tts pelo voice_id retornado. model=minimax-fast aceita MP3 ate 20MB e exige gender_tag (male/female); model=minimax-ultra aceita MP3 ate 5MB e gender_tag e opcional. O servidor normaliza o audio para os primeiros 10 segundos. Nao consome creditos.","operationId":"cloneVoice","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","voice_name","language_tag"],"properties":{"file":{"type":"string","format":"binary","description":"MP3 de exemplo (uma voz, sem musica de fundo)."},"voice_name":{"type":"string","minLength":2,"maxLength":80,"description":"Nome da voz clonada."},"language_tag":{"type":"string","example":"Portuguese","description":"Nome completo do idioma (Portuguese, English, Spanish...)."},"gender_tag":{"type":"string","enum":["male","female"],"description":"Obrigatorio no minimax-fast; opcional no minimax-ultra."},"model":{"type":"string","enum":["minimax-fast","minimax-ultra"],"default":"minimax-fast","description":"Modelo de clonagem."}}},"encoding":{"file":{"contentType":"audio/mpeg"}}}}},"responses":{"200":{"description":"Voz clonada","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"model":{"type":"string","example":"minimax-fast"},"voice_id":{"type":"string","example":"2705228"},"clone_code":{"type":"string","example":"MMX-ABC116AB"},"voice_name":{"type":"string"},"language_tag":{"type":"string"},"gender_tag":{"type":"string","nullable":true},"preview_text":{"type":"string"},"preview_url":{"type":"string","nullable":true},"status":{"type":"string","example":"completed"}}}}}},"400":{"description":"Arquivo/idioma/genero invalido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Idioma invalido (language_tag)."}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/audio/{id}/srt":{"get":{"tags":["Audio"],"summary":"Baixar legenda SRT da própria tarefa","description":"SRT nativo quando disponível; nos motores com legenda local o texto é distribuído proporcionalmente à duração real ou estimada: não é alinhamento por palavra. Música usa letra e duração da primeira faixa; instrumental sem letra não tem SRT. JSON informa srt_mode e duration_estimated quando aproximado. Exige tarefa do titular não excluída.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string","enum":["json"]}}],"responses":{"200":{"description":"SRT UTF-8 com BOM ou JSON","content":{"application/x-subrip":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","properties":{"task_id":{"type":"string"},"srt":{"type":"string"},"srt_mode":{"type":"string","enum":["native","approximate"]},"duration_estimated":{"type":"boolean"}}}}}},"202":{"description":"Tarefa ainda não finalizada"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Tarefa/SRT indisponível, excluído ou de outro titular"},"502":{"description":"Falha temporária ao consultar legenda"}}}},"/api/v1/changelog":{"get":{"tags":["Novidades"],"summary":"Novidades da API (changelog)","description":"Lista as novidades da API em ordem decrescente de data. Alem deste endpoint, TODA resposta /api/v1/* traz o campo notices com as novidades ainda nao vistas pela sua chave (aparece uma unica vez), alem dos headers X-WStudios-API-Changelog e X-WStudios-API-News. Assim o seu sistema consegue avisar os seus usuarios automaticamente quando um recurso novo entra no ar, sem precisar ler documentacao.","operationId":"getApiChangelog","parameters":[{"name":"ack","in":"query","required":false,"schema":{"type":"string","enum":["1"]},"description":"Use ack=1 para marcar todas as novidades como lidas e parar de receber em notices."}],"responses":{"200":{"description":"Lista das novidades","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"latest":{"type":"string","nullable":true},"total":{"type":"integer"},"unseen":{"type":"array","items":{"type":"string"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiNotice"}}}},"example":{"success":true,"latest":"2026-10-01-avisos-automaticos","total":1,"unseen":["2026-10-01-avisos-automaticos"],"items":[{"id":"2026-10-01-avisos-automaticos","date":"2026-10-01","type":"feature","title":"Musica na API: geracao de musica ativa","summary":"A rota POST /api/v1/music aceita provider: \"musica\".","message":"A rota POST /api/v1/music agora aceita o campo provider...","docs_url":"/api-docs","action_suggestion":"Ative a geracao de musica na sua interface."}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}}}}