diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,32 @@
+## 0.5.0
+
+* Support for OverloadedLabels
+
+  `twitter-conduit` now supports the OverloadedLabels extensions for overloaded parameters in `APIRequest` (e.g.: `#count`, `#max_id`).
+
+  We can now write:
+
+  ```haskell
+  homeTimeline & #count ?~ 200
+  ```
+
+  instead of:
+
+  ```haskell
+  import qualified Web.Twitter.Conduit.Parameters as P
+
+  homeTimeline & P.count ?~ 200
+  ```
+
+  NOTE: See `Web.Twitter.Conduit.ParametersDeprecated` module if you would like to use classic value lenses.
+
+* Drop supports conduit < 1.3 and http-conduit < 2.3 [#69](https://github.com/himura/twitter-conduit/pull/69).
+* `Web.Twitter.Conduit.Status` is no longer re-exported by Web.Twitter.Conduit in order to avoid name conflictions (e.g. `update`, `lookup`) [#71](https://github.com/himura/twitter-conduit/pull/71).
+* Add alias for functions in `Web.Twitter.Conduit.Status` with statuses- prefix [#71](https://github.com/himura/twitter-conduit/pull/71).
+  (e.g. `Web.Twitter.Conduit.Api.statusesHomeTimeline` for `Web.Twitter.Conduit.Status.homeTimeline`)
+* Drop supports network < 2.6 [#74](https://github.com/himura/twitter-conduit/pull/74).
+* Support `tweet_mode` parameter [#72](https://github.com/himura/twitter-conduit/pull/72).
+
 ## 0.4.0
 
 * Follow direct message API changes [#65](https://github.com/himura/twitter-conduit/pull/65) [#62](https://github.com/himura/twitter-conduit/pull/62)
diff --git a/Web/Twitter/Conduit.hs b/Web/Twitter/Conduit.hs
--- a/Web/Twitter/Conduit.hs
+++ b/Web/Twitter/Conduit.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
 
 -- |
@@ -21,7 +20,6 @@
        , module Web.Twitter.Conduit.Cursor
        , module Web.Twitter.Conduit.Request
        , module Web.Twitter.Conduit.Response
-       , module Web.Twitter.Conduit.Status
        , module Web.Twitter.Conduit.Stream
        , module Web.Twitter.Conduit.Types
 
@@ -38,10 +36,10 @@
        , sourceWithSearchResult'
 
        -- * 'Web.Twitter.Conduit.Parameters'
-       , Parameters.ListParam(..)
-       , Parameters.MediaData(..)
-       , Parameters.UserListParam(..)
-       , Parameters.UserParam(..)
+       , ListParam(..)
+       , MediaData(..)
+       , UserListParam(..)
+       , UserParam(..)
 
        -- * re-exports
        , OAuth (..)
@@ -55,16 +53,13 @@
 import Web.Twitter.Conduit.Api
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Cursor
-import qualified Web.Twitter.Conduit.Parameters as Parameters
+import Web.Twitter.Conduit.Parameters
 import Web.Twitter.Conduit.Request
 import Web.Twitter.Conduit.Response
-import Web.Twitter.Conduit.Status
 import Web.Twitter.Conduit.Stream
 import Web.Twitter.Conduit.Types
-import Web.Twitter.Types
 
 import Data.Default (def)
-import Data.Time.Calendar (Day)
 import Network.HTTP.Conduit (Manager, newManager, tlsManagerSettings)
 import Web.Authenticate.OAuth
 
@@ -76,9 +71,7 @@
 import Control.Monad.IO.Class
 import Control.Lens
 
-#ifdef HLINT
 {-# ANN module "HLint: ignore Use import/export shortcut" #-}
-#endif
 
 -- $howto
 --
@@ -161,7 +154,7 @@
 -- includes 20 tweets, and you can change the number of tweets by the /count/ parameter.
 --
 -- @
--- timeline \<- 'call' twInfo mgr '$' 'homeTimeline' '&' 'count' '?~' 200
+-- timeline \<- 'call' twInfo mgr '$' 'homeTimeline' '&' #count '?~' 200
 -- @
 --
 -- If you need more statuses, you can obtain those with multiple API requests.
@@ -171,7 +164,7 @@
 -- or use the conduit wrapper 'sourceWithCursor' as below:
 --
 -- @
--- friends \<- 'sourceWithCursor' twInfo mgr ('friendsList' ('ScreenNameParam' \"thimura\") '&' 'count' '?~' 200) '$$' 'CL.consume'
+-- friends \<- 'sourceWithCursor' twInfo mgr ('friendsList' ('ScreenNameParam' \"thimura\") '&' #count '?~' 200) '$$' 'CL.consume'
 -- @
 --
 -- Statuses APIs, for instance, 'homeTimeline', are also wrapped by 'sourceWithMaxId'.
diff --git a/Web/Twitter/Conduit/Api.hs b/Web/Twitter/Conduit/Api.hs
--- a/Web/Twitter/Conduit/Api.hs
+++ b/Web/Twitter/Conduit/Api.hs
@@ -1,14 +1,26 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeOperators #-}
 
 module Web.Twitter.Conduit.Api
        (
+       -- * Status
+         statusesMentionsTimeline
+       , statusesUserTimeline
+       , statusesHomeTimeline
+       , statusesRetweetsOfMe
+       , statusesRetweetsId
+       , statusesShowId
+       , statusesDestroyId
+       , statusesUpdate
+       , statusesRetweetId
+       , statusesUpdateWithMedia
+       , statusesLookup
+
        -- * Search
-         SearchTweets
+       , SearchTweets
        , searchTweets
        , search
 
@@ -144,23 +156,24 @@
        , mediaUpload
        ) where
 
-import Web.Twitter.Types
-import Web.Twitter.Conduit.Parameters hiding (description, name)
-import Web.Twitter.Conduit.Parameters.TH
 import Web.Twitter.Conduit.Base
-import Web.Twitter.Conduit.Request
 import Web.Twitter.Conduit.Cursor
+import Web.Twitter.Conduit.Parameters
+import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Request.Internal
+import qualified Web.Twitter.Conduit.Status as Status
+import Web.Twitter.Types
 
 import Network.HTTP.Client.MultipartFormData
 import qualified Data.Text as T
 import Data.Default
+import Data.Time.Calendar (Day)
 import Data.Aeson
 
 -- $setup
--- >>> :set -XOverloadedStrings
+-- >>> :set -XOverloadedStrings -XOverloadedLabels
 -- >>> import Control.Lens
 
-data SearchTweets
 -- | Returns search query.
 --
 -- You can perform a search query using 'call':
@@ -172,78 +185,73 @@
 --
 -- >>> searchTweets "search text"
 -- APIRequest "GET" "https://api.twitter.com/1.1/search/tweets.json" [("q","search text")]
--- >>> searchTweets "search text" & lang ?~ "ja" & count ?~ 100
+-- >>> searchTweets "search text" & #lang ?~ "ja" & #count ?~ 100
 -- APIRequest "GET" "https://api.twitter.com/1.1/search/tweets.json" [("count","100"),("lang","ja"),("q","search text")]
 searchTweets :: T.Text -- ^ search string
              -> APIRequest SearchTweets (SearchResult [Status])
 searchTweets q = APIRequest "GET" (endpoint ++ "search/tweets.json") [("q", PVString q)]
-deriveHasParamInstances ''SearchTweets
-    [ "lang"
-    , "locale"
-    -- , "result_type"
-    , "count"
-    , "until"
-    , "since_id"
-    , "max_id"
-    , "include_entities"
-    -- , "callback"  (needless)
+type SearchTweets = '[
+      "lang" ':= T.Text
+    , "locale" ':= T.Text
+    , "count" ':= Integer
+    , "until" ':= Day
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "include_entities" ':= Bool
     ]
 
 -- | Alias of 'searchTweets', for backward compatibility
 search :: T.Text -- ^ search string
        -> APIRequest SearchTweets (SearchResult [Status])
 search = searchTweets
+{-# DEPRECATED search "Please use Web.Twitter.Conduit.searchTweets" #-}
 
-data DirectMessages
 -- | Returns query data which asks recent direct messages sent to the authenticating user.
 --
 -- You can perform a query using 'call':
 --
 -- @
--- res <- 'call' twInfo mgr '$' 'directMessages' '&' 'count' '?~' 50
+-- res <- 'call' twInfo mgr '$' 'directMessages' '&' #count '?~' 50
 -- @
 --
 -- >>> directMessages
 -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/events/list.json" []
--- >>> directMessages & count ?~ 50
+-- >>> directMessages & #count ?~ 50
 -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/events/list.json" [("count","50")]
 directMessages :: APIRequest DirectMessages (WithCursor T.Text EventsCursorKey DirectMessage)
 directMessages = APIRequest "GET" (endpoint ++ "direct_messages/events/list.json") def
-deriveHasParamInstances ''DirectMessages
-    [ "count"
-    , "include_entities"
-    , "skip_status"
-    , "full_text"
+type DirectMessages = '[
+      "count" ':= Integer
+    , "include_entities" ':= Bool
+    , "skip_status" ':= Bool
+    , "full_text" ':= Bool
+    , "cursor" ':= T.Text
     ]
-instance HasCursorParam (APIRequest DirectMessages a) T.Text where
-    cursor = wrappedParam "cursor" PVString unPVString
 
-data DirectMessagesSent
 -- | Returns query data which asks recent direct messages sent by the authenticating user.
 --
 -- You can perform a query using 'call':
 --
 -- @
--- res <- 'call' twInfo mgr '$' 'directMessagesSent' '&' 'count' '?~' 100
+-- res <- 'call' twInfo mgr '$' 'directMessagesSent' '&' #count '?~' 100
 -- @
 --
 -- >>> directMessagesSent
 -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/sent.json" []
--- >>> directMessagesSent & count ?~ 100
+-- >>> directMessagesSent & #count ?~ 100
 -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/sent.json" [("count","100")]
 directMessagesSent :: APIRequest DirectMessagesSent [DirectMessage]
 directMessagesSent = APIRequest "GET" (endpoint ++ "direct_messages/sent.json") def
-deriveHasParamInstances ''DirectMessagesSent
-    [ "since_id"
-    , "max_id"
-    , "count"
-    , "include_entities"
-    , "page"
-    , "skip_status"
-    , "full_text"
+type DirectMessagesSent = '[
+      "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "count" ':= Integer
+    , "include_entities" ':= Bool
+    , "page" ':= Integer
+    , "skip_status" ':= Bool
+    , "full_text" ':= Bool
     ]
 
-data DirectMessagesShow
 -- | Returns query data which asks a single direct message, specified by an id parameter.
 --
 -- You can perform a query using 'call':
@@ -256,11 +264,10 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/show.json" [("id","1234567890")]
 directMessagesShow :: StatusId -> APIRequest DirectMessagesShow DirectMessage
 directMessagesShow sId = APIRequest "GET" (endpoint ++ "direct_messages/show.json") [("id", PVInteger sId)]
-deriveHasParamInstances ''DirectMessagesShow
-    [ "full_text"
+type DirectMessagesShow = '[
+      "full_text" ':= Bool
     ]
 
-data DirectMessagesDestroy
 -- | Returns post data which destroys the direct message specified in the required ID parameter.
 --
 -- You can perform a query using 'call':
@@ -273,6 +280,7 @@
 -- APIRequest "DELETE" "https://api.twitter.com/1.1/direct_messages/events/destroy.json" [("id","1234567890")]
 directMessagesDestroy :: StatusId -> APIRequest DirectMessagesDestroy NoContent
 directMessagesDestroy sId = APIRequest "DELETE" (endpoint ++ "direct_messages/events/destroy.json") [("id", PVInteger sId)]
+type DirectMessagesDestroy = EmptyParams
 
 newtype DirectMessagesNewResponse = DirectMessagesNewResponse
     { directMessageBody :: DirectMessage
@@ -281,7 +289,6 @@
 instance FromJSON DirectMessagesNewResponse where
     parseJSON = withObject "DirectMessagesNewResponse" $ \o -> DirectMessagesNewResponse <$> o .: "event"
 
-data DirectMessagesNew
 -- | Returns post data which sends a new direct message to the specified user from the authenticating user.
 --
 -- You can perform a post using 'call':
@@ -308,10 +315,10 @@
                         ]
                   ]
             ]
+type DirectMessagesNew = EmptyParams
 
 type RecipientId = Integer
 
-data FriendshipsNoRetweetsIds
 -- | Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from.
 --
 -- You can perform a request using 'call':
@@ -324,8 +331,8 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/no_retweets/ids.json" []
 friendshipsNoRetweetsIds :: APIRequest FriendshipsNoRetweetsIds [UserId]
 friendshipsNoRetweetsIds = APIRequest "GET" (endpoint ++ "friendships/no_retweets/ids.json") []
+type FriendshipsNoRetweetsIds = EmptyParams
 
-data FriendsIds
 -- | Returns query data which asks a collection of user IDs for every user the specified user is following.
 --
 -- You can perform a query using 'call':
@@ -342,17 +349,15 @@
 --
 -- >>> friendsIds (ScreenNameParam "thimura")
 -- APIRequest "GET" "https://api.twitter.com/1.1/friends/ids.json" [("screen_name","thimura")]
--- >>> friendsIds (ScreenNameParam "thimura") & count ?~ 5000
+-- >>> friendsIds (ScreenNameParam "thimura") & #count ?~ 5000
 -- APIRequest "GET" "https://api.twitter.com/1.1/friends/ids.json" [("count","5000"),("screen_name","thimura")]
 friendsIds :: UserParam -> APIRequest FriendsIds (WithCursor Integer IdsCursorKey UserId)
 friendsIds q = APIRequest "GET" (endpoint ++ "friends/ids.json") (mkUserParam q)
-deriveHasParamInstances ''FriendsIds
-    [ "count"
+type FriendsIds = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
     ]
-instance HasCursorParam (APIRequest FriendsIds a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data FollowersIds
 -- | Returns query data which asks a collection of user IDs for every user following the specified user.
 --
 -- You can perform a query using 'call':
@@ -369,17 +374,15 @@
 --
 -- >>> followersIds (ScreenNameParam "thimura")
 -- APIRequest "GET" "https://api.twitter.com/1.1/followers/ids.json" [("screen_name","thimura")]
--- >>> followersIds (ScreenNameParam "thimura") & count ?~ 5000
+-- >>> followersIds (ScreenNameParam "thimura") & #count ?~ 5000
 -- APIRequest "GET" "https://api.twitter.com/1.1/followers/ids.json" [("count","5000"),("screen_name","thimura")]
 followersIds :: UserParam -> APIRequest FollowersIds (WithCursor Integer IdsCursorKey UserId)
 followersIds q = APIRequest "GET" (endpoint ++ "followers/ids.json") (mkUserParam q)
-deriveHasParamInstances ''FollowersIds
-    [ "count"
+type FollowersIds = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
     ]
-instance HasCursorParam (APIRequest FollowersIds a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data FriendshipsIncoming
 -- | Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user.
 --
 -- You can perform a request by using 'call':
@@ -398,10 +401,10 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/incoming.json" []
 friendshipsIncoming :: APIRequest FriendshipsIncoming (WithCursor Integer IdsCursorKey UserId)
 friendshipsIncoming = APIRequest "GET" (endpoint ++ "friendships/incoming.json") def
-instance HasCursorParam (APIRequest FriendshipsIncoming a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
+type FriendshipsIncoming = '[
+      "cursor" ':= Integer
+    ]
 
-data FriendshipsOutgoing
 -- | Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request.
 --
 -- You can perform a request by using 'call':
@@ -420,10 +423,10 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/outgoing.json" []
 friendshipsOutgoing :: APIRequest FriendshipsOutgoing (WithCursor Integer IdsCursorKey UserId)
 friendshipsOutgoing = APIRequest "GET" (endpoint ++ "friendships/outgoing.json") def
-instance HasCursorParam (APIRequest FriendshipsOutgoing a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
+type FriendshipsOutgoing = '[
+      "cursor" ':= Integer
+    ]
 
-data FriendshipsCreate
 -- | Returns post data which follows the user specified in the ID parameter.
 --
 -- You can perform request by using 'call':
@@ -438,11 +441,10 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/friendships/create.json" [("user_id","69179963")]
 friendshipsCreate :: UserParam -> APIRequest FriendshipsCreate User
 friendshipsCreate user = APIRequest "POST" (endpoint ++ "friendships/create.json") (mkUserParam user)
-deriveHasParamInstances ''FriendshipsCreate
-    [ "follow"
+type FriendshipsCreate = '[
+      "follow" ':= Bool
     ]
 
-data FriendshipsDestroy
 -- | Returns post data which unfollows the user specified in the ID parameter.
 --
 -- You can perform request by using 'call':
@@ -457,8 +459,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/friendships/destroy.json" [("user_id","69179963")]
 friendshipsDestroy :: UserParam -> APIRequest FriendshipsDestroy User
 friendshipsDestroy user = APIRequest "POST" (endpoint ++ "friendships/destroy.json") (mkUserParam user)
+type FriendshipsDestroy = EmptyParams
 
-data FriendsList
 -- | Returns query data which asks a cursored collection of user objects for every user the specified users is following.
 --
 -- You can perform request by using 'call':
@@ -479,15 +481,13 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/friends/list.json" [("user_id","69179963")]
 friendsList :: UserParam -> APIRequest FriendsList (WithCursor Integer UsersCursorKey User)
 friendsList q = APIRequest "GET" (endpoint ++ "friends/list.json") (mkUserParam q)
-deriveHasParamInstances ''FriendsList
-    [ "count"
-    , "skip_status"
-    , "include_user_entities"
+type FriendsList = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
+    , "skip_status" ':= Bool
+    , "include_user_entities" ':= Bool
     ]
-instance HasCursorParam (APIRequest FriendsList a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data FollowersList
 -- | Returns query data which asks a cursored collection of user objects for users following the specified user.
 --
 -- You can perform request by using 'call':
@@ -508,15 +508,13 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/followers/list.json" [("user_id","69179963")]
 followersList :: UserParam -> APIRequest FollowersList (WithCursor Integer UsersCursorKey User)
 followersList q = APIRequest "GET" (endpoint ++ "followers/list.json") (mkUserParam q)
-deriveHasParamInstances ''FollowersList
-    [ "count"
-    , "skip_status"
-    , "include_user_entities"
+type FollowersList = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
+    , "skip_status" ':= Bool
+    , "include_user_entities" ':= Bool
     ]
-instance HasCursorParam (APIRequest FollowersList a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data AccountVerifyCredentials
 -- | Returns query data asks that the credential is valid.
 --
 -- You can perform request by using 'call':
@@ -529,37 +527,35 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/account/verify_credentials.json" []
 accountVerifyCredentials :: APIRequest AccountVerifyCredentials User
 accountVerifyCredentials = APIRequest "GET" (endpoint ++ "account/verify_credentials.json") []
-deriveHasParamInstances ''AccountVerifyCredentials
-    [ "include_entities"
-    , "skip_status"
-    , "include_email"
+type AccountVerifyCredentials = '[
+      "include_entities" ':= Bool
+    , "skip_status" ':= Bool
+    , "include_email" ':= Bool
     ]
 
-data AccountUpdateProfile
 -- | Returns user object with updated fields.
 -- Note that while no specific parameter is required, you need to provide at least one parameter before executing the query.
 --
 -- You can perform request by using 'call':
 --
 -- @
--- res <- 'call' twInfo mgr '$' 'accountUpdateProfile' & 'Web.Twitter.Conduit.Parameters.url' ?~ \"http://www.example.com\"
+-- res <- 'call' twInfo mgr '$' 'accountUpdateProfile' & #url ?~ \"http://www.example.com\"
 -- @
 --
--- >>> accountUpdateProfile & url ?~ "http://www.example.com"
+-- >>> accountUpdateProfile & #url ?~ "http://www.example.com"
 -- APIRequest "POST" "https://api.twitter.com/1.1/account/update_profile.json" [("url","http://www.example.com")]
 accountUpdateProfile :: APIRequest AccountUpdateProfile User
 accountUpdateProfile = APIRequest "POST" (endpoint ++ "account/update_profile.json") []
-deriveHasParamInstances ''AccountUpdateProfile
-    [ "include_entities"
-    , "skip_status"
-    , "name"
-    , "url"
-    , "location"
-    , "description"
-    , "profile_link_color"
+type AccountUpdateProfile = '[
+      "include_entities" ':= Bool
+    , "skip_status" ':= Bool
+    , "name" ':= T.Text
+    , "url" ':= URIString
+    , "location" ':= T.Text
+    , "description" ':= T.Text
+    , "profile_link_color" ':= T.Text
     ]
 
-data UsersLookup
 -- | Returns query data asks user objects.
 --
 -- You can perform request by using 'call':
@@ -572,11 +568,10 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/users/lookup.json" [("screen_name","thimura,twitterapi")]
 usersLookup :: UserListParam -> APIRequest UsersLookup [User]
 usersLookup q = APIRequest "GET" (endpoint ++ "users/lookup.json") (mkUserListParam q)
-deriveHasParamInstances ''UsersLookup
-    [ "include_entities"
+type UsersLookup = '[
+      "include_entities" ':= Bool
     ]
 
-data UsersShow
 -- | Returns query data asks the user specified by user id or screen name parameter.
 --
 -- You can perform request by using 'call':
@@ -589,11 +584,10 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/users/show.json" [("screen_name","thimura")]
 usersShow :: UserParam -> APIRequest UsersShow User
 usersShow q = APIRequest "GET" (endpoint ++ "users/show.json") (mkUserParam q)
-deriveHasParamInstances ''UsersShow
-    [ "include_entities"
+type UsersShow = '[
+      "include_entities" ':= Bool
     ]
 
-data FavoritesList
 -- | Returns the 20 most recent Tweets favorited by the specified user.
 --
 -- You can perform request by using 'call':
@@ -613,14 +607,13 @@
   where
     mkParam Nothing = []
     mkParam (Just usr) = mkUserParam usr
-deriveHasParamInstances ''FavoritesList
-    [ "count"
-    , "since_id"
-    , "max_id"
-    , "include_entities"
+type FavoritesList = '[
+      "count" ':= Integer
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "include_entities" ':= Bool
     ]
 
-data FavoritesCreate
 -- | Returns post data which favorites the status specified in the ID parameter as the authenticating user.
 --
 -- You can perform request by using 'call':
@@ -633,11 +626,10 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/favorites/create.json" [("id","1234567890")]
 favoritesCreate :: StatusId -> APIRequest FavoritesCreate Status
 favoritesCreate sid = APIRequest "POST" (endpoint ++ "favorites/create.json") [("id", PVInteger sid)]
-deriveHasParamInstances ''FavoritesCreate
-    [ "include_entities"
+type FavoritesCreate = '[
+      "include_entities" ':= Bool
     ]
 
-data FavoritesDestroy
 -- | Returns post data unfavorites the status specified in the ID paramter as the authenticating user.
 --
 -- You can perform request by using 'call':
@@ -650,11 +642,10 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/favorites/destroy.json" [("id","1234567890")]
 favoritesDestroy :: StatusId -> APIRequest FavoritesDestroy Status
 favoritesDestroy sid = APIRequest "POST" (endpoint ++ "favorites/destroy.json") [("id", PVInteger sid)]
-deriveHasParamInstances ''FavoritesDestroy
-    [ "include_entities"
+type FavoritesDestroy = '[
+      "include_entities" ':= Bool
     ]
 
-data ListsStatuses
 -- | Returns the query parameter which fetches a timeline of tweets authored by members of the specified list.
 --
 -- You can perform request by using 'call':
@@ -665,7 +656,7 @@
 --
 -- If you need more statuses, you can obtain those by using 'sourceWithMaxId':
 -- @
--- res <- sourceWithMaxId ('listsStatuses' ('ListNameParam' "thimura/haskell") & count ?~ 200) $$ CL.take 1000
+-- res <- sourceWithMaxId ('listsStatuses' ('ListNameParam' "thimura/haskell") & #count ?~ 200) $$ CL.take 1000
 -- @
 --
 -- >>> listsStatuses (ListNameParam "thimura/haskell")
@@ -674,15 +665,14 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/statuses.json" [("list_id","20849097")]
 listsStatuses :: ListParam -> APIRequest ListsStatuses [Status]
 listsStatuses q = APIRequest "GET" (endpoint ++ "lists/statuses.json") (mkListParam q)
-deriveHasParamInstances ''ListsStatuses
-    [ "since_id"
-    , "max_id"
-    , "count"
-    , "include_entities"
-    , "include_rts"
+type ListsStatuses = '[
+      "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "count" ':= Integer
+    , "include_entities" ':= Bool
+    , "include_rts" ':= Bool
     ]
 
-data ListsMembersDestroy
 -- | Returns the post parameter which removes the specified member from the list.
 --
 -- You can perform request by using 'call':
@@ -697,8 +687,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/destroy.json" [("list_id","20849097"),("user_id","69179963")]
 listsMembersDestroy :: ListParam -> UserParam -> APIRequest ListsMembersDestroy List
 listsMembersDestroy list user = APIRequest "POST" (endpoint ++ "lists/members/destroy.json") (mkListParam list ++ mkUserParam user)
+type ListsMembersDestroy = EmptyParams
 
-data ListsMemberships
 -- | Returns the request parameters which asks the lists the specified user has been added to.
 -- If 'UserParam' are not provided, the memberships for the authenticating user are returned.
 --
@@ -716,13 +706,11 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/memberships.json" [("user_id","69179963")]
 listsMemberships :: Maybe UserParam -> APIRequest ListsMemberships (WithCursor Integer ListsCursorKey List)
 listsMemberships q = APIRequest "GET" (endpoint ++ "lists/memberships.json") $ maybe [] mkUserParam q
-deriveHasParamInstances ''ListsMemberships
-    [ "count"
+type ListsMemberships = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
     ]
-instance HasCursorParam (APIRequest ListsMemberships a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data ListsSubscribers
 -- | Returns the request parameter which asks the subscribers of the specified list.
 --
 -- You can perform request by using 'call':
@@ -737,14 +725,12 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/subscribers.json" [("list_id","20849097")]
 listsSubscribers :: ListParam -> APIRequest ListsSubscribers (WithCursor Integer UsersCursorKey User)
 listsSubscribers q = APIRequest "GET" (endpoint ++ "lists/subscribers.json") (mkListParam q)
-deriveHasParamInstances ''ListsSubscribers
-    [ "count"
-    , "skip_status"
+type ListsSubscribers = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
+    , "skip_status" ':= Bool
     ]
-instance HasCursorParam (APIRequest ListsSubscribers a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data ListsSubscriptions
 -- | Returns the request parameter which obtains a collection of the lists the specified user is subscribed to.
 --
 -- You can perform request by using 'call':
@@ -761,13 +747,11 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/subscriptions.json" [("user_id","69179963")]
 listsSubscriptions :: Maybe UserParam -> APIRequest ListsSubscriptions (WithCursor Integer ListsCursorKey List)
 listsSubscriptions q = APIRequest "GET" (endpoint ++ "lists/subscriptions.json") $ maybe [] mkUserParam q
-deriveHasParamInstances ''ListsSubscriptions
-    [ "count"
+type ListsSubscriptions = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
     ]
-instance HasCursorParam (APIRequest ListsSubscriptions a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data ListsOwnerships
 -- | Returns the request parameter which asks the lists owned by the specified Twitter user.
 --
 -- You can perform request by using 'call':
@@ -784,13 +768,11 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/ownerships.json" [("user_id","69179963")]
 listsOwnerships :: Maybe UserParam -> APIRequest ListsOwnerships (WithCursor Integer ListsCursorKey List)
 listsOwnerships q = APIRequest "GET" (endpoint ++ "lists/ownerships.json") $ maybe [] mkUserParam q
-deriveHasParamInstances ''ListsOwnerships
-    [ "count"
+type ListsOwnerships = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
     ]
-instance HasCursorParam (APIRequest ListsOwnerships a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data ListsMembersCreateAll
 -- | Adds multiple members to a list.
 --
 -- You can perform request by using 'call':
@@ -805,8 +787,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/create_all.json" [("list_id","20849097"),("user_id","69179963,6253282")]
 listsMembersCreateAll :: ListParam -> UserListParam -> APIRequest ListsMembersCreateAll List
 listsMembersCreateAll list users = APIRequest "POST" (endpoint ++ "lists/members/create_all.json") (mkListParam list ++ mkUserListParam users)
+type ListsMembersCreateAll = EmptyParams
 
-data ListsMembersDestroyAll
 -- | Adds multiple members to a list.
 --
 -- You can perform request by using 'call':
@@ -821,8 +803,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/destroy_all.json" [("list_id","20849097"),("user_id","69179963,6253282")]
 listsMembersDestroyAll :: ListParam -> UserListParam -> APIRequest ListsMembersDestroyAll List
 listsMembersDestroyAll list users = APIRequest "POST" (endpoint ++ "lists/members/destroy_all.json") (mkListParam list ++ mkUserListParam users)
+type ListsMembersDestroyAll = EmptyParams
 
-data ListsMembers
 -- | Returns query data asks the members of the specified list.
 --
 -- You can perform request by using 'call':
@@ -837,14 +819,12 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/members.json" [("list_id","20849097")]
 listsMembers :: ListParam -> APIRequest ListsMembers (WithCursor Integer UsersCursorKey User)
 listsMembers q = APIRequest "GET" (endpoint ++ "lists/members.json") (mkListParam q)
-deriveHasParamInstances ''ListsMembers
-    [ "count"
-    , "skip_status"
+type ListsMembers = '[
+      "count" ':= Integer
+    , "cursor" ':= Integer
+    , "skip_status" ':= Bool
     ]
-instance HasCursorParam (APIRequest ListsMembers a) Integer where
-    cursor = wrappedParam "cursor" PVInteger unPVInteger
 
-data ListsMembersCreate
 -- | Returns the post parameter which adds a member to a list.
 --
 -- You can perform request by using 'call':
@@ -859,8 +839,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/create.json" [("list_id","20849097"),("user_id","69179963")]
 listsMembersCreate :: ListParam -> UserParam -> APIRequest ListsMembersCreate List
 listsMembersCreate list user = APIRequest "POST" (endpoint ++ "lists/members/create.json") (mkListParam list ++ mkUserParam user)
+type ListsMembersCreate = EmptyParams
 
-data ListsDestroy
 -- | Returns the post parameter which deletes the specified list.
 --
 -- You can perform request by using 'call':
@@ -875,8 +855,8 @@
 -- APIRequest "POST" "https://api.twitter.com/1.1/lists/destroy.json" [("list_id","20849097")]
 listsDestroy :: ListParam -> APIRequest ListsDestroy List
 listsDestroy list = APIRequest "POST" (endpoint ++ "lists/destroy.json") (mkListParam list)
+type ListsDestroy = EmptyParams
 
-data ListsUpdate
 -- | Returns the post parameter which updates the specified list.
 --
 -- You can perform request by using 'call':
@@ -897,8 +877,8 @@
     p' = maybe id (\d -> (("description", PVString d):)) description p
     mode True = "public"
     mode False = "private"
+type ListsUpdate = EmptyParams
 
-data ListsCreate
 -- | Returns the post parameter which creates a new list for the authenticated user.
 --
 -- You can perform request by using 'call':
@@ -923,8 +903,8 @@
     p' = maybe id (\d -> (("description", PVString d):)) description p
     mode True = "public"
     mode False = "private"
+type ListsCreate = EmptyParams
 
-data ListsShow
 -- | Returns the request parameter which asks the specified list.
 --
 -- You can perform request by using 'call':
@@ -939,8 +919,8 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/lists/show.json" [("list_id","20849097")]
 listsShow :: ListParam -> APIRequest ListsShow List
 listsShow q = APIRequest "GET" (endpoint ++ "lists/show.json") (mkListParam q)
+type ListsShow = EmptyParams
 
-data MediaUpload
 -- | Upload media and returns the media data.
 --
 -- You can update your status with multiple media by calling 'mediaUpload' and 'update' successively.
@@ -955,7 +935,7 @@
 -- and then collect the resulting media IDs and update your status by calling 'update':
 --
 -- @
--- 'call' twInfo mgr '$' 'update' \"Hello World\" '&' 'mediaIds' '?~' ['mediaId' res1, 'mediaId' res2]
+-- 'call' twInfo mgr '$' 'update' \"Hello World\" '&' #media_ids '?~' ['uploadedMediaId' res1, 'uploadedMediaId' res2]
 -- @
 --
 -- See: <https://dev.twitter.com/docs/api/multiple-media-extended-entities>
@@ -970,3 +950,27 @@
     uri = "https://upload.twitter.com/1.1/media/upload.json"
     mediaBody (MediaFromFile fp) = partFileSource "media" fp
     mediaBody (MediaRequestBody filename filebody) = partFileRequestBody "media" filename filebody
+type MediaUpload = EmptyParams
+
+statusesMentionsTimeline :: APIRequest Status.StatusesMentionsTimeline [Status]
+statusesMentionsTimeline = Status.mentionsTimeline
+statusesUserTimeline :: UserParam -> APIRequest Status.StatusesUserTimeline [Status]
+statusesUserTimeline = Status.userTimeline
+statusesHomeTimeline :: APIRequest Status.StatusesHomeTimeline [Status]
+statusesHomeTimeline = Status.homeTimeline
+statusesRetweetsOfMe :: APIRequest Status.StatusesRetweetsOfMe [Status]
+statusesRetweetsOfMe = Status.retweetsOfMe
+statusesRetweetsId :: StatusId -> APIRequest Status.StatusesRetweetsId [RetweetedStatus]
+statusesRetweetsId = Status.retweetsId
+statusesShowId :: StatusId -> APIRequest Status.StatusesShowId Status
+statusesShowId = Status.showId
+statusesDestroyId :: StatusId -> APIRequest Status.StatusesDestroyId Status
+statusesDestroyId = Status.destroyId
+statusesUpdate :: T.Text -> APIRequest Status.StatusesUpdate Status
+statusesUpdate = Status.update
+statusesRetweetId :: StatusId -> APIRequest Status.StatusesRetweetId RetweetedStatus
+statusesRetweetId = Status.retweetId
+statusesUpdateWithMedia :: T.Text -> MediaData -> APIRequest Status.StatusesUpdateWithMedia Status
+statusesUpdateWithMedia = Status.updateWithMedia
+statusesLookup :: [StatusId] -> APIRequest Status.StatusesLookup [Status]
+statusesLookup = Status.lookup
diff --git a/Web/Twitter/Conduit/Base.hs b/Web/Twitter/Conduit/Base.hs
--- a/Web/Twitter/Conduit/Base.hs
+++ b/Web/Twitter/Conduit/Base.hs
@@ -1,8 +1,12 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedLabels #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 module Web.Twitter.Conduit.Base
@@ -27,33 +31,35 @@
        ) where
 
 import Web.Twitter.Conduit.Cursor
-import Web.Twitter.Conduit.Parameters hiding (url)
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Request.Internal
 import Web.Twitter.Conduit.Response
 import Web.Twitter.Conduit.Types
 import Web.Twitter.Types.Lens
 
 import Control.Lens
 import Control.Monad (void)
-import Control.Monad.Base
 import Control.Monad.Catch (MonadThrow (..))
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Resource (MonadResource, ResourceT, runResourceT)
 import Data.Aeson
 import Data.Aeson.Lens
 import Data.ByteString (ByteString)
+import Data.Coerce
 import qualified Data.Conduit as C
 import qualified Data.Conduit.Attoparsec as CA
 import qualified Data.Conduit.List as CL
 import qualified Data.Map as M
-import Data.Monoid
 import qualified Data.Text.Encoding as T
 import Network.HTTP.Client.MultipartFormData
 import qualified Network.HTTP.Conduit as HTTP
 import qualified Network.HTTP.Types as HT
-import Unsafe.Coerce
 import Web.Authenticate.OAuth (signOAuth)
 
+#if __GLASGOW_HASKELL__ < 804
+import Data.Monoid
+#endif
+
 makeRequest :: APIRequest apiName responseType
             -> IO HTTP.Request
 makeRequest (APIRequest m u pa) = makeRequest' m u (makeSimpleQuery pa)
@@ -75,28 +81,16 @@
              -> HT.SimpleQuery -- ^ Query
              -> IO HTTP.Request
 makeRequest' m url query = do
-#if MIN_VERSION_http_client(0,4,30)
     req <- HTTP.parseRequest url
-#else
-    req <- HTTP.parseUrl url
-#endif
     let addParams =
             if m == "POST"
             then HTTP.urlEncodedBody query
             else \r -> r { HTTP.queryString = HT.renderSimpleQuery False query }
-    return $ addParams $ req { HTTP.method = m
-#if !MIN_VERSION_http_client(0,4,30)
-                             , HTTP.checkStatus = \_ _ _ -> Nothing
-#endif
-                             }
+    return $ addParams $ req { HTTP.method = m }
 
 class ResponseBodyType a where
     parseResponseBody ::
-#if MIN_VERSION_http_conduit(2,3,0)
            Response (C.ConduitM () ByteString (ResourceT IO) ())
-#else
-           Response (C.ResumableSource m ByteString)
-#endif
         -> ResourceT IO (Response a)
 
 type NoContent = ()
@@ -115,11 +109,7 @@
             => TWInfo
             -> HTTP.Manager
             -> HTTP.Request
-#if MIN_VERSION_http_conduit(2,3,0)
             -> m (Response (C.ConduitM () ByteString m ()))
-#else
-            -> m (Response (C.ResumableSource m ByteString))
-#endif
 getResponse TWInfo{..} mgr req = do
     signedReq <- signOAuth (twOAuth twToken) (twCredential twToken) $ req { HTTP.proxy = twProxy }
     res <- HTTP.http signedReq mgr
@@ -133,19 +123,11 @@
 endpoint = "https://api.twitter.com/1.1/"
 
 getValue ::
-#if MIN_VERSION_http_conduit(2,3,0)
             Response (C.ConduitM () ByteString (ResourceT IO) ())
-#else
-            Response (C.ResumableSource (ResourceT IO) ByteString)
-#endif
          -> ResourceT IO (Response Value)
 getValue res = do
     value <-
-#if MIN_VERSION_http_conduit(2,3,0)
       C.runConduit $ responseBody res C..| sinkJSON
-#else
-      responseBody res C.$$+- sinkJSON
-#endif
     return $ res { responseBody = value }
 
 checkResponse :: Response Value
@@ -166,11 +148,7 @@
     sci = HT.statusCode responseStatus
 
 getValueOrThrow :: FromJSON a
-#if MIN_VERSION_http_conduit(2,3,0)
                 => Response (C.ConduitM () ByteString (ResourceT IO) ())
-#else
-                => Response (C.ResumableSource (ResourceT IO) ByteString)
-#endif
                 -> ResourceT IO (Response a)
 getValueOrThrow res = do
     res' <- getValue res
@@ -255,12 +233,12 @@
 sourceWithMaxId :: ( MonadIO m
                    , FromJSON responseType
                    , AsStatus responseType
-                   , HasMaxIdParam (APIRequest apiName [responseType])
+                   , HasParam "max_id" Integer supports
                    )
                 => TWInfo -- ^ Twitter Setting
                 -> HTTP.Manager
-                -> APIRequest apiName [responseType]
-                -> C.Source m responseType
+                -> APIRequest supports [responseType]
+                -> C.ConduitT () responseType m ()
 sourceWithMaxId info mgr = loop
   where
     loop req = do
@@ -268,7 +246,7 @@
         case getMinId res of
             Just mid -> do
                 CL.sourceList res
-                loop $ req & maxId ?~ mid - 1
+                loop $ req & #max_id ?~ mid - 1
             Nothing -> CL.sourceList res
     getMinId = minimumOf (traverse . status_id)
 
@@ -278,22 +256,21 @@
 --
 -- This function cooperate with instances of 'HasMaxIdParam'.
 sourceWithMaxId' :: ( MonadIO m
-                    , HasMaxIdParam (APIRequest apiName [responseType])
+                    , HasParam "max_id" Integer supports
                     )
                  => TWInfo -- ^ Twitter Setting
                  -> HTTP.Manager
-                 -> APIRequest apiName [responseType]
-                 -> C.Source m Value
+                 -> APIRequest supports [responseType]
+                 -> C.ConduitT () Value m ()
 sourceWithMaxId' info mgr = loop
   where
     loop req = do
-        res <- liftIO $ call' info mgr req
-        case getMinId res of
+        (res :: [Value]) <- liftIO $ call' info mgr req
+        case minimumOf (traverse . key "id" . _Integer) res of
             Just mid -> do
                 CL.sourceList res
-                loop $ req & maxId ?~ mid - 1
+                loop $ req & #max_id ?~ mid - 1
             Nothing -> CL.sourceList res
-    getMinId = minimumOf (traverse . key "id" . _Integer)
 
 -- | A wrapper function to perform multiple API request with changing @cursor@ parameter.
 --
@@ -301,18 +278,18 @@
 sourceWithCursor :: ( MonadIO m
                     , FromJSON responseType
                     , CursorKey ck
-                    , HasCursorParam (APIRequest apiName (WithCursor Integer ck responseType)) Integer
+                    , HasParam "cursor" Integer supports
                     )
                  => TWInfo -- ^ Twitter Setting
                  -> HTTP.Manager
-                 -> APIRequest apiName (WithCursor Integer ck responseType)
-                 -> C.Source m responseType
+                 -> APIRequest supports (WithCursor Integer ck responseType)
+                 -> C.ConduitT () responseType m ()
 sourceWithCursor info mgr req = loop (Just (-1))
   where
     loop Nothing = CL.sourceNull
     loop (Just 0) = CL.sourceNull
     loop (Just cur) = do
-        res <- liftIO $ call info mgr $ req & cursor ?~ cur
+        res <- liftIO $ call info mgr $ req & #cursor ?~ cur
         CL.sourceList $ contents res
         loop $ nextCursor res
 
@@ -323,21 +300,21 @@
 -- This function cooperate with instances of 'HasCursorParam'.
 sourceWithCursor' :: ( MonadIO m
                      , CursorKey ck
-                     , HasCursorParam (APIRequest apiName (WithCursor Integer ck responseType)) Integer
+                     , HasParam "cursor" Integer supports
                      )
                   => TWInfo -- ^ Twitter Setting
                   -> HTTP.Manager
-                  -> APIRequest apiName (WithCursor Integer ck responseType)
-                  -> C.Source m Value
+                  -> APIRequest supports (WithCursor Integer ck responseType)
+                  -> C.ConduitT () Value m ()
 sourceWithCursor' info mgr req = loop (Just (-1))
   where
     relax :: APIRequest apiName (WithCursor Integer ck responseType)
           -> APIRequest apiName (WithCursor Integer ck Value)
-    relax = unsafeCoerce
+    relax = coerce
     loop Nothing = CL.sourceNull
     loop (Just 0) = CL.sourceNull
     loop (Just cur) = do
-        res <- liftIO $ call info mgr $ relax $ req & cursor ?~ cur
+        res <- liftIO $ call info mgr $ relax $ req & #cursor ?~ cur
         CL.sourceList $ contents res
         loop $ nextCursor res
 
@@ -347,8 +324,8 @@
                           )
                        => TWInfo -- ^ Twitter Setting
                        -> HTTP.Manager
-                       -> APIRequest apiName (SearchResult [responseType])
-                       -> m (SearchResult (C.Source m responseType))
+                       -> APIRequest supports (SearchResult [responseType])
+                       -> m (SearchResult (C.ConduitT () responseType m ()))
 sourceWithSearchResult info mgr req = do
     res <- liftIO $ call info mgr req
     let body = CL.sourceList (res ^. searchResultStatuses) <>
@@ -369,8 +346,8 @@
                            )
                         => TWInfo -- ^ Twitter Setting
                         -> HTTP.Manager
-                        -> APIRequest apiName (SearchResult [responseType])
-                        -> m (SearchResult (C.Source m Value))
+                        -> APIRequest supports (SearchResult [responseType])
+                        -> m (SearchResult (C.ConduitT () Value m ()))
 sourceWithSearchResult' info mgr req = do
     res <- liftIO $ call info mgr $ relax req
     let body = CL.sourceList (res ^. searchResultStatuses) <>
@@ -380,7 +357,7 @@
     origQueryMap = req ^. params . to M.fromList
     relax :: APIRequest apiName (SearchResult [responseType])
           -> APIRequest apiName (SearchResult [Value])
-    relax = unsafeCoerce
+    relax = coerce
     loop Nothing = CL.sourceNull
     loop (Just nextResultsStr) = do
         let nextResults = nextResultsStr & HT.parseSimpleQuery . T.encodeUtf8 & traversed . _2 %~ (PVString . T.decodeUtf8)
@@ -390,12 +367,12 @@
         loop $ res ^. searchResultSearchMetadata . searchMetadataNextResults
 
 sinkJSON :: ( MonadThrow m
-            ) => C.Consumer ByteString m Value
+            ) => C.ConduitT ByteString o m Value
 sinkJSON = CA.sinkParser json
 
 sinkFromJSON :: ( FromJSON a
                 , MonadThrow m
-                ) => C.Consumer ByteString m a
+                ) => C.ConduitT ByteString o m a
 sinkFromJSON = do
     v <- sinkJSON
     case fromJSON v of
diff --git a/Web/Twitter/Conduit/Cursor.hs b/Web/Twitter/Conduit/Cursor.hs
--- a/Web/Twitter/Conduit/Cursor.hs
+++ b/Web/Twitter/Conduit/Cursor.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE CPP #-}
 
 module Web.Twitter.Conduit.Cursor
        ( CursorKey (..)
@@ -12,10 +11,6 @@
        , WithCursor (..)
        ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Control.Applicative
-import Data.Monoid
-#endif
 import Data.Aeson
 import Data.Text (Text)
 import Web.Twitter.Types (checkError)
@@ -45,7 +40,6 @@
 instance CursorKey EventsCursorKey where
     cursorKey = const "events"
 
-#if __GLASGOW_HASKELL__ >= 706
 -- | A wrapper for API responses which have "next_cursor" field.
 --
 -- The first type parameter of 'WithCursor' specifies the field name of contents.
@@ -67,7 +61,6 @@
 -- Just "hogehoge"
 -- >>> contents res
 -- [1000]
-#endif
 data WithCursor cursorType cursorKey wrapped = WithCursor
     { previousCursor :: Maybe cursorType
     , nextCursor :: Maybe cursorType
diff --git a/Web/Twitter/Conduit/Lens.hs b/Web/Twitter/Conduit/Lens.hs
--- a/Web/Twitter/Conduit/Lens.hs
+++ b/Web/Twitter/Conduit/Lens.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE RankNTypes #-}
 
 module Web.Twitter.Conduit.Lens
@@ -27,9 +26,6 @@
        , TT.ListsCursorKey
        ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Control.Applicative
-#endif
 import Control.Lens
 import Data.Text (Text)
 import Network.HTTP.Types (Status, ResponseHeaders)
diff --git a/Web/Twitter/Conduit/Parameters.hs b/Web/Twitter/Conduit/Parameters.hs
--- a/Web/Twitter/Conduit/Parameters.hs
+++ b/Web/Twitter/Conduit/Parameters.hs
@@ -1,51 +1,7 @@
-{-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
 
 module Web.Twitter.Conduit.Parameters
-       ( Parameters(..)
-       , PV(..)
-       , APIQuery
-       , APIQueryItem
-       , makeSimpleQuery
-
-       , HasSinceIdParam (..)
-       , HasCountParam (..)
-       , HasMaxIdParam (..)
-       , HasPageParam (..)
-       , HasCursorParam (..)
-       , HasTrimUserParam (..)
-       , HasExcludeRepliesParam (..)
-       , HasContributorDetailsParam (..)
-       , HasIncludeEntitiesParam (..)
-       , HasIncludeEmailParam (..)
-       , HasIncludeExtAltTextParam (..)
-       , HasIncludeUserEntitiesParam (..)
-       , HasIncludeRtsParam (..)
-       , HasIncludeMyRetweetParam (..)
-       , HasInReplyToStatusIdParam (..)
-       , HasDisplayCoordinatesParam (..)
-       , HasPossiblySensitiveParam (..)
-       , HasLangParam (..)
-       , HasLanguageParam (..)
-       , HasLocaleParam (..)
-       , HasFilterLevelParam (..)
-       , HasStallWarningsParam (..)
-       , HasRepliesParam (..)
-       , HasUntilParam (..)
-       , HasSkipStatusParam (..)
-       , HasFollowParam (..)
-       , HasMapParam (..)
-       , HasMediaIdsParam (..)
-       , HasDescriptionParam (..)
-       , HasNameParam (..)
-       , HasProfileLinkColorParam (..)
-       , HasLocationParam (..)
-       , HasUrlParam (..)
-       , HasFullTextParam (..)
-       , HasWithParam (..)
-
-       , UserParam(..)
+       ( UserParam(..)
        , UserListParam(..)
        , ListParam(..)
        , MediaData(..)
@@ -54,13 +10,14 @@
        , mkListParam
        ) where
 
-import Control.Lens
 import qualified Data.Text as T
 import Network.HTTP.Client (RequestBody)
-import Web.Twitter.Conduit.Parameters.TH
-import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Request.Internal (APIQuery, PV(..))
 import Web.Twitter.Types
 
+-- $setup
+-- >>> import Web.Twitter.Conduit.Request.Internal
+
 data UserParam = UserIdParam UserId | ScreenNameParam String
                deriving (Show, Eq)
 data UserListParam = UserIdListParam [UserId] | ScreenNameListParam [String]
@@ -70,44 +27,6 @@
 data MediaData = MediaFromFile FilePath
                | MediaRequestBody FilePath RequestBody
 
-defineHasParamClassInteger "count"
-defineHasParamClassInteger "since_id"
-defineHasParamClassInteger "max_id"
-defineHasParamClassInteger "page"
-defineHasParamClassBool "trim_user"
-defineHasParamClassBool "exclude_replies"
-defineHasParamClassBool "contributor_details"
-defineHasParamClassBool "include_entities"
-defineHasParamClassBool "include_email"
-defineHasParamClassBool "include_user_entities"
-defineHasParamClassBool "include_rts"
-defineHasParamClassBool "include_my_retweet"
-defineHasParamClassBool "include_ext_alt_text"
-defineHasParamClassInteger "in_reply_to_status_id"
-defineHasParamClassBool "display_coordinates"
-defineHasParamClassBool "possibly_sensitive"
-defineHasParamClassString "lang"
-defineHasParamClassString "language"
-defineHasParamClassString "locale"
-defineHasParamClassString "filter_level"
-defineHasParamClassBool "stall_warnings"
-defineHasParamClassString "replies"
-defineHasParamClassDay "until"
-defineHasParamClassBool "skip_status"
-defineHasParamClassBool "follow"
-defineHasParamClassBool "map"
-defineHasParamClassIntegerArray "media_ids"
-defineHasParamClassString "description"
-defineHasParamClassString "name"
-defineHasParamClassString "profile_link_color"
-defineHasParamClassString "location"
-defineHasParamClassURI "url"
-defineHasParamClassBool "full_text"
-defineHasParamClassString "with"
-
-class Parameters p => HasCursorParam p a | p -> a where
-    cursor :: Lens' p (Maybe a)
-
 -- | converts 'UserParam' to 'HT.SimpleQuery'.
 --
 -- >>> makeSimpleQuery . mkUserParam $ UserIdParam 123456
@@ -128,7 +47,7 @@
 -- [("screen_name","thimura,NikaidouShinku")]
 mkUserListParam :: UserListParam -> APIQuery
 mkUserListParam (UserIdListParam uids) =  [("user_id", PVIntegerArray uids)]
-mkUserListParam (ScreenNameListParam sns) = [("screen_name", PVStringArray (Prelude.map T.pack sns))]
+mkUserListParam (ScreenNameListParam sns) = [("screen_name", PVStringArray (map T.pack sns))]
 
 -- | converts 'ListParam' to 'HT.SimpleQuery'.
 --
diff --git a/Web/Twitter/Conduit/Parameters/TH.hs b/Web/Twitter/Conduit/Parameters/TH.hs
deleted file mode 100644
--- a/Web/Twitter/Conduit/Parameters/TH.hs
+++ /dev/null
@@ -1,122 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE TemplateHaskell #-}
-
-module Web.Twitter.Conduit.Parameters.TH
-       ( defineHasParamClass
-       , defineHasParamClass'
-       , defineHasParamClassBool
-       , defineHasParamClassDay
-       , defineHasParamClassInteger
-       , defineHasParamClassIntegerArray
-       , defineHasParamClassString
-       , defineHasParamClassStringArray
-       , defineHasParamClassURI
-       , deriveHasParamInstances
-       , wrappedParam
-       ) where
-
-import Web.Twitter.Conduit.Request
-import Language.Haskell.TH
-import Control.Lens
-import qualified Data.ByteString as S
-import Data.Char
-import Data.Text (Text)
-import Data.Time.Calendar (Day)
-import Web.Twitter.Types
-
-snakeToLowerCamel :: String -> String
-snakeToLowerCamel [] = []
-snakeToLowerCamel "_" = []
-snakeToLowerCamel ('_':x:xs) = toUpper x : snakeToLowerCamel xs
-snakeToLowerCamel str = f ++ snakeToLowerCamel next
-  where (f, next) = span (/= '_') str
-
-snakeToUpperCamel :: String -> String
-snakeToUpperCamel = upcase . snakeToLowerCamel
-  where
-    upcase [] = []
-    upcase (x:xs) = toUpper x : xs
-
-paramNameToClassName :: String -> String
-paramNameToClassName paramName = "Has" ++ snakeToUpperCamel paramName ++ "Param"
-
-wrappedParam :: Parameters p
-             => S.ByteString
-             -> (a -> PV)
-             -> (PV -> a)
-             -> Lens' p (Maybe a)
-wrappedParam key wrap unwrap = lens getter setter
-   where
-     getter = preview $ params . to (lookup key) . _Just . to unwrap
-     setter = flip (over params . replace key)
-     replace k (Just v) = ((k, wrap v):) . dropAssoc k
-     replace k Nothing = dropAssoc k
-     dropAssoc k = filter ((/= k) . fst)
-
-defineHasParamClass :: Name -- wrap function
-                    -> Name -- unwrap function
-                    -> TypeQ -- wrapped type
-                    -> String -- ^ parameter name
-                    -> Q [Dec]
-defineHasParamClass wrap unwrap typ paramName =
-    defineHasParamClass' cNameS fNameS wrap unwrap typ paramName 
-  where
-    cNameS = paramNameToClassName paramName
-    fNameS = snakeToLowerCamel paramName
-
-defineHasParamClass' :: String -> String -> Name -> Name -> TypeQ -> String -> Q [Dec]
-defineHasParamClass' cNameS fNameS wrap unwrap typ paramName = do
-    a <- newName "a"
-    cName <- newName cNameS
-    fName <- newName fNameS
-#if MIN_VERSION_template_haskell(2, 10, 0)
-    let cCxt = cxt [conT ''Parameters `appT` varT a]
-#else
-    let cCxt = cxt [classP ''Parameters [varT a]]
-#endif
-    let tySig = sigD fName (appT (appT (conT ''Lens') (varT a)) (appT (conT ''Maybe) typ))
-        valDef = valD (varP fName) (normalB (appE (appE (appE (varE 'wrappedParam) (litE (stringL paramName))) (conE wrap)) (varE unwrap))) []
-    dec <- classD cCxt cName [PlainTV a] [] [tySig, valDef]
-    return [dec]
-
-deriveHasParamInstances :: Name -- ^ target data type name
-                        -> [String] -- ^ parameter name
-                        -> Q [Dec]
-deriveHasParamInstances typName paramNameList =
-    mapM mkInstance cNameStrList
-  where
-    cNameStrList = map paramNameToClassName paramNameList
-    mkInstance cn = instanceD (return []) (appT (conT (mkName cn)) targetType) []
-    targetType = do
-        a <- newName "a"
-        appT (appT (conT (mkName "APIRequest")) (conT typName)) (varT a)
-
-defineHasParamClassInteger :: String -> Q [Dec]
-defineHasParamClassInteger =
-    defineHasParamClass 'PVInteger 'unPVInteger [t|Integer|]
-
-defineHasParamClassBool :: String -> Q [Dec]
-defineHasParamClassBool =
-    defineHasParamClass 'PVBool 'unPVBool [t|Bool|]
-
-defineHasParamClassString :: String -> Q [Dec]
-defineHasParamClassString =
-    defineHasParamClass 'PVString 'unPVString [t|Text|]
-
-defineHasParamClassURI :: String -> Q [Dec]
-defineHasParamClassURI =
-    defineHasParamClass 'PVString 'unPVString [t|URIString|]
-
-defineHasParamClassIntegerArray :: String -> Q [Dec]
-defineHasParamClassIntegerArray =
-    defineHasParamClass 'PVIntegerArray 'unPVIntegerArray [t|[Integer]|]
-
-defineHasParamClassStringArray :: String -> Q [Dec]
-defineHasParamClassStringArray =
-    defineHasParamClass 'PVStringArray 'unPVStringArray [t|[Text]|]
-
-defineHasParamClassDay :: String -> Q [Dec]
-defineHasParamClassDay =
-    defineHasParamClass 'PVDay 'unPVDay [t|Day|]
diff --git a/Web/Twitter/Conduit/ParametersDeprecated.hs b/Web/Twitter/Conduit/ParametersDeprecated.hs
new file mode 100644
--- /dev/null
+++ b/Web/Twitter/Conduit/ParametersDeprecated.hs
@@ -0,0 +1,113 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Web.Twitter.Conduit.ParametersDeprecated where
+
+import Data.Text (Text)
+import Web.Twitter.Types
+import Data.Time.Calendar (Day)
+import Web.Twitter.Conduit.Request.Internal
+import Control.Lens
+
+count :: (Parameters p, HasParam "count" Integer (SupportParameters p)) => Lens' p (Maybe Integer)
+count = rawParam "count"
+
+sinceId :: (Parameters p, HasParam "since_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)
+sinceId = rawParam "since_id"
+
+maxId :: (Parameters p, HasParam "max_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)
+maxId = rawParam "max_id"
+
+page :: (Parameters p, HasParam "page" Integer (SupportParameters p)) => Lens' p (Maybe Integer)
+page = rawParam "page"
+
+trimUser :: (Parameters p, HasParam "trim_user" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+trimUser = rawParam "trim_user"
+
+excludeReplies :: (Parameters p, HasParam "exclude_replies" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+excludeReplies = rawParam "exclude_replies"
+
+contributorDetails :: (Parameters p, HasParam "contributor_details" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+contributorDetails = rawParam "contributor_details"
+
+includeEntities :: (Parameters p, HasParam "include_entities" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeEntities = rawParam "include_entities"
+
+includeEmail :: (Parameters p, HasParam "include_email" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeEmail = rawParam "include_email"
+
+includeUserEntities :: (Parameters p, HasParam "include_user_entities" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeUserEntities = rawParam "include_user_entities"
+
+includeRts :: (Parameters p, HasParam "include_rts" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeRts = rawParam "include_rts"
+
+includeMyRetweet :: (Parameters p, HasParam "include_my_retweet" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeMyRetweet = rawParam "include_my_retweet"
+
+includeExtAltText :: (Parameters p, HasParam "include_ext_alt_text" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+includeExtAltText = rawParam "include_ext_alt_text"
+
+inReplyToStatusId :: (Parameters p, HasParam "in_reply_to_status_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)
+inReplyToStatusId = rawParam "in_reply_to_status_id"
+
+displayCoordinates :: (Parameters p, HasParam "display_coordinates" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+displayCoordinates = rawParam "display_coordinates"
+
+possiblySensitive :: (Parameters p, HasParam "possibly_sensitive" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+possiblySensitive = rawParam "possibly_sensitive"
+
+lang :: (Parameters p, HasParam "lang" Text (SupportParameters p)) => Lens' p (Maybe Text)
+lang = rawParam "lang"
+
+language :: (Parameters p, HasParam "language" Text (SupportParameters p)) => Lens' p (Maybe Text)
+language = rawParam "language"
+
+locale :: (Parameters p, HasParam "locale" Text (SupportParameters p)) => Lens' p (Maybe Text)
+locale = rawParam "locale"
+
+filterLevel :: (Parameters p, HasParam "filter_level" Text (SupportParameters p)) => Lens' p (Maybe Text)
+filterLevel = rawParam "filter_level"
+
+stallWarnings :: (Parameters p, HasParam "stall_warnings" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+stallWarnings = rawParam "stall_warnings"
+
+replies :: (Parameters p, HasParam "replies" Text (SupportParameters p)) => Lens' p (Maybe Text)
+replies = rawParam "replies"
+
+until :: (Parameters p, HasParam "until" Day (SupportParameters p)) => Lens' p (Maybe Day)
+until = rawParam "until"
+
+skipStatus :: (Parameters p, HasParam "skip_status" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+skipStatus = rawParam "skip_status"
+
+follow :: (Parameters p, HasParam "follow" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+follow = rawParam "follow"
+
+map :: (Parameters p, HasParam "map" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+map = rawParam "map"
+
+mediaIds :: (Parameters p, HasParam "media_ids" [Integer] (SupportParameters p)) => Lens' p (Maybe [Integer])
+mediaIds = rawParam "media_ids"
+
+description :: (Parameters p, HasParam "description" Text (SupportParameters p)) => Lens' p (Maybe Text)
+description = rawParam "description"
+
+name :: (Parameters p, HasParam "name" Text (SupportParameters p)) => Lens' p (Maybe Text)
+name = rawParam "name"
+
+profileLinkColor :: (Parameters p, HasParam "profile_link_color" Text (SupportParameters p)) => Lens' p (Maybe Text)
+profileLinkColor = rawParam "profile_link_color"
+
+location :: (Parameters p, HasParam "location" Text (SupportParameters p)) => Lens' p (Maybe Text)
+location = rawParam "location"
+
+url :: (Parameters p, HasParam "url" URIString (SupportParameters p)) => Lens' p (Maybe URIString)
+url = rawParam "url"
+
+fullText :: (Parameters p, HasParam "full_text" Bool (SupportParameters p)) => Lens' p (Maybe Bool)
+fullText = rawParam "full_text"
+
+with :: (Parameters p, HasParam "with" Text (SupportParameters p)) => Lens' p (Maybe Text)
+with = rawParam "with"
diff --git a/Web/Twitter/Conduit/Request.hs b/Web/Twitter/Conduit/Request.hs
--- a/Web/Twitter/Conduit/Request.hs
+++ b/Web/Twitter/Conduit/Request.hs
@@ -1,61 +1,39 @@
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Web.Twitter.Conduit.Request
-       ( Parameters(..)
+       ( HasParam
        , APIRequest(..)
-       , APIQuery
-       , APIQueryItem
-       , PV(..)
-       , makeSimpleQuery
-       , paramValueBS
        ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Control.Applicative
-#endif
-import Control.Lens
 import Data.Aeson
-import Data.ByteString (ByteString)
-import qualified Data.ByteString.Char8 as S8
-import Data.Text (Text)
-import qualified Data.Text.Encoding as T
-import Data.Time.Calendar (Day)
+import GHC.TypeLits (Symbol)
 import Network.HTTP.Client.MultipartFormData
 import qualified Network.HTTP.Types as HT
-
-class Parameters a where
-    params :: Lens' a APIQuery
+import Web.Twitter.Conduit.Request.Internal
 
--- In GHC 7.4.2, the following test fails with Overlapping instances error.
--- It may be caused by #5820 "defining instance in GHCi leads to duplicated instances".
--- So, we bypass below tests when GHC version older than 7.6.
--- see details: https://ghc.haskell.org/trac/ghc/ticket/5820
-#if __GLASGOW_HASKELL__ >= 706
 -- $setup
--- >>> :set -XOverloadedStrings -XRank2Types -XEmptyDataDecls -XFlexibleInstances
+-- >>> :set -XOverloadedStrings -XDataKinds -XTypeOperators
 -- >>> import Control.Lens
--- >>> import Data.Default
 -- >>> import Web.Twitter.Conduit.Parameters
--- >>> data SampleApi
 -- >>> type SampleId = Integer
--- >>> instance HasCountParam (APIRequest SampleApi [SampleId])
--- >>> instance HasMaxIdParam (APIRequest SampleApi [SampleId])
--- >>> let sampleApiRequest :: APIRequest SampleApi [SampleId]; sampleApiRequest = APIRequest "GET" "https://api.twitter.com/sample/api.json" def
+-- >>> type SampleApi = '["count" ':= Integer, "max_id" ':= Integer]
+-- >>> let sampleApiRequest :: APIRequest SampleApi [SampleId]; sampleApiRequest = APIRequest "GET" "https://api.twitter.com/sample/api.json" []
 
 -- | API request. You should use specific builder functions instead of building this directly.
 --
 -- For example, if there were a @SampleApi@ type and a builder function which named @sampleApiRequest@.
--- In addition, @'APIRequest' SampleApi [SampleId]@ is a instance of both of 'HasCountParam' and 'HasMaxIdParam'.
 --
 -- @
--- data 'SampleApi'
--- type 'SampleId' = 'Integer'
--- instance 'HasCountParam' ('APIRequest' 'SampleApi' ['SampleId'])
--- instance 'HasMaxIdParam' ('APIRequest' 'SampleApi' ['SampleId'])
--- 'sampleApiRequest' :: 'APIRequest' 'SampleApi' ['SampleId']
--- 'sampleApiRequest' = 'APIRequest' \"GET\" \"https:\/\/api.twitter.com\/sample\/api.json\" 'def'
+-- type SampleId = 'Integer'
+-- sampleApiRequest :: 'APIRequest' SampleApi [SampleId]
+-- sampleApiRequest = 'APIRequest' \"GET\" \"https:\/\/api.twitter.com\/sample\/api.json\" []
+-- type SampleApi = '[ "count" ':= Integer
+--                   , "max_id" ':= Integer
+--                   ]
+--
 -- @
 --
 -- We can obtain request params from @'APIRequest' SampleApi [SampleId]@ :
@@ -63,14 +41,15 @@
 -- >>> sampleApiRequest ^. params
 -- []
 --
--- And update request parameters.
+-- The second type parameter of the APIRequest represents the allowed parameters for the APIRequest.
+-- For example, @sampleApiRequest@ has 2 @Integer@ parameters, that is "count" and "max_id".
+-- You can update those parameters by label lenses (@#count@ and @#max_id@ respectively)
 --
--- >>> (sampleApiRequest & count ?~ 100 & maxId ?~ 1234567890) ^. params
+-- >>> (sampleApiRequest & #count ?~ 100 & #max_id ?~ 1234567890) ^. params
 -- [("max_id",PVInteger {unPVInteger = 1234567890}),("count",PVInteger {unPVInteger = 100})]
--- >>> (sampleApiRequest & count ?~ 100 & maxId ?~ 1234567890 & count .~ Nothing) ^. params
+-- >>> (sampleApiRequest & #count ?~ 100 & #max_id ?~ 1234567890 & #count .~ Nothing) ^. params
 -- [("max_id",PVInteger {unPVInteger = 1234567890})]
-#endif
-data APIRequest apiName responseType
+data APIRequest (supports :: [Param Symbol *]) responseType
     = APIRequest
       { _method :: HT.Method
       , _url :: String
@@ -88,7 +67,9 @@
       , _params :: APIQuery
       , _body :: Value
       }
-instance Parameters (APIRequest apiName responseType) where
+instance Parameters (APIRequest supports responseType) where
+    type SupportParameters (APIRequest supports responseType) = supports
+
     params f (APIRequest m u pa) = APIRequest m u <$> f pa
     params f (APIRequestMultipart m u pa prt) =
         (\p -> APIRequestMultipart m u p prt) <$> f pa
@@ -97,27 +78,3 @@
     show (APIRequest m u p) = "APIRequest " ++ show m ++ " " ++ show u ++ " " ++ show (makeSimpleQuery p)
     show (APIRequestMultipart m u p _) = "APIRequestMultipart " ++ show m ++ " " ++ show u ++ " " ++ show (makeSimpleQuery p)
     show (APIRequestJSON m u p _) = "APIRequestJSON " ++ show m ++ " " ++ show u ++ " " ++ show (makeSimpleQuery p)
-
-type APIQuery = [APIQueryItem]
-type APIQueryItem = (ByteString, PV)
-
-data PV
-    = PVInteger { unPVInteger :: Integer }
-    | PVBool { unPVBool :: Bool }
-    | PVString { unPVString :: Text }
-    | PVIntegerArray { unPVIntegerArray :: [Integer] }
-    | PVStringArray { unPVStringArray :: [Text] }
-    | PVDay { unPVDay :: Day }
-    deriving (Show, Eq)
-
-makeSimpleQuery :: APIQuery -> HT.SimpleQuery
-makeSimpleQuery = traversed . _2 %~ paramValueBS
-
-paramValueBS :: PV -> ByteString
-paramValueBS (PVInteger i) = S8.pack . show $ i
-paramValueBS (PVBool True) = "true"
-paramValueBS (PVBool False) = "false"
-paramValueBS (PVString txt) = T.encodeUtf8 txt
-paramValueBS (PVIntegerArray iarr) = S8.intercalate "," $ map (S8.pack . show) iarr
-paramValueBS (PVStringArray iarr) = S8.intercalate "," $ map T.encodeUtf8 iarr
-paramValueBS (PVDay day) = S8.pack . show $ day
diff --git a/Web/Twitter/Conduit/Request/Internal.hs b/Web/Twitter/Conduit/Request/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Web/Twitter/Conduit/Request/Internal.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Web.Twitter.Conduit.Request.Internal where
+
+import Control.Lens
+import Data.ByteString (ByteString)
+import qualified Data.ByteString.Char8 as S8
+import Data.Proxy
+import Data.Text (Text)
+import qualified Data.Text.Encoding as T
+import Data.Time.Calendar (Day)
+import GHC.OverloadedLabels
+import GHC.TypeLits
+import qualified Network.HTTP.Types as HT
+
+data Param label t = label := t
+
+type EmptyParams = ('[] :: [Param Symbol *])
+
+type HasParam (label :: Symbol) (paramType :: *) (params :: [Param Symbol *]) = ParamType label params ~ paramType
+type family ParamType (label :: Symbol) (params :: [Param Symbol *]) :: * where
+    ParamType label ((label ':= paramType) ': ks) = paramType
+    ParamType label ((label' ':= paramType') ': ks) = ParamType label ks
+
+type APIQuery = [APIQueryItem]
+type APIQueryItem = (ByteString, PV)
+
+data PV
+    = PVInteger { unPVInteger :: Integer }
+    | PVBool { unPVBool :: Bool }
+    | PVString { unPVString :: Text }
+    | PVIntegerArray { unPVIntegerArray :: [Integer] }
+    | PVStringArray { unPVStringArray :: [Text] }
+    | PVDay { unPVDay :: Day }
+    deriving (Show, Eq)
+
+class Parameters req where
+    type SupportParameters req :: [Param Symbol *]
+    params :: Lens' req APIQuery
+
+class ParameterValue a where
+    wrap :: a -> PV
+    unwrap :: PV -> a
+instance ParameterValue Integer where
+    wrap = PVInteger
+    unwrap = unPVInteger
+instance ParameterValue Bool where
+    wrap = PVBool
+    unwrap = unPVBool
+instance ParameterValue Text where
+    wrap = PVString
+    unwrap = unPVString
+instance ParameterValue [Integer] where
+    wrap = PVIntegerArray
+    unwrap = unPVIntegerArray
+instance ParameterValue [Text] where
+    wrap = PVStringArray
+    unwrap = unPVStringArray
+instance ParameterValue Day where
+    wrap = PVDay
+    unwrap = unPVDay
+
+makeSimpleQuery :: APIQuery -> HT.SimpleQuery
+makeSimpleQuery = traversed . _2 %~ paramValueBS
+
+paramValueBS :: PV -> ByteString
+paramValueBS (PVInteger i) = S8.pack . show $ i
+paramValueBS (PVBool True) = "true"
+paramValueBS (PVBool False) = "false"
+paramValueBS (PVString txt) = T.encodeUtf8 txt
+paramValueBS (PVIntegerArray iarr) = S8.intercalate "," $ map (S8.pack . show) iarr
+paramValueBS (PVStringArray iarr) = S8.intercalate "," $ map T.encodeUtf8 iarr
+paramValueBS (PVDay day) = S8.pack . show $ day
+
+rawParam ::
+       (Parameters p, ParameterValue a)
+    => ByteString -- ^ key
+    -> Lens' p (Maybe a)
+rawParam key = lens getter setter
+   where
+     getter = preview $ params . to (lookup key) . _Just . to unwrap
+     setter = flip (over params . replace key)
+     replace k (Just v) = ((k, wrap v):) . dropAssoc k
+     replace k Nothing = dropAssoc k
+     dropAssoc k = filter ((/= k) . fst)
+
+instance ( Parameters req
+         , ParameterValue a
+         , KnownSymbol label
+         , HasParam label a (SupportParameters req)
+         , Functor f
+         , lens ~ ((Maybe a -> f (Maybe a)) -> req -> f req)) =>
+         IsLabel label lens where
+#if MIN_VERSION_base(4, 10, 0)
+    fromLabel = rawParam key
+#else
+    fromLabel _ = rawParam key
+#endif
+      where
+        key = S8.pack (symbolVal (Proxy :: Proxy label))
diff --git a/Web/Twitter/Conduit/Response.hs b/Web/Twitter/Conduit/Response.hs
--- a/Web/Twitter/Conduit/Response.hs
+++ b/Web/Twitter/Conduit/Response.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveFunctor #-}
@@ -11,11 +10,6 @@
        , TwitterErrorMessage (..)
        ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Control.Applicative
-import Data.Foldable (Foldable)
-import Data.Traversable (Traversable)
-#endif
 import Control.Exception
 import Data.Aeson
 import Data.Data
diff --git a/Web/Twitter/Conduit/Status.hs b/Web/Twitter/Conduit/Status.hs
--- a/Web/Twitter/Conduit/Status.hs
+++ b/Web/Twitter/Conduit/Status.hs
@@ -1,8 +1,6 @@
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE TypeOperators #-}
 
 module Web.Twitter.Conduit.Status
        (
@@ -38,8 +36,8 @@
 import Prelude hiding ( lookup )
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Request.Internal
 import Web.Twitter.Conduit.Parameters
-import Web.Twitter.Conduit.Parameters.TH
 import Web.Twitter.Types
 
 import qualified Data.Text as T
@@ -47,12 +45,11 @@
 import Data.Default
 
 -- $setup
--- >>> :set -XOverloadedStrings
+-- >>> :set -XOverloadedStrings -XOverloadedLabels
 -- >>> import Control.Lens
 
 -- * Timelines
 
-data StatusesMentionsTimeline
 -- | Returns query data asks the most recent mentions for the authenticating user.
 --
 -- You can perform a query using 'call':
@@ -65,16 +62,16 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/mentions_timeline.json" []
 mentionsTimeline :: APIRequest StatusesMentionsTimeline [Status]
 mentionsTimeline = APIRequest "GET" (endpoint ++ "statuses/mentions_timeline.json") def
-deriveHasParamInstances ''StatusesMentionsTimeline
-    [ "count"
-    , "since_id"
-    , "max_id"
-    , "trim_user"
-    , "contributor_details"
-    , "include_entities"
+type StatusesMentionsTimeline = '[
+      "count" ':= Integer
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "trim_user" ':= Bool
+    , "contributor_details" ':= Bool
+    , "include_entities" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesUserTimeline
 -- | Returns query data asks a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id parameters.
 --
 -- You can perform a search query using 'call':
@@ -85,21 +82,21 @@
 --
 -- >>> userTimeline (ScreenNameParam "thimura")
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/user_timeline.json" [("screen_name","thimura")]
--- >>> userTimeline (ScreenNameParam "thimura") & includeRts ?~ True & count ?~ 200
+-- >>> userTimeline (ScreenNameParam "thimura") & #include_rts ?~ True & #count ?~ 200
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/user_timeline.json" [("count","200"),("include_rts","true"),("screen_name","thimura")]
 userTimeline :: UserParam -> APIRequest StatusesUserTimeline [Status]
 userTimeline q = APIRequest "GET" (endpoint ++ "statuses/user_timeline.json") (mkUserParam q)
-deriveHasParamInstances ''StatusesUserTimeline
-    [ "count"
-    , "since_id"
-    , "max_id"
-    , "trim_user"
-    , "exclude_replies"
-    , "contributor_details"
-    , "include_rts"
+type StatusesUserTimeline = '[
+      "count" ':= Integer
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "trim_user" ':= Bool
+    , "exclude_replies" ':= Bool
+    , "contributor_details" ':= Bool
+    , "include_rts" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesHomeTimeline
 -- | Returns query data asks a collection of the most recentTweets and retweets posted by the authenticating user and the users they follow.
 --
 -- You can perform a search query using 'call':
@@ -110,21 +107,21 @@
 --
 -- >>> homeTimeline
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/home_timeline.json" []
--- >>> homeTimeline & count ?~ 200
+-- >>> homeTimeline & #count ?~ 200
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/home_timeline.json" [("count","200")]
 homeTimeline :: APIRequest StatusesHomeTimeline [Status]
 homeTimeline = APIRequest "GET" (endpoint ++ "statuses/home_timeline.json") def
-deriveHasParamInstances ''StatusesHomeTimeline
-    [ "count"
-    , "since_id"
-    , "max_id"
-    , "trim_user"
-    , "exclude_replies"
-    , "contributor_details"
-    , "include_entities"
+type StatusesHomeTimeline = '[
+      "count" ':= Integer
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "trim_user" ':= Bool
+    , "exclude_replies" ':= Bool
+    , "contributor_details" ':= Bool
+    , "include_entities" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesRetweetsOfMe
 -- | Returns query data asks the most recent tweets authored by the authenticating user that have been retweeted by others.
 --
 -- You can perform a search query using 'call':
@@ -135,22 +132,22 @@
 --
 -- >>> retweetsOfMe
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets_of_me.json" []
--- >>> retweetsOfMe & count ?~ 100
+-- >>> retweetsOfMe & #count ?~ 100
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets_of_me.json" [("count","100")]
 retweetsOfMe :: APIRequest StatusesRetweetsOfMe [Status]
 retweetsOfMe = APIRequest "GET" (endpoint ++ "statuses/retweets_of_me.json") def
-deriveHasParamInstances ''StatusesRetweetsOfMe
-    [ "count"
-    , "since_id"
-    , "max_id"
-    , "trim_user"
-    , "include_entities"
-    , "include_user_entities"
+type StatusesRetweetsOfMe = '[
+      "count" ':= Integer
+    , "since_id" ':= Integer
+    , "max_id" ':= Integer
+    , "trim_user" ':= Bool
+    , "include_entities" ':= Bool
+    , "include_user_entities" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
 -- * Tweets
 
-data StatusesRetweetsId
 -- | Returns query data that asks for the most recent retweets of the specified tweet
 --
 -- You can perform a search query using 'call':
@@ -161,17 +158,16 @@
 --
 -- >>> retweetsId 1234567890
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets/1234567890.json" []
--- >>> retweetsId 1234567890 & count ?~ 100
+-- >>> retweetsId 1234567890 & #count ?~ 100
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets/1234567890.json" [("count","100")]
 retweetsId :: StatusId -> APIRequest StatusesRetweetsId [RetweetedStatus]
 retweetsId status_id = APIRequest "GET" uri def
   where uri = endpoint ++ "statuses/retweets/" ++ show status_id ++ ".json"
-deriveHasParamInstances ''StatusesRetweetsId
-    [ "count"
-    , "trim_user"
+type StatusesRetweetsId = '[
+      "count" ':= Integer
+    , "trim_user" ':= Bool
     ]
 
-data StatusesShowId
 -- | Returns query data asks a single Tweet, specified by the id parameter.
 --
 -- You can perform a search query using 'call':
@@ -182,19 +178,19 @@
 --
 -- >>> showId 1234567890
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/show/1234567890.json" []
--- >>> showId 1234567890 & includeMyRetweet ?~ True
+-- >>> showId 1234567890 & #include_my_retweet ?~ True
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/show/1234567890.json" [("include_my_retweet","true")]
 showId :: StatusId -> APIRequest StatusesShowId Status
 showId status_id = APIRequest "GET" uri def
   where uri = endpoint ++ "statuses/show/" ++ show status_id ++ ".json"
-deriveHasParamInstances ''StatusesShowId
-    [ "trim_user"
-    , "include_my_retweet"
-    , "include_entities"
-    , "include_ext_alt_text"
+type StatusesShowId = '[
+      "trim_user" ':= Bool
+    , "include_my_retweet" ':= Bool
+    , "include_entities" ':= Bool
+    , "include_ext_alt_text" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesDestroyId
 -- | Returns post data which destroys the status specified by the require ID parameter.
 --
 -- You can perform a search query using 'call':
@@ -208,11 +204,11 @@
 destroyId :: StatusId -> APIRequest StatusesDestroyId Status
 destroyId status_id = APIRequest "POST" uri def
   where uri = endpoint ++ "statuses/destroy/" ++ show status_id ++ ".json"
-deriveHasParamInstances ''StatusesDestroyId
-    [ "trim_user"
+type StatusesDestroyId = '[
+      "trim_user" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesUpdate
 -- | Returns post data which updates the authenticating user's current status.
 -- To upload an image to accompany the tweet, use 'updateWithMedia'.
 --
@@ -224,21 +220,21 @@
 --
 -- >>> update "Hello World"
 -- APIRequest "POST" "https://api.twitter.com/1.1/statuses/update.json" [("status","Hello World")]
--- >>> update "Hello World" & inReplyToStatusId ?~ 1234567890
+-- >>> update "Hello World" & #in_reply_to_status_id ?~ 1234567890
 -- APIRequest "POST" "https://api.twitter.com/1.1/statuses/update.json" [("in_reply_to_status_id","1234567890"),("status","Hello World")]
 update :: T.Text -> APIRequest StatusesUpdate Status
 update status = APIRequest "POST" uri [("status", PVString status)]
   where uri = endpoint ++ "statuses/update.json"
-deriveHasParamInstances ''StatusesUpdate
-    [ "in_reply_to_status_id"
+type StatusesUpdate = '[
+      "in_reply_to_status_id" ':= Integer
     -- , "lat_long"
     -- , "place_id"
-    , "display_coordinates"
-    , "trim_user"
-    , "media_ids"
+    , "display_coordinates" ':= Bool
+    , "trim_user" ':= Bool
+    , "media_ids" ':= [Integer]
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesRetweetId
 -- | Returns post data which retweets a tweet, specified by ID.
 --
 -- You can perform a search query using 'call':
@@ -252,11 +248,10 @@
 retweetId :: StatusId -> APIRequest StatusesRetweetId RetweetedStatus
 retweetId status_id = APIRequest "POST" uri def
   where uri = endpoint ++ "statuses/retweet/" ++ show status_id ++ ".json"
-deriveHasParamInstances ''StatusesRetweetId
-    [ "trim_user"
+type StatusesRetweetId = '[
+      "trim_user" ':= Bool
     ]
 
-data StatusesUpdateWithMedia
 -- | Returns post data which updates the authenticating user's current status and attaches media for upload.
 --
 -- You can perform a search query using 'call':
@@ -276,15 +271,15 @@
     uri = endpoint ++ "statuses/update_with_media.json"
     mediaBody (MediaFromFile fp) = partFileSource "media[]" fp
     mediaBody (MediaRequestBody filename filebody) = partFileRequestBody "media[]" filename filebody
-deriveHasParamInstances ''StatusesUpdateWithMedia
-    [ "possibly_sensitive"
-    , "in_reply_to_status_id"
+type StatusesUpdateWithMedia = '[
+      "possibly_sensitive" ':= Bool
+    , "in_reply_to_status_id" ':= Integer
     -- , "lat_long"
     -- , "place_id"
-    , "display_coordinates"
+    , "display_coordinates" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
 
-data StatusesLookup
 -- | Returns fully-hydrated tweet objects for up to 100 tweets per request, as specified by comma-separated values passed to the id parameter.
 --
 -- You can perform a request using 'call':
@@ -297,12 +292,13 @@
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/lookup.json" [("id","10")]
 -- >>> lookup [10, 432656548536401920]
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/lookup.json" [("id","10,432656548536401920")]
--- >>> lookup [10, 432656548536401920] & includeEntities ?~ True
+-- >>> lookup [10, 432656548536401920] & #include_entities ?~ True
 -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/lookup.json" [("include_entities","true"),("id","10,432656548536401920")]
 lookup :: [StatusId] -> APIRequest StatusesLookup [Status]
 lookup ids = APIRequest "GET" (endpoint ++ "statuses/lookup.json") [("id", PVIntegerArray ids)]
-deriveHasParamInstances ''StatusesLookup
-    [ "include_entities"
-    , "trim_user"
-    , "map"
+type StatusesLookup = '[
+      "include_entities" ':= Bool
+    , "trim_user" ':= Bool
+    , "map" ':= Bool
+    , "tweet_mode" ':= T.Text
     ]
diff --git a/Web/Twitter/Conduit/Stream.hs b/Web/Twitter/Conduit/Stream.hs
--- a/Web/Twitter/Conduit/Stream.hs
+++ b/Web/Twitter/Conduit/Stream.hs
@@ -1,9 +1,8 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 module Web.Twitter.Conduit.Stream
        (
@@ -27,9 +26,8 @@
 import Web.Twitter.Conduit.Types
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Types
-import Web.Twitter.Conduit.Parameters
-import Web.Twitter.Conduit.Parameters.TH
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Request.Internal
 import Web.Twitter.Conduit.Response
 
 import Control.Monad.Catch
@@ -39,77 +37,44 @@
 import qualified Data.ByteString.Char8 as S8
 import Data.Char
 import qualified Data.Conduit as C
-import qualified Data.Conduit.Internal as CI
 import qualified Data.Conduit.List as CL
 import qualified Data.List as L
 import qualified Data.Text as T
 import qualified Network.HTTP.Conduit as HTTP
 
-#if MIN_VERSION_conduit(1,3,0)
-#else
-#if MIN_VERSION_conduit(1,0,16)
-($=+) :: MonadIO m
-      => CI.ResumableSource m a
-      -> CI.Conduit a m o
-      -> m (CI.ResumableSource m o)
-($=+) = (return .) . (C.$=+)
-#else
-rsrc $=+ cndt = do
-    (src, finalizer) <- C.unwrapResumable rsrc
-    return $ CI.ResumableSource (src C.$= cndt) finalizer
-#endif
-#endif
-
 stream ::
           ( MonadResource m
           , FromJSON responseType
-#if MIN_VERSION_conduit(1,3,0)
           , MonadThrow m
-#endif
           )
        => TWInfo
        -> HTTP.Manager
        -> APIRequest apiName responseType
-#if MIN_VERSION_http_conduit(2,3,0)
         -> m (C.ConduitM () responseType m ())
-#else
-       -> m (C.ResumableSource m responseType)
-#endif
 stream = stream'
 
 stream' ::
            ( MonadResource m
            , FromJSON value
-#if MIN_VERSION_conduit(1,3,0)
            , MonadThrow m
-#endif
            )
         => TWInfo
         -> HTTP.Manager
         -> APIRequest apiName responseType
-#if MIN_VERSION_http_conduit(2,3,0)
         -> m (C.ConduitM () value m ())
-#else
-        -> m (C.ResumableSource m value)
-#endif
 stream' info mgr req = do
     rsrc <- getResponse info mgr =<< liftIO (makeRequest req)
-#if MIN_VERSION_http_conduit(2,3,0)
     return $ responseBody rsrc C..| CL.sequence sinkFromJSONIgnoreSpaces
-#else
-    responseBody rsrc $=+ CL.sequence sinkFromJSONIgnoreSpaces
-#endif
   where
-    sinkFromJSONIgnoreSpaces = CL.filter (not . S8.all isSpace) C.=$ sinkFromJSON
+    sinkFromJSONIgnoreSpaces = CL.filter (not . S8.all isSpace) C..| sinkFromJSON
 
-data Userstream
 userstream :: APIRequest Userstream StreamingAPI
 userstream = APIRequest "GET" "https://userstream.twitter.com/1.1/user.json" []
-deriveHasParamInstances ''Userstream
-    [ "language"
-    , "filter_level"
-    , "stall_warnings"
-    , "replies"
+type Userstream = '[
+      "language" ':= T.Text
+    , "filter_level" ':= T.Text
+    , "stall_warnings" ':= Bool
+    , "replies" ':= T.Text
     ]
 
 -- https://dev.twitter.com/streaming/overview/request-parameters
@@ -134,8 +99,6 @@
 statusesFilterEndpoint :: String
 statusesFilterEndpoint = "https://stream.twitter.com/1.1/statuses/filter.json"
 
-data StatusesFilter
-
 -- | Returns statuses/filter.json API query data.
 --
 -- >>> statusesFilterByFollow [1,2,3]
@@ -150,9 +113,8 @@
 statusesFilterByTrack :: T.Text -- ^ keyword
                       -> APIRequest StatusesFilter StreamingAPI
 statusesFilterByTrack keyword = statusesFilter [Track [keyword]]
-
-deriveHasParamInstances ''StatusesFilter
-    [ "language"
-    , "filter_level"
-    , "stall_warnings"
+type StatusesFilter = '[
+      "language" ':= T.Text
+    , "filter_level" ':= T.Text
+    , "stall_warnings" ':= Bool
     ]
diff --git a/sample/fav.hs b/sample/fav.hs
--- a/sample/fav.hs
+++ b/sample/fav.hs
@@ -15,7 +15,7 @@
     mgr <- newManager tlsManagerSettings
     let sId = read statusIdStr
 
-    targetStatus <- call twInfo mgr $ showId sId
+    targetStatus <- call twInfo mgr $ statusesShowId sId
     putStrLn $ "Favorite Tweet: " ++ targetStatus ^. to show
     res <- call twInfo mgr $ favoritesCreate sId
     print res
diff --git a/sample/oauth_callback.hs b/sample/oauth_callback.hs
--- a/sample/oauth_callback.hs
+++ b/sample/oauth_callback.hs
@@ -9,14 +9,13 @@
 
 import Web.Scotty
 import qualified Network.HTTP.Types as HT
-import Web.Twitter.Conduit hiding (lookup,url)
+import Web.Twitter.Conduit
 import qualified Web.Authenticate.OAuth as OA
 import qualified Data.Text.Lazy as LT
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as S8
 import qualified Data.Map as M
 import Data.Maybe
-import Data.Monoid
 import Data.IORef
 import Control.Monad.IO.Class
 import System.Environment
diff --git a/sample/oauth_pin.hs b/sample/oauth_pin.hs
--- a/sample/oauth_pin.hs
+++ b/sample/oauth_pin.hs
@@ -8,11 +8,10 @@
 
 module Main where
 
-import Web.Twitter.Conduit hiding (lookup,url)
+import Web.Twitter.Conduit hiding (lookup)
 import Web.Authenticate.OAuth as OA
 import qualified Data.ByteString.Char8 as S8
 import Data.Maybe
-import Data.Monoid
 import System.Environment
 import System.IO (hFlush, stdout)
 
diff --git a/sample/oslist.hs b/sample/oslist.hs
--- a/sample/oslist.hs
+++ b/sample/oslist.hs
@@ -1,10 +1,10 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Main where
 
-import Web.Twitter.Conduit hiding (map)
+import Web.Twitter.Conduit
 import Common
 
-import qualified Data.Conduit as C
+import Data.Conduit
 import qualified Data.Conduit.List as CL
 import qualified Data.Map as M
 import System.Environment
@@ -16,8 +16,8 @@
     mgr <- newManager tlsManagerSettings
     let sn = ScreenNameParam screenName
 
-    folids <- sourceWithCursor twInfo mgr (followersIds sn) C.$$ CL.consume
-    friids <- sourceWithCursor twInfo mgr (friendsIds sn) C.$$ CL.consume
+    folids <- runConduit $ sourceWithCursor twInfo mgr (followersIds sn) .| CL.consume
+    friids <- runConduit $ sourceWithCursor twInfo mgr (friendsIds sn) .| CL.consume
 
     let folmap = M.fromList $ map (flip (,) True) folids
         os = filter (\uid -> M.notMember uid folmap) friids
diff --git a/sample/post.hs b/sample/post.hs
--- a/sample/post.hs
+++ b/sample/post.hs
@@ -1,11 +1,9 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Main where
 
-import Web.Twitter.Conduit hiding (map)
+import Web.Twitter.Conduit
 import Common
 
-import Control.Applicative
-import Data.Monoid
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
 import System.Environment
@@ -16,5 +14,5 @@
     T.putStrLn $ "Post message: " <> status
     twInfo <- getTWInfoFromEnv
     mgr <- newManager tlsManagerSettings
-    res <- call twInfo mgr $ update status
+    res <- call twInfo mgr $ statusesUpdate status
     print res
diff --git a/sample/postWithMedia.hs b/sample/postWithMedia.hs
--- a/sample/postWithMedia.hs
+++ b/sample/postWithMedia.hs
@@ -13,5 +13,5 @@
     putStrLn $ "Post message: " ++ status
     twInfo <- getTWInfoFromEnv
     mgr <- newManager tlsManagerSettings
-    res <- call twInfo mgr $ updateWithMedia (T.pack status) (MediaFromFile filepath)
+    res <- call twInfo mgr $ statusesUpdateWithMedia (T.pack status) (MediaFromFile filepath)
     print res
diff --git a/sample/postWithMultipleMedia.hs b/sample/postWithMultipleMedia.hs
--- a/sample/postWithMultipleMedia.hs
+++ b/sample/postWithMultipleMedia.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedLabels #-}
+
 module Main where
 
 import Web.Twitter.Conduit
-import qualified Web.Twitter.Conduit.Parameters as P
 import Web.Twitter.Types.Lens
 import Common
 
@@ -27,5 +28,5 @@
         putStrLn $ "Upload completed: media_id: " ++ ret ^. uploadedMediaId . to show ++ ", filepath: " ++ filepath
         return ret
     putStrLn $ "Post message: " ++ status
-    res <- call twInfo mgr $ update (T.pack status) & P.mediaIds ?~ (uploadedMediaList ^.. traversed .  uploadedMediaId)
+    res <- call twInfo mgr $ statusesUpdate (T.pack status) & #media_ids ?~ (uploadedMediaList ^.. traversed .  uploadedMediaId)
     print res
diff --git a/sample/searchSource.hs b/sample/searchSource.hs
--- a/sample/searchSource.hs
+++ b/sample/searchSource.hs
@@ -22,4 +22,4 @@
     let metadata = res ^. searchResultSearchMetadata
     putStrLn $ "search completed in: " ++ metadata ^. searchMetadataCompletedIn . to show
     putStrLn $ "search result max id: " ++ metadata ^. searchMetadataMaxId . to show
-    res ^. searchResultStatuses $$ CL.isolate (read num) =$ CL.mapM_ print
+    runConduit $ res ^. searchResultStatuses .| CL.isolate (read num) .| CL.mapM_ print
diff --git a/sample/simple.hs b/sample/simple.hs
--- a/sample/simple.hs
+++ b/sample/simple.hs
@@ -1,15 +1,15 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedLabels #-}
 {-# LANGUAGE FlexibleContexts #-}
 
 module Main where
 
 import Web.Twitter.Conduit
-import qualified Web.Twitter.Conduit.Parameters as P
 import Web.Twitter.Types.Lens
 
 import Control.Lens
 import qualified Data.ByteString.Char8 as B8
-import qualified Data.Conduit as C
+import Data.Conduit
 import qualified Data.Conduit.List as CL
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
@@ -49,12 +49,15 @@
     mgr <- newManager tlsManagerSettings
     twInfo <- getTWInfo mgr
     putStrLn $ "# your home timeline (up to 800 tweets):"
-    sourceWithMaxId twInfo mgr (homeTimeline & P.count ?~ 200)
-        C.$= CL.isolate 800
-        C.$$ CL.mapM_ $ \status -> do
-            T.putStrLn $ T.concat [ T.pack . show $ status ^. statusId
-                                  , ": "
-                                  , status ^. statusUser . userScreenName
-                                  , ": "
-                                  , status ^. statusText
-                                  ]
+    runConduit $ sourceWithMaxId twInfo mgr (statusesHomeTimeline & #count ?~ 200)
+        .| CL.isolate 800
+        .| CL.mapM_
+            (\status -> do
+                 T.putStrLn $
+                     T.concat
+                         [ T.pack . show $ status ^. statusId
+                         , ": "
+                         , status ^. statusUser . userScreenName
+                         , ": "
+                         , status ^. statusText
+                         ])
diff --git a/sample/twitter-conduit-sample.cabal b/sample/twitter-conduit-sample.cabal
--- a/sample/twitter-conduit-sample.cabal
+++ b/sample/twitter-conduit-sample.cabal
@@ -28,7 +28,7 @@
     , containers
     , directory
     , filepath
-    , http-conduit
+    , http-conduit >= 2.3.0
     , lens
     , process
     , resourcet
diff --git a/sample/userstream.hs b/sample/userstream.hs
--- a/sample/userstream.hs
+++ b/sample/userstream.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards #-}
 
@@ -6,13 +5,11 @@
 import Web.Twitter.Types.Lens
 import Common
 
-import Control.Applicative
 import Control.Lens
 import Control.Monad
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Resource
 import Data.Conduit
-import qualified Data.Conduit as C
 import qualified Data.Conduit.Binary as CB
 import qualified Data.Conduit.List as CL
 import qualified Data.Text as T
@@ -39,11 +36,7 @@
     mgr <- newManager tlsManagerSettings
     runResourceT $ do
         src <- stream twInfo mgr userstream
-#if MIN_VERSION_http_conduit(2,3,0)
-        C.runConduit $ src C..| CL.mapM_ (liftIO . printTL)
-#else
-        src C.$$+- CL.mapM_ (liftIO . printTL)
-#endif
+        runConduit $ src .| CL.mapM_ (liftIO . printTL)
 
 showStatus :: AsStatus s => s -> T.Text
 showStatus s = T.concat [ s ^. user . userScreenName
@@ -85,13 +78,9 @@
     let fname = ipath </> sn ++ "__" ++ takeFileName url
     exists <- doesFileExist fname
     unless exists $ do
-        req <- parseUrl url
+        req <- parseRequest url
         mgr <- newManager tlsManagerSettings
         runResourceT $ do
             body <- http req mgr
-#if MIN_VERSION_http_conduit(2,3,0)
-            C.runConduit $ HTTP.responseBody body C..| CB.sinkFile fname
-#else
-            HTTP.responseBody body $$+- CB.sinkFile fname
-#endif
+            runConduit $ HTTP.responseBody body .| CB.sinkFile fname
     return fname
diff --git a/tests/StatusSpec.hs b/tests/StatusSpec.hs
--- a/tests/StatusSpec.hs
+++ b/tests/StatusSpec.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedLabels #-}
 {-# LANGUAGE CPP #-}
 
 module StatusSpec where
@@ -56,11 +57,11 @@
         it "returns the recent tweets which include RTs when specified include_rts option" $ do
             res <- call twInfo mgr
                    $ userTimeline (Param.ScreenNameParam "thimura")
-                   & Param.count ?~ 100 & Param.includeRts ?~ True
+                   & #count ?~ 100 & #include_rts ?~ True
             res `shouldSatisfy` (anyOf (folded . statusRetweetedStatus . _Just . statusUser . userScreenName) (/= "thimura"))
         it "iterate with sourceWithMaxId" $ do
             let src = sourceWithMaxId twInfo mgr $
-                      userTimeline (Param.ScreenNameParam "thimura") & Param.count ?~ 200
+                      userTimeline (Param.ScreenNameParam "thimura") & #count ?~ 200
             tl <- src $$ CL.isolate 600 =$ CL.consume
             length tl `shouldSatisfy` (== 600)
 
diff --git a/tests/TestUtils.hs b/tests/TestUtils.hs
--- a/tests/TestUtils.hs
+++ b/tests/TestUtils.hs
@@ -1,20 +1,10 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
 
 module TestUtils (getTWInfo) where
 
-import Web.Twitter.Conduit
-
-import qualified Network.URI as URI
-import Network.HTTP.Conduit
-import qualified Data.Map as M
 import qualified Data.ByteString.Char8 as S8
-import qualified Data.CaseInsensitive as CI
-import Control.Applicative
 import System.Environment
-import Control.Lens
+import Web.Twitter.Conduit
 
 getOAuthTokens :: IO (OAuth, Credential)
 getOAuthTokens = do
@@ -34,21 +24,7 @@
   where
     getEnv' = (S8.pack <$>) . getEnv
 
-getProxyEnv :: IO (Maybe Proxy)
-getProxyEnv = do
-    env <- M.fromList . over (mapped . _1) CI.mk <$> getEnvironment
-    let u = M.lookup "https_proxy" env <|>
-            M.lookup "http_proxy" env <|>
-            M.lookup "proxy" env >>= URI.parseURI >>= URI.uriAuthority
-    return $ Proxy <$> (S8.pack . URI.uriRegName <$> u) <*> (parsePort . URI.uriPort <$> u)
-  where
-    parsePort :: String -> Int
-    parsePort []       = 8080
-    parsePort (':':xs) = read xs
-    parsePort xs       = error $ "port number parse failed " ++ xs
-
 getTWInfo :: IO TWInfo
 getTWInfo = do
-    pr <- getProxyEnv
     (oa, cred) <- getOAuthTokens
-    return $ (setCredential oa cred def) { twProxy = pr }
+    return $ setCredential oa cred def
diff --git a/twitter-conduit.cabal b/twitter-conduit.cabal
--- a/twitter-conduit.cabal
+++ b/twitter-conduit.cabal
@@ -1,5 +1,5 @@
 name:              twitter-conduit
-version:           0.4.0
+version:           0.5.0
 license:           BSD3
 license-file:      LICENSE
 author:            HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA
@@ -39,10 +39,6 @@
   type: git
   location: git://github.com/himura/twitter-conduit.git
 
-flag network-uri
-  description: Get Network.URI from the network-uri package
-  default: True
-
 flag run-integrated-test
   description: use debug output when running testsuites
   default: False
@@ -56,22 +52,21 @@
     , attoparsec >= 0.10
     , authenticate-oauth >= 1.3
     , bytestring >= 0.10.2
-    , conduit >= 1.1
-    , conduit-extra >= 1.1
+    , conduit >= 1.3
+    , conduit-extra >= 1.3
     , containers
     , data-default >= 0.3
     , exceptions >= 0.5
-    , http-client >= 0.3.0
-    , http-conduit >= 2.0 && < 2.4
+    , ghc-prim
+    , http-client >= 0.5.0
+    , http-conduit >= 2.3 && < 2.4
     , http-types
     , lens >= 4.4
     , lens-aeson >= 1
     , resourcet >= 1.0
-    , template-haskell
     , text >= 0.11
     , time
     , transformers >= 0.2.2
-    , transformers-base
     , twitter-types >= 0.9
     , twitter-types-lens >= 0.9
 
@@ -84,10 +79,11 @@
     Web.Twitter.Conduit.Status
     Web.Twitter.Conduit.Base
     Web.Twitter.Conduit.Request
+    Web.Twitter.Conduit.Request.Internal
     Web.Twitter.Conduit.Response
     Web.Twitter.Conduit.Cursor
     Web.Twitter.Conduit.Parameters
-    Web.Twitter.Conduit.Parameters.TH
+    Web.Twitter.Conduit.ParametersDeprecated
 
   default-language: Haskell2010
 
@@ -128,7 +124,6 @@
     , attoparsec
     , authenticate-oauth
     , bytestring
-    , case-insensitive
     , conduit
     , conduit-extra
     , containers
@@ -140,18 +135,11 @@
     , lens
     , lens-aeson
     , resourcet
-    , template-haskell
     , text
     , time
     , twitter-conduit
     , twitter-types
     , twitter-types-lens
-
-  if flag(network-uri)
-    build-depends: network-uri >= 2.6
-  else
-    build-depends: network < 2.6
-
 
   other-modules:
     Spec
