# GET /revalidate

GET `/revalidate`

Refetch lyrics for a song that is already cached, and replace the cache entry when the content changed. This works for both found lyrics and cached "no lyrics" results. Requires a valid API key. It refreshes only the default TTML entry that `/getLyrics` serves.

## Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `s`, `song`, `songName` | string | Always send | Song name. |
| `a`, `artist`, `artistName` | string | Always send | Artist name. |
| `al`, `album`, `albumName` | string | Always send | Album name. Improves matching. |
| `d`, `duration` | string of digits | Always send | Track duration in whole seconds. Improves matching. |

## Headers

| Name | Required | Description |
| --- | --- | --- |
| `X-API-Key` | Yes | Valid API key. The endpoint works only when the server enforces API keys. |

## Example request

   

```bash
curl -H "X-API-Key: your-api-key" \
  "https://api.betterlyrics.org/revalidate?s=E85&a=Don%20Toliver&al=OCTANE&d=154"
```

```javascript
const res = await fetch("https://api.betterlyrics.org/revalidate?s=E85&a=Don%20Toliver&al=OCTANE&d=154", {
  headers: { "X-API-Key": "your-api-key" },
});
const data = await res.json();
```

```python
import requests

res = requests.get(
    "https://api.betterlyrics.org/revalidate?s=E85&a=Don%20Toliver&al=OCTANE&d=154",
    headers={"X-API-Key": "your-api-key"},
)
data = res.json()
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://api.betterlyrics.org/revalidate?s=E85&a=Don%20Toliver&al=OCTANE&d=154", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", "your-api-key")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(body))
}
```

## Success response

Status: `200 OK`

```json
{
  "updated": true,
  "cacheKey": "ttml_lyrics:e85 don toliver octane 154s",
  "wasNegativeCache": false
}
```

When the upstream fetch fails or finds no lyrics, the status is still `200 OK`. The cache entry is not changed:

```json
{
  "error": "no lyrics found from source",
  "updated": false,
  "cacheKey": "ttml_lyrics:e85 don toliver octane 154s"
}
```

## Response fields

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `updated` | boolean | Yes | `true` when the cached content changed. |
| `cacheKey` | string | Yes | The cache key that was revalidated. |
| `wasNegativeCache` | boolean | No | `true` when the entry was a cached "no lyrics" result. Absent when `error` is set. |
| `error` | string | No | Why the upstream fetch failed. Only present when `updated` is `false`. |

## When to use

-   You know lyrics now exist for a song that had none before
-   The lyrics were corrected at the source
-   You want to make sure you have the latest version

## Error responses

### Missing or invalid API key (401)

```json
{
  "error": "API key required for revalidation",
  "message": "Provide a valid API key via X-API-Key header"
}
```

### Missing parameters (400)

Both song and artist are required.

```json
{
  "error": "song (s) and artist (a) parameters are required"
}
```

### Not in cache (404)

```json
{
  "error": "no cached lyrics found for this query",
  "cacheKey": "ttml_lyrics:unknown song artist"
}
```

## Notes

-   Only songs that are already cached can be revalidated. Other queries return `404`.
-   The lookup uses the exact cache key for the query, with no duration tolerance. The key includes album and duration, so send the same four values you send to `/getLyrics`. Without them, the lookup usually returns `404`.
-   Only the default TTML entry is refreshed. Entries for `/ttml/getLyrics`, `/kugou/getLyrics` and `/qq/getLyrics` are not changed.
-   When the fetched lyrics replace a negative cache entry, the negative entry is removed
-   The `updated` field is `false` if the content has not changed
-   A valid API key is always required, so this endpoint is never rate limited (`X-RateLimit-Type: bypass`)

Source: https://docs.betterlyrics.org/reference/revalidate
