Audioscrobbler Protocol v1.1

Terms

APP
The client software used to play music. could be iTunes / XMMS / any other player.
SERVER
The AudioScrobbler server.
SESSION
A SESSION starts when the APP is loaded, and ends when the APP is closed. A SESSION consists of a single HANDSHAKE followed by multiple SUBMISSIONS.
HANDSHAKE
A HANDSHAKE is the process of inital negotiation of the APP with the SERVER.
SUBMISSION
The process of sending information on one or more played song from the APP to the SERVER.

The Handshake

A Handshake is the first step in beginning a SESSION. A Handshake should occur just once during a SESSION, e.g. when the APP first loads, or after the APP detects 3 catastrophic (i.e. DNS resolution or connection refused) failures in submitting. In this case, the APP should not handshake more than once every 30 minutes. If the APP fails to connect to the handshake URL, the user should be informed.

Request:

This is a HTTP GET to the following url:

http://post.audioscrobbler.com/?hs=true&p=1.1&c=<clientid>&v=<clientver>&u=<user>
  • hs=true indicates a handshake is requested
  • p=1.1 is the Audioscrobbler protocol version
  • c=<clientid> is the name of the APP. Client IDs must be registered with Russ. Whilst testing you may use id 'tst', plugin version 1.0. Please do not release any code using the tst id.
    • Applescriptable MacOS X Application (iTunes) = osx
    • Winamp2 = wa2
    • Winamp3 = wa3
    • XMMS = xms
    • XMMS2 = xm2
    • Windows Media Player = wmp
    • SliMP3 = slm
    • MusicMatch Jukebox = mmj
    • FooBar = foo
    • QCD = qcd
    • AmigaAMP = ami
    • BMPx = mpx
    • Audacious = aud
    • Herrie = her
  • v=<clientver> is the version of the APP plugin
  • u=<user> is the user name

Response:

Lines in the SERVER responses and APP requests are separated by a unix newline character (\n) only.

UPTODATE
<md5 challenge>
<url to submit script>
INTERVAL n
  • The UPTODATE means your version is up to date.
  • The url is where to post your data to
  • INTERVAL is the number of seconds you must wait between sending updates. If the server is doing ok this will be 0. If it is under heavy stress, it may go up to avoid too many submissions in a short space of time.

If you are using an outdated version of a plugin, you will see something like this, indicating an update is available:

UPDATE <updateurl>
<md5 challenge>
<url to submit script>
INTERVAL n

This allows you to notify the user, and perhaps load the downloads page in a browser.

If the request fails, you will get:

FAILED <reason>
INTERVAL n

If the user is invalid:

BADUSER
INTERVAL n

Submitting Songs

  • Each song should be posted to the server when it is 50% or 240 seconds complete, whichever comes first.
  • If a user seeks (i.e. manually changes position) within a song before the song is due to be submitted, do not submit that song.
  • Songs with a duration of less than 30 seconds should not be submitted.
  • Do not try to guess info from the filename - if there are no tags, don't submit the file.
  • If a MusicBrainz? ID is present in the file (as defined here), then you should send it.
  • If a user is playing a stream instead of a regular file, do not submit that stream/song.

Request:

HTTP Post to submit script given in handshake. Note that all the post variables noted here MUST be supplied for each entry, even if they are blank. All variables must also be sent on one line, no new line separators as shown below. (hint: standard HTTP post request). Content type should be "application/x-www-form-urlencoded".

The items in <brackets> should be replaced by user data, minus the brackets. To preserve characters that fall outside of normal ASCII, like accented latin characters and Asian languages, UTF-8 encoding is used first, then URL encoding. Everything must be valid UTF-8. If it's not, don't complain that the system is ignoring you :). If your plugin isn't submitting valid UTF-8, it's logged at our end and I'll probably contact you :).

u=<user>&s=<MD5 response>&a[0]=<artist 0>&t[0]=<track 0>&b[0]=<album 0>&m[0]=<mbid 0>&l[0]=<length 0>&i[0]=<time 0>

You can also send multiple submissions in one request, like so:

u=<user>&s=<MD5 response>&
a[0]=<artist 0>&t[0]=<track 0>&b[0]=<album 0>&m[0]=<mbid 0>&l[0]=<length 0>&i[0]=<time 0>&
a[1]=<artist 1>&t[1]=<track 1>&b[1]=<album 1>&m[1]=<mbid 1>&l[1]=<length 1>&i[1]=<time 1>&
...
a[n]=<artist n>&t[n]=<track n>&b[n]=<album n>&m[n]=<mbid n>&l[n]=<length n>&i[n]=<time n>&

If you try to submit more than 10 tracks at once, some of them may not be accepted.

The MD5 response is md5(md5(your_password) + challenge), where MD5 is the ascii-encoded, lowercase MD5 representation, and + represents concatenation. MD5 strings must be converted to their hex value before concatenation with the challenge string and before submission to the final MD5 response.

The individual fields are:

a[0]
- artist name
  • t[0]
    - track title
  • b[0]
    - album name
  • m[0]
    - MusicBrainz? ID (send empty id if you don't know it, don't skip it)
  • l[0]
    - track length in seconds
  • i[0]
    - UTC date/time in YYYY-MM-DD hh:mm:ss format

    You may want to consider using a well featured HTTP library like the cross platform / open source libcurl (http://curl.haxx.se/libcurl/) that can automate url encoding, headers, error handling, background loading, formation of the POST query, etc.

    Response:

    You will receive either 1 or 2 lines in response to a submission.

    OK
    INTERVAL n
    

    Or

    FAILED <reason>
    INTERVAL n
    

    Or

    BADAUTH
    INTERVAL n
    

    If the server returns OK, you should remove the submitted tracks from your plugin's cache. Note that OK does not mean that the submissions have been entered into the DB - it just means we are in a position to process them. The three main reasons that submissions are OK'd but not entered are:

    • Bad UTF-8
    • Bad tagging (we now completely drop any entries which look crap, e.g. 01-artist_blah)
    • Spam filter (sanity checks like claiming to have played 10 songs in 10 seconds -- not possible)

    If it returns FAILED <reason>: The space after FAILED followed by an error message is optional. This indicates something went wrong, and you should cache the submission and retry later. When? Would it make sense to recommend an exponential backoff?

    The optional description might provide a clue as to the problem. If you get a FAILED message, either try to display the error text in a non-intrusive way, or only display the error once for repeated retries with the same error (the wa2 plugin had a habit of spamming clients with messageboxes, which stopped us doing useful things with the FAILED message).

    If it returns BADAUTH, you may need to re-handshake (you're likely to get temporarily blocked if you're attempting to resubmit at one-second intervals after getting repeated BADAUTH errors).

    The optional second line INTERVAL <seconds>: This means the server is very busy, and you should wait at least <seconds> seconds between further submissions. When the server calms down again you will get another INTERVAL response specifiying a lesser number (probably zero).

    INTERVAL commands can be at the end of any response block, but don't expect them to be. Always observe the latest INTERVAL you get.

    If the client gets an un-parsable response (probably HTML) then there was an error of some sort, so assume the FAILED response.

    Plugin Guidelines

    • DO NOT popup error boxes unless absolutely necessary. If you make your plugin pop up a "your password is incorrect" error message every time a song is played, it gets annoying. The server may go offline for periods and cause errors. These should be logged silently!