FastSaverAPI moved. The API and dashboard now live at api.fastsaver.iowhat changed.

Shazam API for song recognition from an audio clip

The Shazam API brings song recognition to your own app: post a few seconds of audio and get the title, artist, cover art, lyrics and a YouTube video_id you can turn into a playable file. The same key reads Shazam charts by country and looks up lyrics for any title and artist pair you already hold.

Last updated

Endpoints
POST /shazam/identify · GET /shazam/top · GET /shazam/lyrics
Credits
5 identify · 2 lyrics · 1 charts
Upload
mp3, m4a, ogg, mp4 — 50 MB ceiling
Returns
title, artist, lyrics + YouTube matches

coverage

three endpoints, one music stack

Recognition on its own is rarely the product. A user sends a clip, your app names the song, then hands back something playable. These three endpoints cover the first two thirds of that; the YouTube side of the API covers the rest.

identify

5 credits

Upload audio, get the track back with its Shazam id, artwork, lyrics and YouTube matches.

top

1 credit

Shazam charts for one country code or world, ten tracks per page.

lyrics

2 credits

Lyrics for a track you can already name — pass title and artist.

All three authenticate with the same X-Api-Key header and answer with { "ok": true, … }. Only identify is a POST, and only identify sends bytes.

usage

identifying a track from audio

Send the file as multipart/form-data under the field name file. There is no URL variant — the audio has to reach the recogniser somehow.

POST https://api.fastsaver.io/v1/shazam/identify 5 credits · multipart
request
curl -X POST "https://api.fastsaver.io/v1/shazam/identify" \
  -H "X-Api-Key: fs_sk_•••••••••••" \
  -F 'file=@clip.m4a;type=audio/x-m4a'
200 OK · response
{
  "ok": true,
  "id": "102147933",
  "title": "Сердце пацана",
  "artist": "YARMAK",
  "thumbnail": "https://is1-ssl.mzstatic.com/image/thumb/...",
  "lyrics": "...",
  "results": [
    {
      "video_id": "vk6014HuxcE",
      "title": "YARMAK - Сердце пацана",
      "duration": "3:24",
      "thumbnail": "https://i.ytimg.com/vi/vk6014HuxcE/mqdefault.jpg",
      "thumbnail_max": "https://i.ytimg.com/vi/vk6014HuxcE/maxresdefault.jpg"
    }
  ]
}
FieldTypeNotes
idstringShazam track id. A stable key for your own cache — note that /shazam/lyrics does not accept it.
titlestringTrack name as Shazam has it, in the original script.
artiststringCredited performer, not the uploader.
thumbnailstringCover art URL, ready to show in a reply.
lyricsstringIncluded when Shazam has them, so a hit often needs no second call.
resultsarrayYouTube matches, each with video_id, title, duration and two thumbnail sizes.

Treat results as search output, not as something the recogniser vouched for. It is ordered best-first, but a popular track also surfaces covers, sped-up edits and hour-long loops. Compare duration and title against the recognised track before you auto-deliver the first entry.

the real use case

recognise → video_id → Telegram audio

This is what most people build. A user forwards a voice note or a video to your bot; you reply with the song as a proper audio file. Two API calls, no file ever touches your disk, and 12 credits once the track is cached.

python · recognise and deliver
import requests

API = "https://api.fastsaver.io/v1"
AUTH = {"X-Api-Key": "fs_sk_•••••••••••"}
BOT = "@your_bot"
TELEGRAM_TOKEN = "123456789:AA-your-bot-token"
TG = "https://api.telegram.org/bot" + TELEGRAM_TOKEN

def identify(path: str) -> dict | None:
    with open(path, "rb") as fh:
        r = requests.post(API + "/shazam/identify", headers=AUTH,
                          files={"file": fh}, timeout=120)
    data = r.json()
    return data if data.get("ok") and data.get("results") else None

def telegram_audio(video_id: str) -> str:
    r = requests.post(API + "/youtube/audio/tg-bot", headers=AUTH,
                      json={"video_id": video_id, "bot_username": BOT},
                      timeout=180)
    return r.json()["file_id"]

def deliver(chat_id: int, path: str) -> None:
    song = identify(path)
    if song is None:
        requests.post(TG + "/sendMessage", json={
            "chat_id": chat_id,
            "text": "No match. Try a cleaner few seconds.",
        })
        return
    file_id = telegram_audio(song["results"][0]["video_id"])
    requests.post(TG + "/sendAudio", json={
        "chat_id": chat_id,
        "audio": file_id,
        "caption": song["artist"] + " — " + song["title"],
    })

if __name__ == "__main__":
    deliver(123456789, "clip.m4a")

The second step returns a Telegram file_id, not a download URL. Telegram already holds the bytes, so sendAudio resolves instantly and your bandwidth stays flat. The id is bound to the bot_username you passed, so use the real one even while testing. The Telegram music bot guide covers the search-driven variant.

Budget for the miss, not the hit. /youtube/audio/tg-bot charges 7 credits only when we already hold that video_id; if we do not, it downloads the track first and bills the full 15 of a YouTube download. So the pipeline is 12 credits for a song someone has asked for before and 20 for one nobody has — a difference that shows up as soon as your users start finding obscure music rather than the same twenty chart tracks.

the other two

charts and standalone lyrics

/shazam/top is the cheapest call in the API and the easiest way to seed a music app with content nobody has to search for. Ten tracks per page, pages 1 to 3. Pass a country code such as us, gb, ru or uz, or world for the global chart.

GET https://api.fastsaver.io/v1/shazam/top 1 credit
request
curl "https://api.fastsaver.io/v1/shazam/top?country=world&page=1" \
  -H "X-Api-Key: fs_sk_•••••••••••"
200 OK · response
{
  "ok": true,
  "results": [
    {
      "video_id": "7nVctvQVz0U",
      "title": "Taylor Swift - The Fate of Ophelia",
      "duration": "3:47",
      "thumbnail_url": "https://i.ytimg.com/vi/7nVctvQVz0U/mqdefault.jpg"
    },
    {
      "video_id": "9_bTl2vvYQg",
      "title": "HUNTR/X - Golden",
      "duration": "3:15",
      "thumbnail_url": "https://i.ytimg.com/vi/9_bTl2vvYQg/mqdefault.jpg"
    }
  ]
}

Chart rows already carry a video_id, so a trending list feeds the same delivery step as a recognition. Note the field is thumbnail_url here and thumbnail in the identify results; map both into your own model rather than passing raw payloads around.

Lyrics have their own endpoint for when you already know the track. It is a lookup by name, not by id: title and artist are both required query parameters, and leaving either one out fails validation before the request ever reaches the lyrics provider. Send the strings exactly as /shazam/identify gave them to you, URL-encoded.

GET https://api.fastsaver.io/v1/shazam/lyrics 2 credits
request
curl -G "https://api.fastsaver.io/v1/shazam/lyrics" \
  --data-urlencode "title=Сердце пацана" \
  --data-urlencode "artist=YARMAK" \
  -H "X-Api-Key: fs_sk_•••••••••••"
200 OK · response
{
  "ok": true,
  "lyrics": "..."
}

That is the entire payload — ok and lyrics. Nothing echoes the track back, and there is no language field, so a right-to-left layout or a translation offer has to be decided from metadata you already hold rather than from this response. Because the match is on the strings you send, a reformatted title or a rewritten "feat." credit can come back empty for a song that does have lyrics: keep the pair verbatim from identify and cache it alongside the track.

honesty

what recognition actually needs

Be blunt with yourself about the input. Fingerprinting compares a spectral signature against an index; it does not listen the way you do. A short, clean excerpt beats a long, dirty one.

  • Trim before uploading. Five to fifteen seconds of the strongest passage. A full track costs upload time and does not raise the hit rate.
  • Pick the musical part. A clip dominated by talking, applause or wind is a coin flip.
  • Do not re-encode down. A phone recording is fine; a 32 kbps recompression of one is worse.
  • Edits break matches. Pitch-shifted, sped-up and heavily filtered versions often return no match, or the wrong release of the right song.
  • Obscure music may be absent. Unreleased tracks, private DJ edits and most library music are not in the index. There is nothing to return.

If you accept video, cut the audio on your worker first — one ffmpeg call.

trim before you upload
ffmpeg -i input.mp4 -ss 00:00:20 -t 12 -vn -c:a aac -b:a 128k clip.m4a

caveats

upload ceilings, missed matches and chart depth

  • 50 MB and four containers. mp3, m4a, ogg and mp4. Anything else, convert first.
  • No match is a normal outcome. Design that path first — a "try a clearer clip" reply is part of the product, not an edge case.
  • YouTube matches are search results. Verify before auto-sending, especially for tracks with heavy remix traffic.
  • Charts are a snapshot. Pages 1–3, ten rows each, reordering through the day. Cache with a short TTL.
  • Throughput is capped by plan — from 10 requests a minute on Free up to 900 on Mega. Uploads are the slowest call here, so queue them instead of firing a batch in parallel.
  • Lyrics and artwork are third-party metadata. Availability varies by track and region, and they are not yours to present as your own.

Whatever you upload, and whatever you then do with the match, is on you. Naming a song is not a licence to redistribute it.

faq

questions about the Shazam API

How do I identify a song from an audio file with an API?

POST the file as multipart/form-data to /shazam/identify under the field name file — mp3, m4a, ogg or mp4, up to 50 MB. You get back the Shazam id, title, artist, thumbnail, lyrics and a results array of matching YouTube tracks.

How long should the audio clip be for reliable recognition?

Five to fifteen seconds of the clearest passage. Recognition matches a fingerprint window, so a full track adds upload time and nothing else. If the clip is mostly crowd noise or speech, cut to where the music dominates.

Can I fetch lyrics without running recognition again?

Yes, as long as you can already name the track. GET /shazam/lyrics takes title and artist as required query parameters — both, or the request fails validation — and costs 2 credits instead of 5. The response is { "ok": true, "lyrics": "…" } and nothing else: no title, no artist and no language field come back. Cache the title and artist from the first recognition and you never pay to identify the same clip twice.

How do I send the recognised song to a Telegram user as an audio file?

Pass results[0].video_id to /youtube/audio/tg-bot with your bot username. You get a Telegram file_id that your bot hands to sendAudio — nothing downloaded to your server, nothing uploaded to Telegram. That step bills 7 credits when the track is already in our cache and 15 when it is not, because a miss falls through to a full YouTube download.

What does song recognition cost per request?

5 credits to identify, 2 for a lyrics lookup by title and artist, 1 for a page of charts. Recognise-then-deliver costs 12 when the matched track is already cached and 20 the first time anyone asks for it, since the Telegram step is 7 cached and 15 on a miss. On the free tier's 1,000 credits that is about 83 repeat lookups, or 50 if every track is new to the cache.

Upload a clip and see the JSON

The playground takes a file directly — drop in twelve seconds of audio and read the match before you write any code.