API de calibração de marcas de tempo da letra

Atualizado em 2026-09-18 · equipe Suno-API

Isto não é reconhecimento de fala. O texto usa sempre a letra original que você fornece; nós apenas colocamos cada caractere no instante correto — então nunca acontece de "caracteres mal ouvidos desalinharem a letra".

Descrição do endpoint

Alinha uma letra existente com um áudio e devolve marcas de tempo por linha e por caractere, para realce caractere a caractere no estilo karaokê, letra com rolagem e geração de legendas.

Endpoint: POST /api/music/lyrics-align

Autenticação: veja Autenticação; o cabeçalho é Authorization: Bearer YOUR_API_KEY

Cobrança: cobrada por chamada (atualmente ¥0,1 por chamada por padrão); numa música da plataforma com separação de voz marcada, cobra-se mais uma vez ao preço de "separação de voz/acompanhamento". O valor realmente cobrado segue a configuração de preços do back-office.

Tempo médio: 5–15 segundos (dependendo da duração do áudio e de haver separação de voz na hora)

Por que é preciso calibrar: as marcas do lado gerador nem sempre são exatas

A API de letras com marcas de tempo devolve diretamente as marcas palavra a palavra do lado gerador e elas têm imprecisões:

A calibração refaz o alinhamento temporal sobre a letra que você fornece: só o tempo é corrigido, nunca o texto, o que serve para casos em que "bater" importa (realce por caractere no KTV, legendas por caractere, pontuação de canto).

Abordagem recomendada (três passos, melhor resultado)

  1. Extraia primeiro a voz (separação voz/acompanhamento) e alinhe apenas a faixa de voz: o acompanhamento e as harmonias deixam de interferir. Base medida: numa comparação linha a linha de "mixagem completa vs faixa de voz" da mesma música, 5 de 28 linhas divergiam mais de 0,25 s (a maior, 2,64 s); dois motores independentes divergiam em média 0,239 s na faixa de voz e 0,508 s na mixagem completa — quase metade da concordância. Por isso, para realce por caractere (KTV/legendas) recomendamos ativar. (O ganho exato está sendo medido de novo com o motor novo.)
  2. Forneça a letra completa: a música inteira, linha a linha, correspondendo um a um com o áudio. Uma frase ou seção em falta desloca todas as linhas seguintes; não inclua marcas como [00:23.82] na letra (são ignoradas automaticamente).
  3. Numa música da plataforma basta marcar vocal_separate: true e fazemos "separação + alinhamento" num passo só.

Três formas de usar

Uso O que enviar De onde vem a letra Separação de voz
Música externa · URL público audio_url + letra Você fornece ❌ Não suportado
Música externa · envio directo de ficheiro local (novo em 2026-10) audio_object_key + letra Você fornece ❌ Não suportado
Música da plataforma (gerada neste site) song_id Nós tiramos do registo da música ✅ Opcional

Como os parâmetros se relacionam (é o que mais se erra: leia com atenção)

Novo: envio directo de ficheiro local (o áudio não passa pelos nossos servidores)

Use quando o áudio está na sua máquina e prefere não o enviar primeiro para o seu próprio armazenamento público. Dois passos:

  1. POST /api/music/lyrics-align/upload-ticket com file_name / file_size / content_type e recebe um put_url (URL assinado, sem credenciais de longa duração) e um object_key;
  2. Faça PUT do ficheiro para put_url, levando o content_type da resposta tal como veio (participa na assinatura; um caractere alterado dá 403);
  3. Ao enviar o alinhamento, mande audio_object_key em vez de audio_url.

A credencial é de uso único: ao terminar o alinhamento (sucesso ou falha) o servidor apaga o objeto e reutilizar a mesma chave dá erro.

Novo: a letra passou a ser opcional

Antes, uma música externa exigia letra. Agora pode omiti-la: o servidor faz um reconhecimento e usa o texto reconhecido como letra.

O custo tem de ficar claro: o texto passa a depender do resultado do reconhecimento, pelo que algum caractere pode estar errado. Essas respostas são marcadas com lyrics_source: "asr", confidence: "low" e, em warnings[], {"code":"no_reference_lyrics"}.

Para realce por caractere / KTV, forneça sempre a letra original.

Parâmetros da requisição

Headers

Parâmetro Tipo Obrigatório Observações
Authorization string sim Bearer YOUR_API_KEY
Content-Type string sim application/json

Parâmetros do body

Parâmetro Tipo Obrigatório Padrão Observações
song_id string um de dois - ID de música da plataforma
lyrics string não - Letra original, linhas separadas por \n. Agora pode ser omitida
audio_url string um de dois para externas - Endereço do áudio; precisa ser publicamente descarregável
audio_object_key string um de dois para externas - Chave do objeto enviado diretamente (chame antes /lyrics-align/upload-ticket)
vocal_separate boolean não false Se separar a voz primeiro (só músicas da plataforma)
language string não automático Chinese / English etc.; se não enviar, deduzido da letra
granularity string não both both / line (sem saída por caractere) / word
sections string não keep keep mantém marcas como [Chorus] (não entram na linha do tempo) / drop
format string não json json / lrc / lrc-word (os dois últimos devolvem também o texto lrc e lrc_word)

Limites

Item Limite
Duração do áudio ≤ 6 minutos (mais devolve erro e reembolso total)
Origem do áudio Precisa ser publicamente descarregável; endereços que exijam sessão não são aceites
Formato da letra Texto simples, linhas com \n; marcas de seção como [Verse] ou 【主歌】 são mantidas mas não entram na linha do tempo
Lotes Uma música por chamada; para várias, faça o seu próprio ciclo
Guardar o resultado Este endpoint não persiste nada; guarde você o resultado

Exemplos de requisição

Música externa (letra + endereço do áudio)

curl -X POST https://www.suno-api.io/api/music/lyrics-align \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "lyrics": "Caminhando por ruas frias\nA brisa da noite roça meus olhos\nO tempo corre como a água",
    "audio_url": "https://your-bucket.example.com/song.mp3"
  }'

Música da plataforma (sem separação)

curl -X POST https://www.suno-api.io/api/music/lyrics-align \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"song_id": "17e52af7-b5df-4877-a98a-dce94e0e6aa2"}'

Música da plataforma + separação de voz (recomendado para karaokê)

curl -X POST https://www.suno-api.io/api/music/lyrics-align \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"song_id": "17e52af7-b5df-4877-a98a-dce94e0e6aa2", "vocal_separate": true}'

Resposta

Resposta de sucesso

{
  "success": true,
  "lyrics_source": "platform",
  "vocal_separate": false,
  "coverage": 0.935,
  "exact": 196,
  "fuzzy": 4,
  "total": 214,
  "lines": [
    {
      "text": "Caminhando por ruas frias",
      "start": 21.66,
      "end": 24.06,
      "chars": [
        {"char": "C", "start": 21.66, "end": 21.74, "word": true},
        {"char": "a", "start": 21.98, "end": 22.22, "word": true}
      ]
    }
  ]
}

Referência dos campos

Campo Tipo Observações
success boolean Se a requisição foi bem-sucedida
lyrics_source string platform = letra tirada da música da plataforma; user = letra fornecida por você; asr = não deu letra e o texto veio do reconhecimento
vocal_separate boolean Se desta vez passou por separação de voz
confidence string high / low (sempre low quando lyrics_source=asr)
warnings[] array Avisos de degradação; contém {"code":"no_reference_lyrics"} quando não houve letra
coverage number Qualidade do alinhamento: proporção de caracteres com âncora temporal clara (0–1)
exact / fuzzy / total number Caracteres exatos / homófonos / caracteres válidos da letra
lines[].text string Uma linha da letra, caractere a caractere igual ao seu original
lines[].start / end number Início e fim da linha (segundos)
lines[].section boolean Se a linha é marca de seção (true = sem tempo e sem realce)
lines[].chars[] array Tempos por caractere: char, start/end em segundos, word se entra na linha do tempo (pontuação é false)
words[] array Lista plana por caractere: text / start / end / line; não é devolvida com granularity=line
lrc string Texto LRC por linha (só com format=lrc ou lrc-word)
lrc_word string LRC por caractere melhorado, com etiquetas <mm:ss.xx> na linha (só com format=lrc-word)

Como usar o coverage (três faixas)

coverage Uso sugerido
≥ 0,9 Dá para realce por caractere (karaokê)
0,8 – 0,9 Mistura por caractere e por linha, ou realce só por linha com o caractere como referência
< 0,8 Apenas realce por linha (repetições, harmonias densas, dialetos e rap tendem a sair baixo)

Estado e tempos

Cenário Tempo medido
Música da plataforma · sem separação cerca de 4,5 s
Música da plataforma · separação (já há faixa de voz) cerca de 11 s
Música da plataforma · separação (é preciso separar na hora) cerca de 25 s, até cerca de 1 minuto
Música externa · letra + endereço do áudio cerca de 5–15 s (conforme a duração)

O limite de uma execução no servidor é 8 minutos; defina o timeout do cliente em 120 segundos ou mais.

Respostas de erro

{
  "success": false,
  "message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
Cenário Cobra?
Falta o áudio (nenhum dos três) Não cobra (processamento não iniciado)
audio_url e audio_object_key ao mesmo tempo Não cobra (processamento não iniciado)
O objeto do envio directo ainda não está ou já foi apagado Não cobra (processamento não iniciado)
granularity / sections / format inválidos Não cobra (processamento não iniciado)
A música da plataforma não existe / não é da conta atual Não cobra (processamento não iniciado)
Parâmetros em falta ou inválidos Não cobra (processamento não iniciado)
Áudio acima do limite de 6 minutos Reembolso total
Áudio não descarregável (endereço não público / exige login) Reembolso total
Sem letra e o reconhecimento do servidor falhou Reembolso total
Marcou separação de voz mas não há faixa utilizável Reembolso total (incluindo o preço da separação)
Falha ou timeout do serviço de alinhamento Reembolso total

Princípio: sem resultado final, reembolso total. Só se cobra quando as marcas por caractere são realmente devolvidas, e o reembolso é automático, sem pedido.

Cobrança

Item Quando é cobrado Observações
Calibração das marcas da letra (base) Em cada chamada Por chamada (atualmente ¥0,1 por chamada por padrão); o valor real segue a configuração de preços do back-office
Taxa adicional de transcrição Só quando não fornece letra O servidor tem de correr um reconhecimento de fala, um custo que o escalão "com letra" não tem, por isso é tarifado à parte
Separação de voz (opcional, só músicas da plataforma) Ao marcar vocal_separate É cobrada uma vez ao preço atual de "separação de voz/acompanhamento" e liquidada junto com este endpoint

A combinação:

a pagar = preço base + (sem letra ? taxa de transcrição : 0) + (separação marcada ? preço da separação : 0)

A separação de voz é cobrada uma só vez: se já separou e tem a faixa de voz disponível, cobra-a este endpoint; se for preciso separar na hora, cobra-a o passo de separação.

Exemplo completo (Python)

import requests

API_KEY = "YOUR_API_KEY"
BASE = "https://www.suno-api.io"

def align_lyrics(song_id=None, lyrics=None, audio_url=None, vocal_separate=False):
    payload = {}
    if song_id:
        payload["song_id"] = song_id
        payload["vocal_separate"] = vocal_separate
    else:
        payload["lyrics"] = lyrics
        payload["audio_url"] = audio_url

    r = requests.post(
        f"{BASE}/api/music/lyrics-align",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json=payload,
        timeout=600,
    )
    data = r.json()
    if not data.get("success"):
        raise RuntimeError(data.get("message"))
    return data


res = align_lyrics(song_id="17e52af7-b5df-4877-a98a-dce94e0e6aa2", vocal_separate=True)
print("qualidade do alinhamento coverage =", res["coverage"])
for line in res["lines"]:
    print(f'{line["start"]:7.2f}  {line["text"]}')
    # karaokê por caractere: cada caractere em line["chars"] tem o seu start / end

Perguntas frequentes

P: A saída é por caractere ou por linha? R: Ambas. lines[].start é por linha e lines[].chars[].start / end por caractere; o reprodutor usa a que precisar.

P: Porque é que o texto devolvido é igual ao que enviei? R: É o desenho. Não reconhecemos nem reescrevemos, só alinhamos tempos, por isso a letra nunca é "corrigida para gralha".

P: O coverage é alto mas ainda soa ligeiramente desviado. R: O erro por caractere costuma andar nas dezenas de milissegundos; se a música toda estiver desviada um valor fixo, é provável que haja um trecho de silêncio no início do áudio: corte-o e tente de novo.

P: Porque é que há pouco a separação servia e agora diz "faixa de voz indisponível"? R: Os resultados da separação são endereços temporários de vida curta (medido: caducam por volta de meia hora depois). Nesse caso o endpoint tenta separar outra vez; se mesmo assim falhar, há reembolso total. Portanto "separar agora e calibrar depois" não é fiável: faça as duas coisas no mesmo fluxo.

P: Preciso de separar eu próprio uma música da plataforma? R: Não. Com vocal_separate: true verificamos se a música já tem faixa de voz; se não houver uma utilizável, dá erro e reembolsa em vez de despachar a mixagem completa.

P: Dá para fazer lotes? R: Uma música por pedido. Para lotes, faça um ciclo; cada chamada é cobrada normalmente, por isso recomenda-se guardar os resultados em cache.

P: O resultado fica guardado? R: Este endpoint não persiste nada; guarde você o valor devolvido (as marcas por linha e por caractere vão na resposta).

PróximoAPI de certificado de licença comercial de música

Obter uma chave de API

Crie uma chave de API no console após o cadastro. Cada geração custa ¥0,6 e devolve 2 faixas, os downloads são ilimitados e não é preciso número de telefone.

Obter chave de API Voltar à visão geral