<center> # Index of Music APIs + Python/JS Tools *Originally published 2019-08-11 on [docs.sweeting.me](https://docs.sweeting.me/s/blog).* A summary of APIs and resources available for programmers working on projects involving music. Includes links to all the major platform APIs, metadata APIs, audio matching APIs, Python helper libraries, JS frontend implementations, documentation collections, and more. </center> --- [TOC] --- --- # Public Music APIs --- ## Audio * **[iTunes](https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/#searching)** & **[Apple Music](https://developer.apple.com/documentation/applemusicapi/search_for_catalog_resources)** * **[Spotify](http://developer.spotify.com/)** * **[Google Music](https://unofficial-google-music-api.readthedocs.io/en/latest/)** & **[YouTube](https://developers.google.com/youtube/)** * **[BandCamp](https://bandcamp.com/developer)** * **[SoundCloud](https://developers.soundcloud.com/docs/api/guide)** & [MixCloud](https://www.mixcloud.com/developers/) & [Beatport](http://api.beatport.com/) * [Amazon Prime Music](https://github.com/Jaffa/amazon-music) * [Pandora](https://6xq.net/pandora-apidoc/json/) * [Free Music Archive](http://freemusicarchive.org/), [7Digital](http://developer.7digital.com/), [8Tracks](http://8tracks.com/developers), [ccMixter](http://ccmixter.org/query-api), [Deezer](http://developers.deezer.com/api/), [Feed.fm](http://developer.feed.fm/documentation), [Freesound](http://www.freesound.org/help/developers/), [Jamendo](http://developer.jamendo.com/v3.0), [Medianet](http://www.mndigital.com/integration/openapi.html,)[Playme](http://lab.playme.com/api_overview), [Qobuz](https://github.com/Qobuz/api-documentation), [Rdio](http://developer.rdio.com/), [Shoudio](http://shoudio.com/developer,)[Soundkeep](http://www.soundkeep.com/api), [Spotify](https://developer.spotify.com/), [Tomahawk](http://toma.hk/api.html), [Grooveshark](https://grooveshark-api.readthedocs.io/en/latest/) ## Metadata * **Platforms:** Apple Music, iTunes, Spotify, Google Music, SoundCloud, MixCloud * **Public Databases:** **[Last.fm](http://www.last.fm/api)**, **[WhoSampled](https://www.whosampled.com/metadata/)**, [Discogs](https://www.discogs.com/developers/), [FreeDB](http://www.freedb.org/), [MusicBrainz](http://musicbrainz.org/doc/Development/XML_Web_Service/Version_2) * **Paid Services:** **[MusicMachinery](https://musicmachinery.com/music-apis/)**, **[MusixMatch](https://developer.musixmatch.com/documentation/api-reference/matcher-track-get)**, **[Gracenote](https://developer.gracenote.com/web-api)**, **[OneMusicAPI](http://www.onemusicapi.com/)**, **[MusicStory](http://developers.music-story.com/)**, [Rovi](http://developer.rovicorp.com/docs) ## Feeds * **Playlists:** Apple Music, Spotify, Google, Youtube, SoundCloud, Last.fm * **Chat:** [Facebook Messenger](#), [WhatsApp](#), [iMessage](#), [Slack](#), [Zulip](#) * **Social:** **[Reddit](https://www.reddit.com/dev/api/)**, **[The Hype machine](http://hypem.com/)**, **[8tracks](http://8tracks.com/developers)**, **[Playlists.net](http://playlists.net/api/documentation)**, [7Digital](http://developer.7digital.com/), [plug.dj](http://blog.plug.dj/api-documentation/), [Rovi](http://developer.rovicorp.com/), [Setlist.fm](http://api.setlist.fm/docs/index.html), [Shuffler.fm](http://developers.shuffler.fm/), [StereoMood](http://www.stereomood.com/api/documentation/), [Tastekid](http://www.tastekid.com/page/api), [Tunefind](http://www.tunefind.com/api) * **Blogs:** [ResidentAdvisor](https://www.residentadvisor.net/api/dj.asmx?op=getcharts), poolside.fm, radiomeuh.com, thissongissick.com, ukf.com ## More - **Converting:** [Soundiiz](https://soundiiz.com/api), [PlaylistConverter](http://www.playlist-converter.net/tutorial/api), freeyourmusic.com, tunemymusic.com, musconv.com - **Audio Matching:** **[ACRCloud](https://www.acrcloud.com)**, [Soundiiz](https://soundiiz.com/api), [AudioTag](https://audiotag.info/apisection), [Audd](https://docs.audd.io/), [AcousticID](http://acoustid.org/webservice), [BMAT](http://www.bmat.com/), [Gracenote](https://developer.gracenote.com/), [OCR](https://github.com/tesseract-ocr/tesseract) - **Lyrics:** **[RapGenius](https://docs.genius.com/#search-h2)**, **[MusixMatch](https://developer.musixmatch.com/)**, [ChartLyrics](http://www.chartlyrics.com/api.aspx), [LyricFind](http://www.lyricfind.com/services/lyrics-search/) - **Concerts:** **[Songkick](https://www.songkick.com/developer)**, **[Bandsintown](http://www.bandsintown.com/api/overview)**, **[FaceBook](https://developers.facebook.com/docs/graph-api/reference/page/events/)**, **[TicketMaster](https://developer.ticketmaster.com/products-and-docs/apis/discovery-api/v2/)**, [EventBrite](https://www.eventbrite.com/platform/api), [StubHub](https://developer.stubhub.com/), [EventFul](http://api.eventful.com/), [Gigatools](http://api.gigatools.com/), [Jambase](http://developer.jambase.com/), [Rockol](https://rockol.3scale.net/), [SeatGeek](http://platform.seatgeek.com/), [SeatWave](http://developer.seatwave.com/), [Setlist.fm](https://api.setlist.fm/docs/1.0/index.html), [Tourfilter](http://www.tourfilter.com/boston/about/feeds) - **Analytics:** [Musicmetric](http://developer.musicmetric.com/), [NextBigSound](http://api3.nextbigsound.com/) - **Sheet Music:** [Noteflight](http://www.noteflight.com/info/learn_more_developers), [MuseScore](http://developers.musescore.com/) - **Radio:** [Spreaker](http://developers.spreaker.com/) (internet radio), [YES](http://api.yes.com/#station) (live radio) - **Merch:** [DizzyJam](http://www.dizzyjam.com/) (band merch), [RedBubble](https://github.com/prolificjones82/Redbubble-API) (stickers), Amazon, Ebay - **Audio Analysis:** [WhoSampled](https://www.whosampled.com/metadata/), [Auphonic](https://auphonic.com/), [SampleSumo](https://www.samplesumo.com/samplesumo-classical-music-hack-day-vienna), [sonicAPI.com](http://www.sonicapi.com/) - **Lists of APIs:** [MusicMachinery](**https://musicmachinery.com/music-apis/**) [ProgrammableWeb](https://www.programmableweb.com/news/top-10-music-apis-spotify-last.fm-rdio-soundcloud/analysis/2015/02/02), [ProgrammableWeb Lyrics](https://www.programmableweb.com/category/lyrics/api) --- # Libraries & Projects ## Frontend (JavaScript) ### API Bindings: Apple Music - https://github.com/tvillarete/apple-music-js - https://github.com/fvdm/nodejs-searchitunes - https://github.com/sheminusminus/apple-music-token-node ### API Bindings: Spotify ### Music Player Interfaces - **https://github.com/Musish/Musish** - https://github.com/anantn/thinmusic - https://github.com/zachomedia/apple-music-webplayer - https://github.com/naveedgol/music-web-player ## Backend (Python) ### API Bindings: Apple Music **https://github.com/rcrdclub/apple-py-music** **https://github.com/mpalazzolo/apple-music-python** https://github.com/pelauimagineering/apple-music-token-generator ### API Bindings: iTunes **https://github.com/sleepyfran/itunespy** https://github.com/ocelma/python-itunes https://blog.ruanbekker.com/blog/2018/05/08/use-python-requests-to-interact-with-the-itunes-api-to-search-for-music-info/ ### API Bindings: Spotify **https://github.com/plamere/spotipy** https://developer.spotify.com/documentation/web-api/ https://github.com/JMPerez/spotify-web-api-js ### API Bindings: Google Music https://unofficial-google-music-api.readthedocs.io/en/latest/ ### API Bindings: SoundCloud **https://github.com/3jackdaws/soundcloud-lib** https://github.com/soundcloud/soundcloud-python ### API Bindings: Local iTunes Library **https://github.com/liamks/libpytunes** (query local library) https://github.com/scholnicks/itunes-library (query local library) **https://github.com/Stephan5/smarter-playlists** (convert to postgresql, modern) https://github.com/btbuxton/python-itunes (convert to sqlite, old) https://github.com/hile/pytunes (control mac iTunes/Music.app playback, modern) https://github.com/fscm/lastfm2itunes (update local playcounts from lastfm) `ffmpeg -i inputapplemusicfile.m4a -c:a libmp3lame -ac 2 -b:a 320k decryptedoutputfile.mp3` Convert apple music file locally to mp3 ### Audio Identification **https://github.com/Lahorde/shazam-on-linux** (fakes a linux sound card) **https://github.com/acrcloud/acrcloud_sdk_python** (3rd-party api) https://github.com/worldveil/dejavu (offline/self-hosted) https://github.com/bshankar/audiophile (offline/self-hosted) ### Utilities **https://github.com/simonschellaert/spotify2am** https://github.com/sandeharsa/SpotifyToiTunes https://github.com/nileshk/spotify2itunes https://github.com/moogar0880/pytagger https://github.com/mikeder/music-scraper (Subreddit music scraper) https://www.reddit.com/r/DataHoarder/comments/87h5zh/how_to_scrape_music_subreddits/ --- --- # Example Implementations --- ## Metadata Search & Matching ### Approach #1: Search iTunes Using HTTP API > `https://itunes.apple.com/search?entity=song&term={query}&country=us` > [See API Documentation](https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/#searching) ```python # Based on https://github.com/simonschellaert/spotify2am/blob/master/retrieve-identifiers.py def itunes_search(title: str, artist: str) -> Optional[str]: headers = { "X-Apple-Store-Front" : "143446-10,32 ab:rSwnYxS0 t:music2", "X-Apple-Tz" : "7200" } url = "https://itunes.apple.com/WebObjects/MZStore.woa/wa/search?clientApplication=MusicPlayer&term=" + urllib.parse.quote(title) response = requests.get(url, headers=headers) data = response.json() songs = [ result for result in data["storePlatformData"]["lockup"]["results"].values() if result["kind"] == "song" ] # Attempt to match by title & artist for song in songs: if song["name"].lower() == title.lower() and (song["artistName"].lower() in artist.lower() or artist.lower() in song["artistName"].lower()): return song["id"] # Attempt to match by title if we didn't get a title & artist match for song in songs: if song["name"].lower() == title.lower(): return song["id"] ``` ### Approach #2: Search iTunes API Using Helper Library ```python import itunespy # https://github.com/sleepyfran/itunespy def itunes_search(query: str) -> Optional[str]: return itunespy.search_track(query) ``` ### Approach #3: Search Apple Music Using HTTP API > `https://api.music.apple.com/v1/catalog/{STORE}/songs?term={query}` > [See API Documentation](https://developer.apple.com/documentation/applemusicapi/search_for_catalog_resources) ```python def apple_music_search(query: str) -> Optional[str]: STORE = "143446-10,32 ab:rSwnYxS0 t:music2" URL = f'https://api.music.apple.com/v1/catalog/{STORE}/songs?term={query}' # https://github.com/pelauimagineering/apple-music-token-generator JWT_TOKEN = 'JWT token goes here' headers = { 'Authorization': 'Bearer {JWT_TOKEN}' } response = requests.get(url, headers=headers) data = response.data() for song in data['data']: yield song[''] ``` ### Approach #4: Search Apple Music API Using Helper Library ```python import applemusicpy # https://github.com/mpalazzolo/apple-music-python def apple_music_search(query: str) -> List[Dict[str, Any]]: # From: https://help.apple.com/developer-account/#/devce5522674 AM_TEAM_ID = 'Q3VA4FKRSA' AM_KEY_ID = 'LDPSQHMGSF' AM_KEY_SECRET = '''-----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgiYb676NDALvbYf/8 CBLDy4Ny5jUugPd6K4sTh8RJNgigCgYIKoZIzj0DAQehRANCAATvpMrO+o/pEIzm JyeZueumZo7LynV3fX/vvnbFuOme5BGIrIiishc01IfUaC0Ct3Gb0s//Q1D6yr4A gybMMIR5 -----END PRIVATE KEY-----''' AM = applemusicpy.AppleMusic( team_id=AM_TEAM_ID, key_id=AM_KEY_ID, secret_key=AM_KEY_SECRET, ) results = AM.search(query, types=['songs'], limit=5) return results['results']['songs']['data'] ``` ### Approach #5: Match Using Paid Metadata Service TODO: Pick the best one to try from the list above. ### Approach #6: Match From Audio File - https://us-console.acrcloud.com/service/avr - https://us-console.acrcloud.com/pricing ```python from acrcloud.recognizer import ACRCloudRecognizer def arccloud_search(filename: str) -> Optional[str]: ARC_HOST = 'identify-us-west-2.acrcloud.com' ARC_ACCESS_KEY = '6b92095c8cc537a771beb0deb711618e' ARC_ACCESS_SECRET = 'C3WOEuMmgUlyC57J2154k694mNEuJLjpJwwiR0U2' ARC = ACRCloudRecognizer({ 'host':'XXXXXXXX', 'access_key':'XXXXXXXX', 'access_secret':'XXXXXXXX', 'timeout':10 # seconds }) with open('musicfile.mp3', 'rb') as f: return ARC.recognize_by_filebuffer(f.read(), 0) ```