Providers
The API supports several lyrics providers. They differ in coverage, timing detail and response format. The default endpoint uses TTML, and you can pick another provider when you need to.
Available providers
TTML
DefaultSyllable-synced lyrics with precise timing.
| Endpoint | /getLyrics or /ttml/getLyrics |
| Sync level | Syllable |
| Best for | Karaoke-style display, syllable highlighting |
| Response format | TTML XML |
Kugou
Line-synced lyrics with broad coverage.
| Endpoint | /kugou/getLyrics |
| Sync level | Line |
| Best for | Line-by-line display, fallback coverage |
| Response format | LRC-style text |
Word-timed lyrics, useful when TTML has no match.
| Endpoint | /qq/getLyrics |
| Sync level | Word |
| Best for | Word highlighting when TTML returns no results |
| Response format | QRC XML |
Choosing a provider
Use the default TTML provider unless you need something else:
- TTML has the best overall coverage and precision. Use it for karaoke-style syllable highlighting.
- Kugou is line-synced with broad coverage. Use it if TTML returns no results.
- QQ is word-timed. Use it if TTML returns no results and you still want timing finer than a line.
Response differences
Each provider returns a different format. @braccato/parsers
reads all three into the same line structure, so you can switch providers without changing your
rendering code.
TTML response
/getLyrics returns:
{
"ttml": "<?xml version=\"1.0\"?>..."
} /ttml/getLyrics uses the same shape as the other provider-specific endpoints:
{
"lyrics": "<?xml version=\"1.0\"?>...",
"provider": "ttml"
} Kugou response
{
"lyrics": "[00:12.34]First line of lyrics\n[00:15.67]Second line...",
"provider": "kugou"
} QQ response
{
"lyrics": "<?xml version="1.0" encoding="utf-8"?><QrcInfos>...[5767,324]Wanderlust - (5767,109)The (5876,106)Weeknd(5982,109)...</QrcInfos>",
"provider": "qq"
} The QRC body sits inside an XML envelope, with word timing after each word. See QRC format for the structure and how to parse it.
Provider-specific headers
The provider-specific endpoints send an X-Provider header that indicates which provider served
the response. /getLyrics does not send it:
X-Provider: ttml Cache isolation
Each provider has its own cache namespace. A song cached via TTML will not be served when you request via Kugou or QQ, and the other way around. That way you always get the format you asked for.
Cache key prefixes:
ttml_lyrics:for TTMLkugou_lyrics:for Kugouqq_lyrics:for QQ
/getLyrics and /ttml/getLyrics both use ttml_lyrics:, but format the album and
duration in the key differently, so they share entries only when neither album nor duration is sent.