BSD-3-Clause licensed and maintained by Mark Karpov
This version can be pinned in stack with:req-3.9.1@sha256:e5cc547cc37cb60b809b0d1abba4623abe6f1af40911dde38e2fc8b16630a177,3747

Module documentation for 3.9.1


License BSD3 Hackage Stackage Nightly Stackage LTS CI

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import Control.Monad.IO.Class
import Data.Aeson
import Network.HTTP.Req

main :: IO ()
-- You can either make your monad an instance of 'MonadHttp', or use
-- 'runReq' in any IO-enabled monad without defining new instances.
main = runReq defaultHttpConfig $ do
  let payload =
          [ "foo" .= (10 :: Int),
            "bar" .= (20 :: Int)
  -- One function—full power and flexibility, automatic retrying on timeouts
  -- and such, automatic connection sharing.
  r <-
      POST -- method
      (https "" /: "post") -- safe by construction URL
      (ReqBodyJson payload) -- use built-in options or add your own
      jsonResponse -- specify how to interpret response
      mempty -- query params, headers, explicit port number, etc.
  liftIO $ print (responseBody r :: Value)

Req is an HTTP client library that attempts to be easy-to-use, type-safe, and expandable.

“Easy-to-use” means that the library is designed to be beginner-friendly so it’s simple to add to your monad stack, intuitive to work with, well-documented, and does not get in your way. Doing HTTP requests is a common task and a Haskell library for this should be approachable and clear to beginners, thus certain compromises were made. For example, one cannot currently modify ManagerSettings of the default manager because the library always uses the same implicit global manager for simplicity and maximal connection sharing. There is a way to use your own manager with different settings, but it requires more typing.

“Type-safe” means that the library tries to eliminate certain classes of errors. For example, we have correct-by-construction URLs; it is guaranteed that the user does not send the request body when using methods like GET or OPTIONS, and the amount of implicit assumptions is minimized by making the user specify their intentions in an explicit form. For example, it’s not possible to avoid specifying the body or the method of a request. Authentication methods that assume HTTPS force the user to use HTTPS at the type level.

“Expandable” refers to the ability to create new components without having to resort to hacking. For example, it’s possible to define your own HTTP methods, create new ways to construct the body of a request, create new authorization options, perform a request in a different way, and create your own methods to parse a response.

The library uses the following mature packages under the hood to guarantee you the best experience:

It is important to note that since we leverage well-known libraries that the whole Haskell ecosystem uses, there is no risk in using Req. The machinery for performing requests is the same as with http-conduit and Wreq. The only difference is the API.

Related packages

The following packages are designed to be used with Req:

  • req-conduit—support for streaming request and response bodies in constant memory.

If you happen to have written a package that adds new features to Req, please submit a PR to include it in this list.

Blog posts


Issues, bugs, and questions may be reported in the GitHub issue tracker for this project.

Pull requests are also welcome.


Copyright © 2016–present Mark Karpov

Distributed under BSD 3 clause license.


Req 3.9.1

  • Builds with GHC 9.0.

Req 3.9.0

  • The useHttpURI and useHttpsURI functions now preserve trailing slashes.

Req 3.8.0

  • Adjusted the value of the httpConfigRetryJudgeException field of defaultHttpConfig to retry on response timeouts and connection timeouts.

Req 3.7.0

  • Added reqCb, a function that allows you to modify the Request object but otherwise performs the requst for you.

  • Derived MonadThrow, MonadCatch, and MonadMask for the Req monad.

Req 3.6.0

  • Added the httpConfigBodyPreviewLength configuration parameter to HttpConfig.

Req 3.5.0

  • Made Req an instance of MonadUnliftIO. Issue 100.

Req 3.4.0

  • Requests using DELETE method can now have a body. Issue 89.

  • Added the httpConfigRetryJudgeException field to HttpConfig so that requests that result in exceptions can be retried. Issue 93.

  • Added the function renderUrl. Issue 83.

Req 3.3.0

  • Derived Show instances for response types IgnoreResponse, JsonResponse, BsResponse, and LbsResponse.

Req 3.2.0

  • Made the tests pass with http-client-0.7 and later.

  • Added a quasiquoter for URL creation, urlQ.

Req 3.1.0

  • Changed signature of httpConfigRetryPolicy to RetryPolicyM IO.

Req 3.0.0

  • Dropped functions parseUrlHttp, parseUrlHttps, and parseUrl. Instead we now have useHttpURI, useHttpsURI, and useURI take URIs from modern-uri as their argument. You first parse your URL with the modern-uri package and then pass it to those functions. This allows us to work with typed URI representations and seamlessly convert them to something req can work with. As a side effect basic auth from the URIs is now taken into consideration. In the future we may also start to respect fragments if http-client starts to support this.

  • Dropped support for GHC 8.2 and older.

Req 2.1.0

  • Dropped support for GHC 7.10.

  • Added the new acceptHeader method to the HttpResponse type class. Notably, the jsonResponse method now sets "Accept" header to "application/json".

Req 2.0.1

  • Fixed the httpbin tests (they changed something on the server again).

Req 2.0.0

  • Got rid of data-default-class dependency, now we export defaultHttpConfig instead.

Req 1.2.1

  • Fixed a typo in the type signature of parseUrl.

Req 1.2.0

  • Added the parseUrl function.

Req 1.1.0

  • Added customAuth and attachHeader to facilitate creation of custom authentication options.

  • Added basicProxyAuth authentication option.

Req 1.0.0

  • Added the reqBr function allowing to consume Response BodyReader without using a pre-defined instance of HttpResponse, in a custom way.

  • Now streaming of response body does not happen until we’ve checked headers and status code with httpConfigCheckResponse. It also doesn’t happen on every retry. Streaming and obtaining of final response value happens only once when we’re happy with everything.

    Previously we first tried to consume and interpret response body before checking status code and determining whether we should retry the request. This was not good, because we could expect a JSON response but get a response with status code 500, and then still we would try to parse it as JSON first before letting httpConfigCheckResponse throw an exception.

    The corrected behavior should also make retrying more efficient.

  • Changed signatures of several fields of HttpConfig: httpConfigCheckResponse, httpConfigRetryPolicy, and httpConfigRetryJudge in order to eliminate redundant IO and prevent the possibility that these functions could start consuming BodyReader.

  • Removed the makeResponsePreview method from the HttpResponse type class. Preview business is handled by the library automatically on a lower level now. Users do not need to concern themselves with such stuff.

  • Changed the type signature of the getHttpResponse method of the HttpResponse type class. Previously it left too much freedom (and responsibility) to implementers of the method. In fact, we now limit what getHttpResponse does to just consuming and interpreting Response BodyReader, so we can properly control details of connection opening/closing etc., for the user.

  • Dropped support for GHC 7.8.

  • Minor documentation improvements.

Req 0.5.0

  • Changed the signature of the makeResponseBodyPreview from response -> IO ByteString to response -> ByteString.

  • Minor documentation improvements.

Req 0.4.0

  • Added the Req monad and runReq function to run it. This allows to use req without defining new (orphan) instances.

Req 0.3.1

  • Added basicAuthUnsafe.

Req 0.3.0

  • Made URL parsing functions parseUrlHttp and parseUrlHttps recognize port numbers.

  • Added req' function that allows to perform requests via a callback that receives pre-constructed request and manager.

  • Removed the ReturnRequest HTTP response implementation as it was not quite safe and was not going to work with retrying. Use req' instead for “pure” testing.

  • Changed the type of httpConfigCheckResponse, so the second argument can be any instance of HttpResponse.

  • Added built-in automatic retrying. See httpConfigRetryPolicy and httpConfigRetryJudge in HttpConfig. The default configuration retries 5 times on request timeouts.

  • Added the makeResponseBodyPreview method to the HttpResponse type class that allows to specify how to build a “preview” of response body for inclusion into exceptions.

  • Improved wording in the documentation and

Req 0.2.0

  • Added support for multipart form data in the form of ReqBodyMultipart body option and reqBodyMultipart helper function. This also required a change in the type signature of getRequestContentType, which now takes body, not Proxy body because we need to extract boundary from body and put it into Content-Type header. This change, however, shouldn’t be too dangerous for end-users.

  • Added support for OAuth 1.0 authentication via oAuth1 option.

Req 0.1.0

  • Initial release.