diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-google-oauth2-jwt - Copyright Michel Boucey (c) 2016
+google-oauth2-jwt - Copyright Michel Boucey (c) 2016-2017
 
 All rights reserved.
 
diff --git a/google-oauth2-jwt.cabal b/google-oauth2-jwt.cabal
--- a/google-oauth2-jwt.cabal
+++ b/google-oauth2-jwt.cabal
@@ -1,13 +1,14 @@
 name:                google-oauth2-jwt
-version:             0.1.3
+version:             0.2.0
 synopsis:            Get a signed JWT for Google Service Accounts
-description:         Please see README.md
+description:         This library implements the creation of the
+                     signed JWT for Google Service Accounts.
 homepage:            https://github.com/MichelBoucey/google-oauth2-jwt
 license:             BSD3
 license-file:        LICENSE
 author:              Michel Boucey
 maintainer:          michel.boucey@cybervisible.fr
-copyright:           (c) 2016 - Michel Boucey
+copyright:           (c) 2016-2017 - Michel Boucey
 category:            Google
 build-type:          Simple
 extra-source-files:  README.md
@@ -16,13 +17,13 @@
 library
   hs-source-dirs:   src
   exposed-modules:  Network.Google.OAuth2.JWT
-  build-depends:    base >= 4.7 && < 5
-                  , base64-bytestring   >= 1.0.0 && < 1.1
-                  , bytestring          >= 0.10.6 && < 0.11
+  build-depends:    base                >= 4.7      && < 5
+                  , base64-bytestring   >= 1.0.0    && < 1.1
+                  , bytestring          >= 0.10.6   && < 0.11
                   , HsOpenSSL           >= 0.11.1.1 && < 0.12
-                  , RSA                 >= 2.1.0.3 && < 2.3
-                  , text                >= 1.2.2 && < 1.3
-                  , unix-time           >= 0.3.6 && < 0.4
+                  , RSA                 >= 2.1.0.3  && < 2.3
+                  , text                >= 1.2.2    && < 1.3
+                  , unix-time           >= 0.3.6    && < 0.4
 
   default-language: Haskell2010
   GHC-options:      -Wall
diff --git a/src/Network/Google/OAuth2/JWT.hs b/src/Network/Google/OAuth2/JWT.hs
--- a/src/Network/Google/OAuth2/JWT.hs
+++ b/src/Network/Google/OAuth2/JWT.hs
@@ -19,13 +19,14 @@
     ) where
 
 import           Codec.Crypto.RSA.Pure
+import           Control.Monad              (unless)
 import qualified Data.ByteString            as B
 import           Data.ByteString.Base64.URL (encode)
 import           Data.ByteString.Lazy       (fromStrict, toStrict)
 import           Data.Maybe                 (fromMaybe, fromJust)
 import           Data.Monoid                ((<>))
 import qualified Data.Text                  as T
-import           Data.Text.Encoding
+import           Data.Text.Encoding         (encodeUtf8)
 import           Data.UnixTime              (getUnixTime, utSeconds)
 import           Foreign.C.Types
 import           OpenSSL.EVP.PKey           (toKeyPair)
@@ -33,19 +34,23 @@
                                              readPrivateKey)
 import           OpenSSL.RSA
 
-type Scope = T.Text
+data SignedJWT =
+  SignedJWT !B.ByteString
+  deriving (Eq, Show)
 
 type Email = T.Text
 
+type Scope = T.Text
+
 -- | Get the private key obtained from the
--- the Google API Console from a PEM file.
+-- Google API Console from a PEM file.
 fromPEMFile :: FilePath -> IO PrivateKey
 fromPEMFile f = readFile f >>= fromPEMString
 
 -- | Get the private key obtained from the
 -- Google API Console from a PEM 'String'.
 --
--- >fromPEMString "-----BEGIN PRIVATE KEY-----\nB9e ... bMdF\n-----END PRIVATE KEY-----\n"
+-- >fromPEMString "-----BEGIN PRIVATE KEY-----\nB9e [...] bMdF\n-----END PRIVATE KEY-----\n"
 -- >
 fromPEMString :: String -> IO PrivateKey
 fromPEMString s =
@@ -53,10 +58,11 @@
     \k -> return
       PrivateKey
         { private_pub =
-            PublicKey { public_size = rsaSize k
-                      , public_n    = rsaN k
-                      , public_e    = rsaE k
-                      }
+            PublicKey
+              { public_size = rsaSize k
+              , public_n    = rsaN k
+              , public_e    = rsaE k
+              }
         , private_d    = rsaD k
         , private_p    = rsaP k
         , private_q    = rsaQ k
@@ -70,41 +76,42 @@
 --
 -- >grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=
 --
-getSignedJWT :: Email
-             -- ^ The email address of the service account.
-             -> Maybe Email
-             -- ^ The email address of the user for which the
-             -- application is requesting delegated access.
-             -> [Scope]
-             -- ^ The list of the permissions that the application requests.
-             -> Maybe Int
-             -- ^ Expiration time (maximun and default value is an hour, 3600).
-             -> PrivateKey
-             -- ^ The private key gotten from the PEM string obtained from the
-             -- Google API Console.
-             -> IO (Either String B.ByteString)
-             -- ^ Either an error message or a signed JWT.
+getSignedJWT
+  :: Email
+  -- ^ The email address of the service account.
+  -> Maybe Email
+  -- ^ The email address of the user for which the
+  -- application is requesting delegated access.
+  -> [Scope]
+  -- ^ The list of the permissions that the application requests.
+  -> Maybe Int
+  -- ^ Expiration time (maximun and default value is an hour, 3600).
+  -> PrivateKey
+  -- ^ The private key gotten from the PEM string obtained from the
+  -- Google API Console.
+  -> IO (Either String SignedJWT)
+  -- ^ Either an error message or a signed JWT.
 getSignedJWT iss msub scs mxt pk = do
   let xt = fromIntegral (fromMaybe 3600 mxt)
-  if xt >= 1 && xt <= 3600
-    then do
-      cs <- do
-        let s = maybe T.empty (\e -> "\"sub\":\"" <> e <> "\",") msub
-        (t',xt') <- getUnixTime >>=
-          \t -> return (toText (utSeconds t),toText (utSeconds t + CTime xt))
-        return $
-          toJWT $
-            "{\"iss\":\"" <> iss <> "\"," <> s <> "\"scope\":\"" <>
-            T.intercalate " " scs <> "\",\"aud\":\"https://www.goo\
-            \gleapis.com/oauth2/v4/token\",\"exp\":" <> xt' <> ",\"\
-            \iat\":" <> t' <> "}"
-      let i = toJWT "{\"alg\":\"RS256\",\"typ\":\"JWT\"}" <> "." <> cs
-      return $
-        case rsassa_pkcs1_v1_5_sign hashSHA256 pk (fromStrict i) of
-          Right s -> Right (i <> "." <> encode (toStrict s))
-          Left _  -> Left "RSAError"
-    else fail "Bad expiration time"
+  unless (xt >= 1 && xt <= 3600) (fail "Bad expiration time")
+  t <- getUnixTime
+  let i = header <> "." <> toB64 ("{\"iss\":\"" <> iss <> "\","
+          <> maybe T.empty (\e -> "\"sub\":\"" <> e <> "\",") msub
+          <> "\"scope\":\"" <> T.intercalate " " scs <> "\",\"aud\
+          \\":\"https://www.googleapis.com/oauth2/v4/token\",\"ex\
+          \p\":" <> toT (utSeconds t + CTime xt) <> ",\"iat\":"
+          <> toT (utSeconds t) <> "}")
+  return $
+    either
+      (fail "RSAError")
+      (\s -> return $ SignedJWT $ i <> "." <> encode (toStrict s))
+      (rsassa_pkcs1_v1_5_sign hashSHA256 pk $ fromStrict i)
   where
-    toText = T.pack . show
-    toJWT = encode . encodeUtf8
+    toT = T.pack . show
+
+header :: B.ByteString
+header = toB64 "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"
+
+toB64 :: T.Text -> B.ByteString
+toB64 = encode . encodeUtf8
 
