diff --git a/google-drive.cabal b/google-drive.cabal
--- a/google-drive.cabal
+++ b/google-drive.cabal
@@ -1,5 +1,5 @@
 Name:                   google-drive
-Version:                0.1.0
+Version:                0.2.0
 Author:                 Pat Brisbin <pbrisbin@gmail.com>
 Maintainer:             Pat Brisbin <pbrisbin@gmail.com>
 License:                MIT
diff --git a/src/Network/Google/Api.hs b/src/Network/Google/Api.hs
--- a/src/Network/Google/Api.hs
+++ b/src/Network/Google/Api.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE OverloadedStrings #-}
 -- |
 --
@@ -11,6 +12,7 @@
       Api
     , ApiError(..)
     , runApi
+    , runApi_
     , throwApiError
 
     -- * HTTP-related types
@@ -55,19 +57,23 @@
 import Data.Conduit
 import Data.Conduit.Binary (sinkFile)
 import Data.Monoid ((<>))
+import Data.Typeable
 import GHC.Int (Int64)
 import Network.HTTP.Conduit
     ( HttpException(..)
     , Request(..)
     , RequestBody(..)
     , Response(..)
+    , Manager
+    , conduitManagerSettings
+    , closeManager
     , http
     , httpLbs
+    , newManager
     , parseUrl
     , requestBodySource
     , responseBody
     , setQueryString
-    , withManager
     )
 import Network.HTTP.Types
     ( Header
@@ -91,24 +97,33 @@
     = HttpError HttpException -- ^ Exceptions raised by http-conduit
     | InvalidJSON String      -- ^ Failure to parse a response as JSON
     | GenericError String     -- ^ All other errors
-
-instance Error ApiError where
-    strMsg = GenericError
+    deriving Typeable
 
 instance Show ApiError where
     show (HttpError ex) = "HTTP Exception: " <> show ex
     show (InvalidJSON msg) = "failure parsing JSON: " <> msg
     show (GenericError msg) = msg
 
+instance Error ApiError where
+    strMsg = GenericError
+
+instance E.Exception ApiError
+
 -- | A transformer stack for providing the access token and rescuing errors
-type Api = ReaderT String (ErrorT ApiError IO)
+type Api = ReaderT (String, Manager) (ErrorT ApiError IO)
 
 -- | Run an @Api@ computation with the given Access token
 runApi :: String -- ^ OAuth2 access token
        -> Api a
        -> IO (Either ApiError a)
-runApi token f = runErrorT $ runReaderT f token
+runApi token f =
+    E.bracket (newManager conduitManagerSettings) closeManager $ \manager ->
+        runErrorT $ runReaderT f (token, manager)
 
+-- | Like @runApi@ but discards the result and raises @ApiError@s as exceptions
+runApi_ :: String -> Api a -> IO ()
+runApi_ token f = either E.throw (const $ return ()) =<< runApi token f
+
 -- | Abort an @Api@ computation with the given message
 throwApiError :: String -> Api a
 throwApiError = throwError . GenericError
@@ -126,7 +141,7 @@
 getSource url params withSource = do
     request <- setQueryString params <$> authorize url
 
-    tryHttp $ withManager $ \manager -> do
+    withManager' $ \manager -> do
         response <- http request manager
         withSource $ responseBody response
 
@@ -150,12 +165,13 @@
 requestLbs url modify = do
     request <- authorize url
 
-    tryHttp $ withManager $ httpLbs $ modify request
+    withManager' $ httpLbs $ modify request
 
 -- | Create an authorized request for the given URL
 authorize :: URL -> Api Request
 authorize url = do
-    token <- ask
+    (token, _) <- ask
+
     request <- parseUrl' url
 
     let authorization = C8.pack $ "Bearer " <> token
@@ -196,5 +212,10 @@
     Just request -> return request
     Nothing -> throwApiError $ "Invalid URL: " <> url
 
-tryHttp :: IO a -> Api a
-tryHttp = either (throwError . HttpError) return <=< liftIO . E.try
+withManager' :: (Manager -> ResourceT IO a) -> Api a
+withManager' f = do
+    (_, manager) <- ask
+
+    result <- liftIO $ E.try $ runResourceT $ f manager
+
+    either (throwError . HttpError) return result
diff --git a/src/Network/Google/Drive/File.hs b/src/Network/Google/Drive/File.hs
--- a/src/Network/Google/Drive/File.hs
+++ b/src/Network/Google/Drive/File.hs
@@ -182,7 +182,7 @@
         , ("maxResults", Just "1000")
         ]
 
-    return $ items
+    return items
 
   where
     toParam :: Query -> ByteString
@@ -208,7 +208,7 @@
 newFile parent filePath = do
     modified <- liftIO $ getModificationTime filePath
 
-    return $ New $ FileData
+    return $ New FileData
         { fileTitle = T.pack $ takeFileName filePath
         , fileModified = modified
         , fileParents = [parent]
@@ -223,9 +223,9 @@
              -> Text   -- ^ Title to give the folder
              -> Api File
 createFolder parent title = do
-    modified <- liftIO $ getCurrentTime
+    modified <- liftIO getCurrentTime
 
-    postJSON (baseUrl <> "/files") [] $ FileData
+    postJSON (baseUrl <> "/files") [] FileData
         { fileTitle = title
         , fileModified = modified
         , fileParents = [parent]
diff --git a/src/Network/Google/Drive/Upload.hs b/src/Network/Google/Drive/Upload.hs
--- a/src/Network/Google/Drive/Upload.hs
+++ b/src/Network/Google/Drive/Upload.hs
@@ -59,7 +59,7 @@
            -> UploadSource
            -> Api File
 uploadFile file fileLength mkSource =
-    withSessionUrl file $ \url -> do
+    withSessionUrl file $ \url ->
         retryWithBackoff 1 $ do
             completed <- getUploadedBytes url
             resumeUpload url completed fileLength mkSource
