Lastfm API interface

Latest on Hackage:0.7.0

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow to host generated Haddocks.

MIT licensed by Matvey Aksenov, Dmitry Malikov
Maintained by Matvey Aksenov


Hackage Build Status

Complete API interface to service. Documentation is available in two flavours:


liblastfm provides Applicative interface for constructing requests. Also, it handles all machinery needed to prepare request for sending:

  • signing

  • url-encoding

  • miscellaneous stuff like choosing correct HTTP method, etc

Once request is ready, liblastfm can send it and get you back a response. Response format might be:


To install either use hackage:

% cabal install liblastfm

Or git:

% git clone
% cd liblastfm
% cabal install


Suppose, you need to use API method. First find it in liblastfm: Tag would be the name of the module and search would be the name of function. Here it is. So import a couple of modules:

>>> import           Lastfm            -- a bunch of useful utilities
>>> import qualified Lastfm.Tag as Tag -- for

Now you may use applicative <*> for required and <* or *> for optional parameters to construct desired request: <*> tag "russian-folk" <* limit 3 <*> apiKey "29effec263316a1f8a97f753caaa83e0" <* json

To send constructed request use lastfm:

>>> con <- newConnection
>>> lastfm con $ <*> tag "russian-folk" <* limit 10 <*> apiKey "29effec263316a1f8a97f753caaa83e0" <* json
Right (Object (fromList [("results",Object (fromList [("tagmatches", ...

Wiki describes how to parse responses.


Q: I’m getting the following error. How do I fix it?

>>> Artist.getInfo <*> artist "Pink Floyd" <*> apiKey "29effec263316a1f8a97f753caaa83e0"

    Couldn't match expected type `Data.Text.Lazy.Internal.Text'
                with actual type `[Char]

A: This means you haven’t OverloadedStrings extension enabled. To enable it (either one works):

  • type in :set -XOverloadedStrings while in ghci session.

  • add {-# LANGUAGE OverloadedStrings #-} to the top of the file

  • compile with -XOverloadedStrings switch

Q: I’m getting the following error. How do I fix it?

>>> lastfm (Artist.getInfo <*> artist "Pink Floyd" <*> apiKey "29effec263316a1f8a97f753caaa83e0")

    No instance for (Show (IO (Either LastfmError r0)))
      arising from a use of `print'
    Possible fix:
      add an instance declaration for (Show (IO (Either LastfmError r0)))
    In the first argument of `print', namely `it'
    In a stmt of an interactive GHCi command: print it

A: This error message indicates that GHC cannot infer response format for the Request. To fix it, add use json or xml helpers, depending on your needs

A note on testing

To test Lastfm API compatibility (api test suite)—specifically, authentication requiring examples—you will need to set HASKELL_LIBLASTFM_APIKEY, HASKELL_LIBLASTFM_SESSIONKEY, and HASKELL_LIBLASTFM_SECRET environment variables to your api key, session key, and secret respectively; for example (bash):


Please, consult Lastfm API documentation and example/*-authentication.hs examples if you don’t know where to get your credentials.




  • Set default schema to ‘https’ (issue #27 fixed).


  • Stopped using the deprecated stuff from http-client.

  • Removed N.L.Response.closeConnection as it’s become a no-op.

  • Removed the “Network” prefix from the modules’ names.

  • Set default schema to ‘http’, since has no proper SSL support (issue #27).


  • Updated documentation to reflect the changes in 0.5.0.

  • Dropped void and contravariant dependencies


  • Fixed http-client’s Manager misuse: every call to lastfm* takes a Connection parameter now and multiple calls should share it.

  • Updated lens dependency

  • Switched to network-uri package

  • http-conduit exceptions aren’t propagate further into user code anymore

  • XML responses are parsed into Document type from xml-conduit

  • Fixed auth.getMobileSession API method

  • Provided lastfm_ function for making requests without parsing response. That is most useful for POST requests like

  • Supported batch operations for N.L.Track.scrobble, N.L.Library.{addAlbum,addArtist}

  • Vastly simplified internal representations leading to simpler library interface
comments powered byDisqus