diff --git a/BattleNet.hs b/BattleNet.hs
new file mode 100644
--- /dev/null
+++ b/BattleNet.hs
@@ -0,0 +1,6 @@
+module BattleNet(module BattleNet) where
+
+import BattleNet.ApiKey as BattleNet
+import BattleNet.WoWStatic as BattleNet
+import BattleNet.WoW as BattleNet
+
diff --git a/BattleNet/ApiKey.hs b/BattleNet/ApiKey.hs
new file mode 100644
--- /dev/null
+++ b/BattleNet/ApiKey.hs
@@ -0,0 +1,9 @@
+module BattleNet.ApiKey(BattleNetApiKey(..)) where
+
+import Data.Text
+
+data BattleNetApiKey = BattleNetApiKey
+    { bnetApiKey :: Text
+    , bnetApiSecret :: Text
+    , bnetRegion :: Text
+    }
diff --git a/BattleNet/Plumbing.hs b/BattleNet/Plumbing.hs
new file mode 100644
--- /dev/null
+++ b/BattleNet/Plumbing.hs
@@ -0,0 +1,37 @@
+module BattleNet.Plumbing where
+
+import BattleNet.ApiKey
+
+import Control.Applicative
+import Control.Monad
+import Data.Monoid
+import Data.Maybe
+import Data.List
+import Data.Text hiding (intersperse)
+import Data.Aeson
+import qualified  Data.Aeson as Aeson
+import Network.HTTP.Conduit hiding (path, queryString)
+
+apiEndpointUrl' :: Text -> BattleNetApiKey -> [Text] -> [(Text, Text)] -> Text
+apiEndpointUrl' baseDomain key parts queryString = Data.Text.concat $ mconcat
+        [ ["https://"
+          , bnetRegion key
+          , "."
+          , baseDomain
+          , "/"]
+        , renderedParts parts
+        , "?" : renderedQueryStringParams queryString
+        ]
+    where renderedParts = Data.List.intersperse "/"
+          renderedQueryStringParam (k, v) = [k, "=", v]
+          renderedQueryStringParams = mconcat . intersperse ["&"] . fmap renderedQueryStringParam
+
+apiEndpointUrl :: [Text] -> [(Text, Text)] -> BattleNetApiKey -> Text
+apiEndpointUrl parts queryString key = apiEndpointUrl' "api.battle.net" key parts (("apikey", bnetApiKey key) : queryString)
+
+apiEndpoint :: FromJSON a => [Text] -> [(Text, Text)] -> Manager -> BattleNetApiKey -> IO a
+apiEndpoint parts queryString manager key = do
+    path <- parseUrl $ unpack $ apiEndpointUrl parts queryString key
+    response <- responseBody <$> httpLbs path manager
+    let decoded = Aeson.decode response
+    return $ fromMaybe (error $ mconcat ["Invalid response from ", show path, ": ", show response]) decoded
diff --git a/BattleNet/WoW.hs b/BattleNet/WoW.hs
new file mode 100644
--- /dev/null
+++ b/BattleNet/WoW.hs
@@ -0,0 +1,76 @@
+module BattleNet.WoW(WoWCharacterInfo(..), WoWGuildMemberInfo(..), character, userCharacters, guildMembers) where
+
+import BattleNet.ApiKey
+import BattleNet.Plumbing
+import BattleNet.WoWStatic
+import Data.Aeson
+import Data.Map
+import Data.Text
+import Control.Applicative
+import Control.Monad
+import Network.HTTP.Conduit
+
+data WoWCharacterInfo = WoWCharacterInfo
+    { characterName :: Text
+    , characterRealm :: Text
+    , characterClass :: WoWClassInfoId
+    , characterThumbnail :: Text
+    , characterLevel :: Int
+    } deriving Show
+
+instance FromJSON WoWCharacterInfo where
+    parseJSON (Object v) = do
+        characterName <- v .: "name"
+        characterRealm <- v .: "realm"
+        characterClass <- WoWClassInfoId <$> v .: "class"
+        characterThumbnail <- v .: "thumbnail"
+        characterLevel <- v .: "level"
+        return WoWCharacterInfo
+            { characterName = characterName
+            , characterRealm = characterRealm
+            , characterClass = characterClass
+            , characterThumbnail = characterThumbnail
+            , characterLevel = characterLevel
+            }
+    parseJSON _ = mzero
+
+newtype UserCharactersWrapper = UserCharactersWrapper [WoWCharacterInfo]
+
+instance FromJSON UserCharactersWrapper where
+    parseJSON (Object v) = UserCharactersWrapper <$> v .: "characters"
+    parseJSON _ = mzero
+
+data WoWGuildMemberInfo = WoWGuildMemberInfo
+    { memberName :: Text
+    , memberRealm :: Text
+    , memberRank :: Int
+    }
+
+instance FromJSON WoWGuildMemberInfo where
+    parseJSON (Object v) = do
+        member <- v .: "character"
+        memberName <- member .: "name"
+        memberRealm <- member .: "realm"
+        memberRank <- v .: "rank"
+        return WoWGuildMemberInfo
+            { memberName = memberName
+            , memberRealm = memberRealm
+            , memberRank = memberRank
+            }
+
+newtype GuildMemberWrapper = GuildMemberWrapper [WoWGuildMemberInfo]
+
+instance FromJSON GuildMemberWrapper where
+    parseJSON (Object v) = GuildMemberWrapper <$> v .: "members"
+    parseJSON _ = mzero
+
+character :: Text -> Text -> Manager -> BattleNetApiKey -> IO WoWCharacterInfo
+character realm name = apiEndpoint ["wow", "character", realm, name] []
+
+userCharacters :: Text -> Manager -> BattleNetApiKey -> IO [WoWCharacterInfo]
+userCharacters accessToken manager key = unwrapChars <$> apiEndpoint ["wow", "user", "characters"] [("access_token", accessToken)] manager key
+    where unwrapChars (UserCharactersWrapper chars) = chars
+
+guildMembers :: Text -> Text -> Manager -> BattleNetApiKey -> IO [WoWGuildMemberInfo]
+guildMembers realm name manager key = unwrapMembers <$> apiEndpoint ["wow", "guild", realm, name] [("fields", "members")] manager key
+    where unwrapMembers (GuildMemberWrapper chars) = chars
diff --git a/BattleNet/WoWStatic.hs b/BattleNet/WoWStatic.hs
new file mode 100644
--- /dev/null
+++ b/BattleNet/WoWStatic.hs
@@ -0,0 +1,70 @@
+module BattleNet.WoWStatic( WoWClassInfoId(..)
+                          , WoWClassInfo(..), classes
+                          , WoWTalentInfo(..), WoWSpecInfo(..), talents
+                          ) where
+
+import BattleNet.ApiKey
+import BattleNet.Plumbing
+import Data.Aeson
+import Data.Map
+import Data.Text
+import Control.Applicative
+import Control.Monad
+import Network.HTTP.Conduit
+
+newtype WoWClassInfoId = WoWClassInfoId Int deriving (Show, Ord, Eq)
+
+data WoWClassInfo = WoWClassInfo
+    { classId :: WoWClassInfoId
+    , className :: Text
+    } deriving Show
+
+newtype WoWClassesInfo = WoWClassesInfo [WoWClassInfo]
+extractClassesInfo :: WoWClassesInfo -> [WoWClassInfo]
+extractClassesInfo (WoWClassesInfo x) = x
+
+data WoWSpecInfo = WoWSpecInfo
+    { specName :: Text
+    } deriving Show
+
+data WoWTalentInfo = WoWTalentInfo
+    { talentInfoClass :: Text
+    , talentInfoSpecs :: [WoWSpecInfo]
+    } deriving Show
+
+instance FromJSON WoWClassInfo where
+    parseJSON (Object v) = do
+        classId <- WoWClassInfoId <$> v .: "id"
+        className <- v .: "name"
+        return WoWClassInfo
+            { classId = classId
+            , className = className
+            }
+    parseJSON _ = mzero
+
+instance FromJSON WoWClassesInfo where
+    parseJSON (Object v) = WoWClassesInfo <$> (v .: "classes" >>= parseJSON)
+    parseJSON _ = mzero
+
+instance FromJSON WoWSpecInfo where
+    parseJSON (Object v) = do
+        specName <- v .: "name"
+        return WoWSpecInfo
+            { specName = specName
+            }
+
+instance FromJSON WoWTalentInfo where
+    parseJSON (Object v) = do
+        talentInfoClass <- v .: "class"
+        talentInfoSpecs <- v .: "specs"
+        return WoWTalentInfo
+            { talentInfoClass = talentInfoClass
+            , talentInfoSpecs = talentInfoSpecs
+            }
+    parseJSON _ = mzero
+
+classes :: Manager -> BattleNetApiKey -> IO [WoWClassInfo]
+classes manager key = extractClassesInfo <$> apiEndpoint ["wow", "data", "character", "classes"] [] manager key
+
+talents :: Manager -> BattleNetApiKey -> IO (Map WoWClassInfoId WoWTalentInfo)
+talents manager key = mapKeys (WoWClassInfoId . read) <$> apiEndpoint ["wow", "data", "talents"] [] manager key
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Teo Klestrup Röijezon
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/battlenet.cabal b/battlenet.cabal
new file mode 100644
--- /dev/null
+++ b/battlenet.cabal
@@ -0,0 +1,74 @@
+-- Initial battlenet.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                battlenet
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- http://www.haskell.org/haskellwiki/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            API client for Battle.Net
+
+-- A longer description of the package.
+-- description:         
+
+-- The license under which the package is released.
+license:             MIT
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Teo Klestrup Röijezon
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          teo@nullable.se
+
+-- A copyright notice.
+-- copyright:           
+
+category:            Network
+
+build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or a 
+-- README.
+-- extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.10
+
+
+library
+  -- Modules exported by the library.
+  exposed-modules:     BattleNet
+                       BattleNet.ApiKey
+                       BattleNet.WoW
+                       BattleNet.WoWStatic
+                       BattleNet.Plumbing
+  
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- LANGUAGE extensions used by modules in this package.
+  default-extensions:  OverloadedStrings
+
+  -- Other library packages from which modules are imported.
+  build-depends:       base >=4.7 && <4.8,
+                       http-conduit >=2.1.4 && <2.2,
+                       text >=1.2 && <1.3,
+                       aeson >=0.7 && <0.9,
+                       containers >=0.5.5 && <0.6
+  -- Directories containing source files.
+  -- hs-source-dirs:      
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
