diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
-## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.0.2...main)
+## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.0.3...main)
+
+## [v0.7.0.3](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.0.2...v0.7.0.3)
+
+- Support `hoauth-2.7`. This change is only breaking in the unlikely case of users
+  using something other than `fetchAccessToken` or `fetchAccessToken2`
 
 ## [v0.7.0.2](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.0.1...v0.7.0.2)
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
 # Yesod.Auth.OAuth2
 
+
+[![Hackage](https://img.shields.io/hackage/v/yesod-auth-oauth2.svg?style=flat)](https://hackage.haskell.org/package/yesod-auth-oauth2)
+[![Stackage Nightly](http://stackage.org/package/yesod-auth-oauth2/badge/nightly)](http://stackage.org/nightly/package/yesod-auth-oauth2)
+[![Stackage LTS](http://stackage.org/package/yesod-auth-oauth2/badge/lts)](http://stackage.org/lts/package/yesod-auth-oauth2)
+[![CI](https://github.com/freckle/yesod-auth-oauth2/actions/workflows/ci.yml/badge.svg)](https://github.com/pbrisbin/freckle/yesod-auth-oauth2/workflows/ci.yml)
+
 OAuth2 `AuthPlugin`s for Yesod.
 
 ## Usage
diff --git a/src/Network/OAuth/OAuth2/Compat.hs b/src/Network/OAuth/OAuth2/Compat.hs
--- a/src/Network/OAuth/OAuth2/Compat.hs
+++ b/src/Network/OAuth/OAuth2/Compat.hs
@@ -3,6 +3,7 @@
 module Network.OAuth.OAuth2.Compat
     ( OAuth2(..)
     , OAuth2Result
+    , Errors
     , authorizationUrl
     , fetchAccessToken
     , fetchAccessToken2
@@ -15,15 +16,25 @@
 import Data.ByteString.Lazy (ByteString)
 import Data.Text (Text)
 import Network.HTTP.Conduit (Manager)
+import qualified Network.OAuth.OAuth2 as OAuth2
+#if MIN_VERSION_hoauth2(2,7,0)
 import Network.OAuth.OAuth2
     ( AccessToken(..)
     , ExchangeToken(..)
+    , OAuth2Token(..)
+    , RefreshToken(..)
+    )
+import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
+#else
+import Network.OAuth.OAuth2
+    ( AccessToken(..)
+    , ExchangeToken(..)
     , OAuth2Error
     , OAuth2Token(..)
     , RefreshToken(..)
     )
-import qualified Network.OAuth.OAuth2 as OAuth2
-import Network.OAuth.OAuth2.TokenRequest (Errors)
+import qualified Network.OAuth.OAuth2.TokenRequest as LegacyTokenRequest
+#endif
 import URI.ByteString
 
 #if MIN_VERSION_hoauth2(2,2,0)
@@ -39,8 +50,14 @@
     , oauth2RedirectUri :: Maybe (URIRef Absolute)
     }
 
-type OAuth2Result err a = Either (OAuth2Error err) a
+#if MIN_VERSION_hoauth2(2,7,0)
+type Errors = TokenRequestError
+#else
+type Errors = OAuth2Error LegacyTokenRequest.Errors
+#endif
 
+type OAuth2Result err a = Either err a
+
 authorizationUrl :: OAuth2 -> URI
 authorizationUrl = OAuth2.authorizationUrl . getOAuth2
 
@@ -134,7 +151,9 @@
     -> IO (OAuth2Result Errors OAuth2Token)
 fetchAccessTokenBasic m o e = runOAuth2 $ f m (getOAuth2 o) e
   where
-#if MIN_VERSION_hoauth2(2,3,0)
+#if MIN_VERSION_hoauth2(2,6,0)
+    f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretBasic
+#elif MIN_VERSION_hoauth2(2,3,0)
     f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretBasic
 #else
     f = OAuth2.fetchAccessToken
@@ -147,7 +166,9 @@
     -> IO (OAuth2Result Errors OAuth2Token)
 fetchAccessTokenPost m o e = runOAuth2 $ f m (getOAuth2 o) e
   where
-#if MIN_VERSION_hoauth2(2,3,0)
+#if MIN_VERSION_hoauth2(2, 6, 0)
+    f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretPost
+#elif MIN_VERSION_hoauth2(2,3,0)
     f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretPost
 #else
     f = OAuth2.fetchAccessToken2
diff --git a/src/Yesod/Auth/OAuth2/Dispatch.hs b/src/Yesod/Auth/OAuth2/Dispatch.hs
--- a/src/Yesod/Auth/OAuth2/Dispatch.hs
+++ b/src/Yesod/Auth/OAuth2/Dispatch.hs
@@ -18,7 +18,6 @@
 import Data.Text.Encoding (encodeUtf8)
 import Network.HTTP.Conduit (Manager)
 import Network.OAuth.OAuth2.Compat
-import Network.OAuth.OAuth2.TokenRequest (Errors)
 import URI.ByteString.Extension
 import UnliftIO.Exception
 import Yesod.Auth hiding (ServerError)
diff --git a/src/Yesod/Auth/OAuth2/DispatchError.hs b/src/Yesod/Auth/OAuth2/DispatchError.hs
--- a/src/Yesod/Auth/OAuth2/DispatchError.hs
+++ b/src/Yesod/Auth/OAuth2/DispatchError.hs
@@ -9,15 +9,14 @@
 {-# LANGUAGE TypeFamilies #-}
 
 module Yesod.Auth.OAuth2.DispatchError
-    ( DispatchError(..)
-    , handleDispatchError
-    , onDispatchError
-    ) where
+  ( DispatchError(..)
+  , handleDispatchError
+  , onDispatchError
+  ) where
 
 import Control.Monad.Except
 import Data.Text (Text, pack)
-import Network.OAuth.OAuth2
-import Network.OAuth.OAuth2.TokenRequest (Errors)
+import Network.OAuth.OAuth2.Compat (Errors)
 import UnliftIO.Except ()
 import UnliftIO.Exception
 import Yesod.Auth hiding (ServerError)
@@ -31,7 +30,7 @@
     | InvalidStateToken (Maybe Text) Text
     | InvalidCallbackUri Text
     | OAuth2HandshakeError ErrorResponse
-    | OAuth2ResultError (OAuth2Error Errors)
+    | OAuth2ResultError Errors
     | FetchCredsIOException IOException
     | FetchCredsYesodOAuth2Exception YesodOAuth2Exception
     | OtherDispatchError Text
@@ -45,37 +44,37 @@
 --
 dispatchErrorMessage :: DispatchError -> Text
 dispatchErrorMessage = \case
-    MissingParameter name ->
-        "Parameter '" <> name <> "' is required, but not present in the URL"
-    InvalidStateToken{} -> "State token is invalid, please try again"
-    InvalidCallbackUri{}
-        -> "Callback URI was not valid, this server may be misconfigured (no approot)"
-    OAuth2HandshakeError er -> "OAuth2 handshake failure: " <> erUserMessage er
-    OAuth2ResultError{} -> "Login failed, please try again"
-    FetchCredsIOException{} -> "Login failed, please try again"
-    FetchCredsYesodOAuth2Exception{} -> "Login failed, please try again"
-    OtherDispatchError{} -> "Login failed, please try again"
+  MissingParameter name ->
+    "Parameter '" <> name <> "' is required, but not present in the URL"
+  InvalidStateToken{} -> "State token is invalid, please try again"
+  InvalidCallbackUri{} ->
+    "Callback URI was not valid, this server may be misconfigured (no approot)"
+  OAuth2HandshakeError er -> "OAuth2 handshake failure: " <> erUserMessage er
+  OAuth2ResultError{}              -> "Login failed, please try again"
+  FetchCredsIOException{}          -> "Login failed, please try again"
+  FetchCredsYesodOAuth2Exception{} -> "Login failed, please try again"
+  OtherDispatchError{}             -> "Login failed, please try again"
 
 handleDispatchError
-    :: MonadAuthHandler site m
-    => ExceptT DispatchError m TypedContent
-    -> m TypedContent
+  :: MonadAuthHandler site m
+  => ExceptT DispatchError m TypedContent
+  -> m TypedContent
 handleDispatchError f = do
-    result <- runExceptT f
-    either onDispatchError pure result
+  result <- runExceptT f
+  either onDispatchError pure result
 
 onDispatchError :: MonadAuthHandler site m => DispatchError -> m TypedContent
 onDispatchError err = do
-    errorId <- liftIO $ randomText 16
-    let suffix = " [errorId=" <> errorId <> "]"
-    $(logError) $ pack (displayException err) <> suffix
+  errorId <- liftIO $ randomText 16
+  let suffix = " [errorId=" <> errorId <> "]"
+  $(logError) $ pack (displayException err) <> suffix
 
-    let message = dispatchErrorMessage err <> suffix
-        messageValue =
-            object ["error" .= object ["id" .= errorId, "message" .= message]]
+  let message = dispatchErrorMessage err <> suffix
+      messageValue =
+        object ["error" .= object ["id" .= errorId, "message" .= message]]
 
-    loginR <- ($ LoginR) <$> getRouteToParent
+  loginR <- ($ LoginR) <$> getRouteToParent
 
-    selectRep $ do
-        provideRep @_ @Html $ onErrorHtml loginR message
-        provideRep @_ @Value $ pure messageValue
+  selectRep $ do
+    provideRep @_ @Html $ onErrorHtml loginR message
+    provideRep @_ @Value $ pure messageValue
diff --git a/yesod-auth-oauth2.cabal b/yesod-auth-oauth2.cabal
--- a/yesod-auth-oauth2.cabal
+++ b/yesod-auth-oauth2.cabal
@@ -1,6 +1,6 @@
 cabal-version:   1.18
 name:            yesod-auth-oauth2
-version:         0.7.0.2
+version:         0.7.0.3
 license:         MIT
 license-file:    LICENSE
 maintainer:      engineering@freckle.com
@@ -67,19 +67,19 @@
         base >=4.9.0.0 && <5,
         bytestring >=0.9.1.4,
         cryptonite >=0.25,
-        errors >=2.3.0,
+        errors,
         hoauth2 >=1.11.0,
         http-client >=0.4.0,
         http-conduit >=2.0,
         http-types >=0.8,
-        memory >=0.14.18,
-        microlens >=0.4.10,
-        mtl >=2.2.2,
-        safe-exceptions >=0.1.7.0,
+        memory,
+        microlens,
+        mtl,
+        safe-exceptions,
         text >=0.7,
-        transformers >=0.5.5.0,
-        unliftio >=0.2.10,
-        uri-bytestring >=0.3.2.1,
+        transformers,
+        unliftio,
+        uri-bytestring,
         yesod-auth >=1.6.0,
         yesod-core >=1.6.0
 
@@ -91,17 +91,17 @@
     ghc-options:      -Wall -threaded -rtsopts -with-rtsopts=-N
     build-depends:
         aeson >=0.6,
-        aeson-pretty >=0.8.7,
+        aeson-pretty,
         base >=4.9.0.0 && <5,
         bytestring >=0.9.1.4,
         containers >=0.6.0.1,
         http-conduit >=2.0,
-        load-env >=0.2.0.2,
+        load-env,
         text >=0.7,
-        warp >=3.2.25,
-        yesod >=1.6.0,
+        warp,
+        yesod,
         yesod-auth >=1.6.0,
-        yesod-auth-oauth2 -any
+        yesod-auth-oauth2
 
     if !flag(example)
         buildable: False
@@ -118,6 +118,6 @@
     ghc-options:      -Wall
     build-depends:
         base >=4.9.0.0 && <5,
-        hspec >=2.6.1,
-        uri-bytestring >=0.3.2.1,
-        yesod-auth-oauth2 -any
+        hspec,
+        uri-bytestring,
+        yesod-auth-oauth2
