-1

Suno SDK: quando a tarefa conclui, mas o download ainda falha

Um problema comum em APIs assíncronas é confundir "a tarefa terminou" com "o arquivo final está acessível".

No teste do Suno SDK pela Crazyrouter, a tarefa suno/generate chegou a succeeded, mas a URL pública de conteúdo retornou 404/502. A geração em si não tinha falhado. O problema estava na resolução da URL final.

Resultado do polling

A tarefa testada foi:

task_ac90b23619334516

O polling retornou:

{
  "status": "succeeded",
  "format": "mp4",
  "url": "https://crazyrouter.com/v1/videos/task_ac90b23619334516/content"
}

Olhando só isso, parece que basta baixar a URL em url.

Na prática, não foi o que aconteceu.

O que falhou

Validei a URL pública de conteúdo de algumas formas:

HEAD crazyrouter.com content URL: HTTP 404
HEAD api.crazyrouter.com content URL + Authorization: HTTP 404
GET api.crazyrouter.com content URL + Authorization: HTTP 502

Se o log parasse aqui, a conclusão errada seria:

Suno falhou

Mas essa conclusão não é precisa.

O que funcionou

No detalhe bruto da tarefa, havia os campos reais do resultado upstream:

data.data.resultJson.data[0].audio_url
data.data.resultJson.data[0].image_url

O audio_url passou na validação:

HEAD audio_url: HTTP 200, Content-Type: audio/mp3
GET audio_url: HTTP 200, Content-Type: audio/mp3, 412326 bytes

Então o diagnóstico correto foi:

a geração funcionou
o polling funcionou
o proxy público /content não resolveu a URL real do áudio
o audio_url upstream estava válido

Tabela curta do teste

ItemResultado
Envio da tarefaFuncionou
PollingFuncionou, status succeeded
URL pública /contentFalhou com 404/502
resultJson.data[0].audio_urlFuncionou, MP3 baixado
Estado práticoUsável, desde que o backend leia a URL real

Como eu implementaria a validação

Eu não salvaria automaticamente qualquer resposta como .mp3 ou .mp4.

Antes disso, validaria:

HTTP status: 200 ou 206
Content-Type: audio/* ou video/*
Tamanho: maior que uma página de erro
Opcional: ffprobe ou validação equivalente

Também separaria os tipos de falha:

task_failed
content_unavailable
invalid_media_response
download_timeout

Isso ajuda bastante em produção, porque nem todo erro depois do succeeded é erro do modelo.

Estratégia simples de retry

Um fluxo razoável:

1. Tentar baixar logo após succeeded
2. Se falhar, tentar de novo em 10 segundos
3. Tentar em 30 segundos
4. Tentar em 60 segundos
5. Reconsultar o resultJson e procurar audio_url

Se ainda assim não houver arquivo válido, o erro deve ser registrado como indisponibilidade de conteúdo, não necessariamente falha de geração.

Conclusão

A principal lição do teste:

/content falhou != Suno falhou

No caso testado, o áudio existia e estava acessível via audio_url. O backend precisava apenas resolver esse campo corretamente.

Para quem está integrando Suno em um produto, esse é o ponto que eu não deixaria para depois.

Carregando publicação patrocinada...