diff --git a/api-builder.cabal b/api-builder.cabal
--- a/api-builder.cabal
+++ b/api-builder.cabal
@@ -1,5 +1,5 @@
 name: api-builder
-version: 0.1.0.0
+version: 0.1.0.1
 synopsis: Library for easily building REST API wrappers in Haskell
 license: BSD3
 author: Fraser Murray
diff --git a/src/APIBuilder.hs b/src/APIBuilder.hs
--- a/src/APIBuilder.hs
+++ b/src/APIBuilder.hs
@@ -1,3 +1,5 @@
+-- | Exports a bunch of stuff. Check 'APIBuilder.API', 'APIBuilder.Builder',
+--   'APIBuilder.Decoding', 'APIBuilder.Error', and 'APIBuilder.Routes'.
 module APIBuilder 
   ( module Exports ) where
 
diff --git a/src/APIBuilder/API.hs b/src/APIBuilder/API.hs
--- a/src/APIBuilder/API.hs
+++ b/src/APIBuilder/API.hs
@@ -1,11 +1,15 @@
-module APIBuilder.API
-  ( API 
-  , liftEither
-  , liftBuilder
-  , liftState
+module APIBuilder.API (
+  -- * API
+    API 
+  -- ** Running the API
   , runAPI
   , runRoute
   , routeRequest
+  -- ** Lifting
+  , liftEither
+  , liftBuilder
+  , liftState
+  -- ** Changing the @Builder@ within the API
   , name
   , baseURL
   , customizeRoute
@@ -27,20 +31,35 @@
 import qualified Data.Text as T
 import Network.HTTP.Conduit
 
+-- | Main API type. @s@ is the API's internal state, @e@ is the API's custom error type,
+--   and @a@ is the result when the API runs.
 type API s e a = EitherT (APIError e) (StateT Builder (StateT s IO)) a
 
-liftEither :: API s e a -> API s e a
-liftEither = id 
+-- | Lifts an action that works on an @API@ to an action that works on an @API@.
+--   This function is provided solely for future-proofing in the case that more transformers
+--   need to be stacked on top - it's implemented simply as @id@ for the moment.
+liftEither :: EitherT (APIError e) (StateT Builder (StateT s IO)) a -> API s e a
+liftEither = id
 
+-- | Lifts an action that operates on a @Builder@ to one that works on an @API@. Useful
+--   mainly for gaining access to a @Builder@ from inside an @API@.
 liftBuilder :: StateT Builder (StateT s IO) a -> API s e a
 liftBuilder = lift
 
+-- | Lifts an action on an @API@'s state type @s@ to one that works on the @API@. Good
+--   for messing with the state from inside the @API@. 
 liftState :: StateT s IO a -> API s e a
 liftState = lift . lift
 
-runAPI :: Builder -> s -> API s e a -> IO (Either (APIError e) a)
+-- | Runs an @API@ by executing its transformer stack and dumping it all into @IO@.
+runAPI :: Builder -- ^ initial @Builder@ for the @API@ 
+       -> s -- ^ initial state @s@ for the @API@
+       -> API s e a -- ^ the actual @API@ to run
+       -> IO (Either (APIError e) a) -- ^ IO action that returns either an error or the result
 runAPI b s api = evalStateT (evalStateT (runEitherT api) b) s
 
+-- | Runs a @Route@. Infers the type to convert to from the JSON with the @a@ in @API@,
+--   and infers the error type from @e@.
 runRoute :: (FromJSON a, FromJSON e) => Route -> API s e a
 runRoute route = do
   b <- liftBuilder get
@@ -56,19 +75,30 @@
     Just x -> Right x
     Nothing -> Left b
 
+-- | Try to construct a @Request@ from a @Route@ (with the help of the @Builder@). Returns @Nothing@ if
+--   the URL is invalid or there is another error with the @Route@.
 routeRequest :: Builder -> Route -> Maybe Request
 routeRequest b route = 
   let initialURL = parseUrl (T.unpack $ routeURL (_baseURL b) (_customizeRoute b route)) in
   fmap (\url -> _customizeRequest b $ url { method = BS.pack (showMethod $ httpMethod route) }) initialURL
 
+-- | Modify the @name@ of the @Builder@ from inside an API. Using this is probably not the best idea,
+--   it's nice if the @Builder@'s name is stable at least.
 name :: Text -> API s e ()
 name t = liftBuilder $ modify (\b -> b { _name = t })
 
+-- | Modify the @baseURL@ of the @Builder@ from inside an API.
+--   Can be useful for changing the API's endpoints for certain requests.
 baseURL :: Text -> API s e ()
 baseURL t = liftBuilder $ modify (\b -> b { _baseURL = t })
 
+-- | Modify every @Route@ before it runs. Useful for adding extra params to every query,
+--   for example.
 customizeRoute :: (Route -> Route) -> API s e ()
 customizeRoute f = liftBuilder $ modify (\b -> b { _customizeRoute = f })
 
+
+-- | Modify every @Request@ before the API fetches it. Useful for adding headers to every request,
+--   for example.
 customizeRequest :: (Request -> Request) -> API s e ()
 customizeRequest f = liftBuilder $ modify (\b -> b { _customizeRequest = f })
diff --git a/src/APIBuilder/Builder.hs b/src/APIBuilder/Builder.hs
--- a/src/APIBuilder/Builder.hs
+++ b/src/APIBuilder/Builder.hs
@@ -8,6 +8,8 @@
 import Data.Text (Text)
 import qualified Data.Text as T
 
+-- | Builder type for the API. Keeps track of the API's name and base URL, and how
+--   to modify Routes and Requests before they're run.
 data Builder = Builder { _name :: Text
                        , _baseURL :: Text
                        , _customizeRoute :: Route -> Route
@@ -16,5 +18,9 @@
 instance Show Builder where
   show b = "Builder { name = " ++ T.unpack (_name b) ++ "}"
 
-basicBuilder :: Text -> Text -> Builder
+-- | Makes a basic builder, i.e. one that simply has a name and base URL
+--   and doesn't fiddle with Routes / Requests.
+basicBuilder :: Text -- ^ name
+             -> Text -- ^ base url
+             -> Builder -- ^ a simple @Builder@
 basicBuilder n b = Builder n b id id 
diff --git a/src/APIBuilder/Decoding.hs b/src/APIBuilder/Decoding.hs
--- a/src/APIBuilder/Decoding.hs
+++ b/src/APIBuilder/Decoding.hs
@@ -9,6 +9,9 @@
 import Data.Attoparsec.Lazy (parse, eitherResult)
 import qualified Data.ByteString.Lazy as BS
 
+-- | Try to parse a value from a JSON @ByteString@, and if not, try to
+--   parse a useful error from the JSON. If we can't do that, complain about
+--   a @ParseError@.
 decode :: (FromJSON a, FromJSON e) => BS.ByteString -> Either (APIError e) a
 decode s = 
   case eitherDecode s of
@@ -18,5 +21,9 @@
         Right x -> Left $ APIError x
         Left _ -> Left $ ParseError err
 
+-- | @Data.Aeson@'s @decode@ function will only parse a value if it's 
+--   an array or an object, in accordance with some RFC somewhere. Unfortunately
+--   not all JSON APIs respect this, so we have to mess with parsers and values and 
+--   whatnot.
 eitherDecode :: (FromJSON a) => BS.ByteString -> Either String a
 eitherDecode s = eitherResult (parse value s) >>= parseEither parseJSON
diff --git a/src/APIBuilder/Error.hs b/src/APIBuilder/Error.hs
--- a/src/APIBuilder/Error.hs
+++ b/src/APIBuilder/Error.hs
@@ -3,8 +3,15 @@
 
 import Network.HTTP.Conduit (HttpException)
 
-data APIError a = APIError a
-                | HTTPError HttpException
-                | InvalidURLError
-                | ParseError String
+-- | Error type for the @API@, where @a@ is the type that should be returned when
+--   something goes wrong on the other end - i.e. any error that isn't directly related
+--   to this library.
+data APIError a = APIError a -- ^ A type that represents any error that happens on the API end.
+                             --   Define your own custom type with a @FromJSON@ instance if you
+                             --   want to handle them, or you can use @()@ if you just want to
+                             --   ignore them all.
+                | HTTPError HttpException -- ^ Something went wrong when we tried to do a HTTP operation.
+                | InvalidURLError -- ^ You're trying to create an invalid URL somewhere - check your
+                                  --   @Builder@'s base URL and your @Route@s.
+                | ParseError String -- ^ Failed when parsing the response, and it wasn't an error on their end.
   deriving Show
diff --git a/src/APIBuilder/Examples/StackOverflow.hs b/src/APIBuilder/Examples/StackOverflow.hs
--- a/src/APIBuilder/Examples/StackOverflow.hs
+++ b/src/APIBuilder/Examples/StackOverflow.hs
@@ -1,3 +1,5 @@
+-- | Defines a basic example of API use - check the readme for more detail
+--   or check the tutorial at <https://github.com/intolerable/api-builder>
 module APIBuilder.Examples.StackOverflow where
 
 import APIBuilder
diff --git a/src/APIBuilder/Routes.hs b/src/APIBuilder/Routes.hs
--- a/src/APIBuilder/Routes.hs
+++ b/src/APIBuilder/Routes.hs
@@ -1,11 +1,11 @@
 module APIBuilder.Routes
-  ( URLFragment
+  ( Route(..)
+  , URLFragment
   , URLParam
-  , Route(..)
+  , (=.)
   , HTTPMethod(..)
   , showMethod
-  , routeURL
-  , (=.) ) where
+  , routeURL ) where
 
 import Control.Arrow ((***))
 import Data.Maybe (mapMaybe)
@@ -14,28 +14,51 @@
 import qualified Data.Text as T
 import qualified Network.HTTP.Base as HTTP (urlEncodeVars)
 
+-- | Alias for @Text@ to store the URL fragments for each @Route@.
 type URLFragment = Text
+
+-- | Alias to @(Text, Maybe Text)@ used to store each query that gets
+--   tacked onto the request.
 type URLParam = (Text, Maybe Text)
 
+-- | Convenience function for building @URLParam@s.
+-- 
+-- >>> "api_type" =. Just "json"
+-- ("api_type", Just "json")
 (=.) :: Text -> Maybe Text -> (Text, Maybe Text)
 (=.) = (,)
 
+-- | Main type for routes in the API. Used to represent the URL minus the actual 
+--   endpoint URL as well as the query string and the HTTP method used to communicate
+--   with the server.
 data Route = Route { fragments :: [URLFragment]
                    , urlParams :: [URLParam]
                    , httpMethod :: HTTPMethod }
   deriving (Show, Read, Eq)
 
+-- | Type for different HTTP request methods. Has the two most common ones (GET and POST)
+--   as well as support for custom methods.
 data HTTPMethod = GET
                 | POST
                 | CustomMethod Text
   deriving (Show, Read, Eq)
 
+-- | Get a @String@ from a HTTPMethod. Used mostly for creating @Request@s.
+--
+-- >>> showMethod GET
+-- "GET"
+-- >>> showMethod (CustomMethod "PATCH")
+-- "PATCH"
 showMethod :: HTTPMethod -> String
 showMethod GET = "GET"
 showMethod POST = "POST"
 showMethod (CustomMethod t) = T.unpack t
 
-routeURL :: Text -> Route -> Text
+-- | Converts a Route to a URL. Drops any @Nothing@ values from the query, separates the
+--   fragments with "/" and tacks them onto the end of the base URL.
+routeURL :: Text -- ^ base URL for the @Route@ (you can usually get this from the @Builder@)
+         -> Route -- ^ the @Route@ to process
+         -> Text -- ^ the finalized URL as a @Text@
 routeURL baseURL (Route fs ps _) =
   let path = T.intercalate "/" fs
   in baseURL <> "/" <> path <> pathParamsSep fs <> buildParams ps
