diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
-## 2.0.0.0 (4 Dev 2016)
+## 2.1.0.0 (5 Dec 2016)
+
+* Use `http-conduit` instead of `wreq` as HTTP client
+
+## 2.0.0.0 (4 Dec 2016)
 
 * Make `Line.Messaging.Webhook.Validation` independent from WAI. As it does not
   use `Request` of WAI, its argument type is changed.
diff --git a/examples/ScottyWebhook.hs b/examples/ScottyWebhook.hs
--- a/examples/ScottyWebhook.hs
+++ b/examples/ScottyWebhook.hs
@@ -25,7 +25,7 @@
 -- handler.
 app :: ScottyM ()
 app =
-  get "/webhook" $ do
+  post "/webhook" $ do
     channelSecret <- liftIO getChannelSecret
     webhookAction channelSecret handler defaultOnFailure'
 
diff --git a/line.cabal b/line.cabal
--- a/line.cabal
+++ b/line.cabal
@@ -1,5 +1,5 @@
 name: line
-version: 2.0.0.0
+version: 2.1.0.0
 cabal-version: >=1.10
 build-type: Simple
 license: BSD3
@@ -52,8 +52,7 @@
         cryptohash-sha256 >=0.11.100.1 && <0.12,
         base64-bytestring >=1.0.0.1 && <1.1,
         time >=1.6.0.1 && <1.7,
-        wreq >=0.4.1.0 && <0.5,
-        lens ==4.14.*,
+        http-conduit >=2.1.11 && <2.2,
         scotty >=0.11.0 && <0.12
     default-language: Haskell2010
     default-extensions: OverloadedStrings
@@ -65,7 +64,7 @@
     main-is: Spec.hs
     build-depends:
         base >=4.9.0.0 && <4.10,
-        line >=2.0.0.0 && <2.1,
+        line >=2.1.0.0 && <2.2,
         hspec >=2.2.4 && <2.3,
         hspec-wai >=0.6.6 && <0.7,
         QuickCheck >=2.8.2 && <2.9,
diff --git a/src/Line/Messaging/API.hs b/src/Line/Messaging/API.hs
--- a/src/Line/Messaging/API.hs
+++ b/src/Line/Messaging/API.hs
@@ -25,8 +25,6 @@
   ) where
 
 import Control.Exception (SomeException(..))
-import Control.Lens ((&), (.~), (^.))
-import Control.Monad.IO.Class (liftIO)
 import Control.Monad.Trans.Class (lift)
 import Control.Monad.Trans.Reader (runReaderT, ReaderT, ask)
 import Control.Monad.Trans.Except (runExceptT, ExceptT, throwE, catchE)
@@ -34,10 +32,11 @@
 import Data.Text.Encoding (encodeUtf8)
 import Line.Messaging.API.Types
 import Line.Messaging.Types (ReplyToken)
+import Network.HTTP.Simple
+import Network.HTTP.Types.Status (Status(..))
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.Text as T
-import qualified Network.Wreq as Wr
 
 -- | A monad transformer for API calls. If translated into a human-readable
 -- form, it means:
@@ -71,38 +70,36 @@
 runAPI :: IO ChannelAccessToken -> APIIO a -> IO (Either APIError a)
 runAPI getToken api = getToken >>= runExceptT . runReaderT api
 
-getOpts :: APIIO Wr.Options
-getOpts = do
+createReq :: B.ByteString -> String -> APIIO Request
+createReq method url = do
   token <- encodeUtf8 <$> ask
-  return $ Wr.defaults & Wr.header "Authorization" .~ [ "Bearer " `B.append` token ]
-                       & Wr.checkStatus .~ Just (\ _ _ _ -> Nothing) -- do not throw StatusCodeException
+  setRequestIgnoreStatus .
+    setRequestMethod method .
+    addRequestHeader "Authorization" ("Bearer " `B.append` token)
+    <$> parseRequest url
 
 handleError :: SomeException -> (ExceptT APIError IO) a
 handleError = throwE . UndefinedError
 
-runReqIO :: IO (Wr.Response BL.ByteString) -> APIIO BL.ByteString
-runReqIO reqIO = lift $ do
-  res <- liftIO reqIO `catchE` handleError
-  let statusCode = res ^. Wr.responseStatus . Wr.statusCode
-  let body = res ^. Wr.responseBody
-  case statusCode of
+runReq :: Request -> APIIO BL.ByteString
+runReq req = lift $ do
+  res <- httpLBS req `catchE` handleError
+  let status = statusCode $ getResponseStatus res
+  let body = getResponseBody res
+  case status of
     200 -> return $ body
     400 -> throwE $ BadRequest (decode' body)
     401 -> throwE $ Unauthorized (decode' body)
     403 -> throwE $ Forbidden (decode' body)
     429 -> throwE $ TooManyRequests (decode' body)
     500 -> throwE $ InternalServerError (decode' body)
-    _ -> throwE $ UndefinedStatusCode statusCode body
+    _ -> throwE $ UndefinedStatusCode status body
 
 get :: String -> APIIO BL.ByteString
-get url = do
-  opts <- getOpts
-  runReqIO $ Wr.getWith opts url
+get url = createReq "GET" url >>= runReq
 
 post :: ToJSON a => String -> a -> APIIO BL.ByteString
-post url body = do
-  opts <- getOpts
-  runReqIO $ Wr.postWith opts url (toJSON body)
+post url body = setRequestBodyJSON body <$> createReq "POST" url >>= runReq
 
 -- | Push messages into a receiver. The receiver can be a user, a room or
 -- a group, specified by 'ID'.
