Any support questions about this protocol should go to me, (russ at last dot fm) or to the forum.

This still assumes a knowledge of Protocol1, unfortunately. Anyone who merges these two documents gets my undying respect.

Audioscrobbler Plugin Protocol, version 1.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.
  • 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.
  • 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 :).
  • Do not try to guess info from the filename - if there are no tags, don't submit the file.
  • 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).

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:

http://post.audioscrobbler.com/?hs=true&p=1.1&c=<clientid>&v=<clientver>&u=<user>

Response:

There are several possible responses from the server for a HANDSHAKE. The format is:

* Status line, detailing the success or failure state of the HANDSHAKE * MD5 challenge, for use in constructing submissions as part of this SESSION * Submission URL, where submissions should be POSTed. * Interval line. 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.

The MD5 challenge and Submission URL lines are only present if the HANDSHAKE was negotiated successfully.

UPTODATE
<md5 challenge>
<url to submit script>
INTERVAL n

UPTODATE: The HANDSHAKE was successful, and no newer plugin version is available.

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

UPDATE: The HANDSHAKE was successful, but a newer plugin version is available from <updateurl>.

FAILED <reason>
INTERVAL n

FAILED: The HANDSHAKE was unsuccessful, because of <reason>.

BADUSER
INTERVAL n

BADUSER: The HANDSHAKE was unsuccessful, because the supplied user credentials were not recognised.

Client IDs

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.

Song Submissions

  • 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.
  • 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:

Submissions MUST be sent using an HTTP POST request to the URL obtained from the HANDSHAKE process. The submission is formatted as if it were an x-www-urlencoded HTML form response, with the body of the HTTP request containing a single line with key-value pairs separated by =, with multiple pairs separated by &.

Each of the keys below MUST be supplied for every track in the submission, even if there is no value associated with it. (e.g. the MusicBrainz? ID key must be present for each track, even if the track has no MusicBrainz? ID.)

The submission MUST be correctly double-encoded. The value of each field is expressed as a UTF-8 encoded string and then URL encoded. All the characters not part of a value are already valid UTF-8 and MUST NOT be further URL encoded.

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

* <user>: last.fm username (MUST be the same as the username given in the HANDSHAKE) * <MD5 response>: Demonstrates the HANDSHAKE credentials. <MD5 response> is generated as follows: md5(md5(<user_password>) + <MD5 challenge>), an MD5 hash of the string formed by concatenating the MD5 hash of the user's password (<user_password>) with the MD5 challenge sent by the SERVER as part of the HANDSHAKE response (<MD5 challenge>). The ascii-encoded, lowercase MD5 representation MUST be used, and MD5 strings MUST be converted to their hex value before concatenation with the challenge string and before submission to the final MD5 response. * <artist>: The name of the artist * <track>: The name of the track * <album>: The name of the album the track is from * <mbid>: The MusicBrainz? ID of the track * <length>: The length (duration) of the track in whole (integer) seconds * <time>: The date and time the track was played, described in a modified ISO 8601 format. The date format uses the ISO 8601 format except that the time zone specifier MUST NOT be used, the date/time separator MUST be a single space, and all values MUST be expressed with UTC times. For example, a time of 7AM, Pacific Standard Time (UTC + 8) would normally be expressed in ISO 8601 as 2006-02-12T07:00:00+0800. For submission it would be expressed as 2006-02-11 23:00:00.

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>&

Note that the line breaks in the above example were added for clarity and are not allowed in an actual submission.

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

Response:

FAILED <reason>
INTERVAL n

Or

BADAUTH
INTERVAL n

Or

OK
INTERVAL n

If the server returns FAILED, you retry at a later date. When? Would it make sense to recommend an exponential backoff?

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).

If it returns OK, you clear your 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)

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!