diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,33 @@
 # ms-auth
 
-[![Build Status](https://travis-ci.org/githubuser/ms-auth.png)](https://travis-ci.org/githubuser/ms-auth)
+Haskell client bindings to the [Microsoft Identity / Active Directory API]().
+    
+[![Hackage](https://img.shields.io/hackage/v/ms-auth?style=for-the-badge)](https://hackage.haskell.org/package/ms-auth)
 
-TODO Description.
+![main](https://github.com/unfoldml/ms-graph-api/actions/workflows/haskell.yml/badge.svg?branch=main)
+
+
+## Introduction
+
+This library provides helpers for building token-based authentication flows within server-based web apps e.g. 
+
+* [Client Credentials](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) (server/server or automation accounts)
+* [Authorization Code](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) (with human users being prompted to delegate some access rights to the app)
+
+, as well as for keeping tokens up to date in the background.
+
+
+## Status
+
+This library is functional but still in development.
+
+## Evolution of the library
+
+Some breaking changes might also be introduced as the library matures.
+
+We adhere to a simplified version of the [Package Versioning Policy](https://pvp.haskell.org/): breaking changes are signaled by increasing the major version number (e.g. 0.x -> 1.x ).
+
+
+## Copyright
+
+(c) 2023-, Marco Zocca, UnfoldML AB
diff --git a/ms-auth.cabal b/ms-auth.cabal
--- a/ms-auth.cabal
+++ b/ms-auth.cabal
@@ -1,8 +1,8 @@
 name:                ms-auth
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            Microsoft Authentication API
 description:         Bindings to the Microsoft Identity API / Active Directory (AD) for building applications that use either Delegated or App-only permissions. Helper functions are provided for building OAuth2 authentication flows and keep tokens transactionally secure and up to date.
-homepage:            https://github.com/unfoldml/ms-auth
+homepage:            https://github.com/unfoldml/ms-api
 license:             BSD3
 license-file:        LICENSE
 author:              Marco Zocca
diff --git a/src/Network/OAuth2/Session.hs b/src/Network/OAuth2/Session.hs
--- a/src/Network/OAuth2/Session.hs
+++ b/src/Network/OAuth2/Session.hs
@@ -5,17 +5,21 @@
 {-# options_ghc -Wno-unused-imports #-}
 -- | MS Identity user session based on OAuth tokens
 --
--- provides both Delegated permission flow (user-based) and App-only (e.g. server-server and automation accounts)
+-- The library supports the following authentication scenarios :
+--
+-- * [Client Credentials](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) (server/server or automation accounts)
+--
+-- * [Authorization Code](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) (with human users being prompted to delegate some access rights to the app)
+--
+-- and provides functions to keep tokens up to date in the background.
 module Network.OAuth2.Session (
-  -- * Azure App Service
-  withAADUser
   -- * App-only flow
-  , Token
+  Token
   , newNoToken
   , expireToken
   , readToken
   , fetchUpdateToken
-  -- * Delegated permissions flow
+  -- * Auth code grant flow
   -- ** OAuth endpoints
   , loginEndpoint
   , replyEndpoint
@@ -27,6 +31,8 @@
   , expireUser
   , tokensToList
   -- * Scotty misc
+  -- ** Azure App Service
+  , withAADUser
   , Scotty
   , Action
                               ) where
@@ -132,13 +138,12 @@
 
 -- * App-only authorization scenarios (i.e via automation accounts. Human users not involved)
 
-
--- app has one token at a time
+-- | App has (at most) one token at a time
 type Token t = TVar (Maybe t)
 
 newNoToken :: MonadIO m => m (Token t)
 newNoToken = newTVarIO Nothing
-expireToken :: MonadIO m => TVar (Maybe a) -> m ()
+expireToken :: MonadIO m => Token t -> m ()
 expireToken ts = atomically $ modifyTVar ts (const Nothing)
 readToken :: MonadIO m => Token t -> m (Maybe t)
 readToken ts = atomically $ readTVar ts
@@ -150,7 +155,7 @@
 -- https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
 fetchUpdateToken :: MonadIO m =>
                     IdpApplication 'ClientCredentials AzureAD
-                 -> Token OAuth2Token
+                 -> Token OAuth2Token -- ^ token TVar
                  -> Manager
                  -> m ()
 fetchUpdateToken idpApp ts mgr = liftIO $ void $ forkFinally loop cleanup
@@ -181,7 +186,7 @@
 
 
 
--- * Delegated permission flow (i.e. human user involved)
+-- * Auth code grant flow (i.e. human user involved)
 
 -- | Login endpoint
 --
@@ -205,7 +210,7 @@
 -- NB : forks a thread per logged in user to keep their tokens up to date
 replyEndpoint :: MonadIO m =>
                  IdpApplication 'AuthorizationCode AzureAD
-              -> Tokens UserSub OAuth2Token
+              -> Tokens UserSub OAuth2Token -- ^ token TVar
               -> Manager
               -> RoutePattern -- ^ e.g. @"/oauth\/reply"@
               -> Scotty m ()
@@ -224,7 +229,7 @@
          Just codeP -> do
            let
              etoken = ExchangeToken $ TL.toStrict codeP
-           _ <- fetchUpdateTokenDeleg ts idpApp mgr etoken
+           _ <- fetchUpdateTokenACG ts idpApp mgr etoken
            pure ()
          Nothing -> throwE OASEExchangeTokenNotFound
 
@@ -239,13 +244,13 @@
 
 -- | 1) the ExchangeToken arrives with the redirect once the user has approved the scopes in the browser
 -- https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0&tabs=http#authorization-response
-fetchUpdateTokenDeleg :: MonadIO m =>
+fetchUpdateTokenACG :: MonadIO m =>
                          Tokens UserSub OAuth2Token
                       -> IdpApplication 'AuthorizationCode AzureAD
                       -> Manager
                       -> ExchangeToken -- ^ also called 'code'. Expires in 10 minutes
                       -> ExceptT OAuthSessionError m OAuth2Token
-fetchUpdateTokenDeleg ts idpApp mgr etoken = ExceptT $ do
+fetchUpdateTokenACG ts idpApp mgr etoken = ExceptT $ do
   tokenResp <- runExceptT $ conduitTokenRequest idpApp mgr etoken -- OAuth2 token
   case tokenResp of
     Right oat -> case idToken oat of
@@ -254,20 +259,20 @@
         idtClaimsE <- decValidIdToken idt -- decode and validate ID token
         case idtClaimsE of
           Right uid -> do
-            _ <- refreshLoopDeleg ts idpApp mgr uid oat -- fork a thread and start refresh loop for this user
+            _ <- refreshLoopACG ts idpApp mgr uid oat -- fork a thread and start refresh loop for this user
             pure $ Right oat
           Left es -> pure $ Left (OASEJWTException es) -- id token validation failed
     Left es -> pure $ Left (OASEOAuth2Errors es)
 
 -- | 2) fork a thread and start token refresh loop for user @uid@
-refreshLoopDeleg :: (MonadIO m, Ord uid, HasRefreshTokenRequest a) =>
+refreshLoopACG :: (MonadIO m, Ord uid, HasRefreshTokenRequest a) =>
                     Tokens uid OAuth2Token
                  -> IdpApplication a i
                  -> Manager
                  -> uid -- ^ user ID
                  -> OAuth2Token
                  -> m ThreadId
-refreshLoopDeleg ts idpApp mgr uid oaToken = liftIO $ forkFinally (act oaToken) cleanup
+refreshLoopACG ts idpApp mgr uid oaToken = liftIO $ forkFinally (act oaToken) cleanup
   where
     cleanup = \case
       Left _ -> do
