diff --git a/snaplet-sqlite-simple-jwt-auth.cabal b/snaplet-sqlite-simple-jwt-auth.cabal
--- a/snaplet-sqlite-simple-jwt-auth.cabal
+++ b/snaplet-sqlite-simple-jwt-auth.cabal
@@ -1,5 +1,5 @@
 name:                snaplet-sqlite-simple-jwt-auth
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            Snaplet for JWT authentication with snaplet-sqlite-simple
 description:
     JWT authentication snaplet for snaplet-sqlite-simple.
@@ -22,7 +22,7 @@
 library
   hs-source-dirs:      src
   exposed-modules:     Snap.Snaplet.SqliteSimple.JwtAuth
-                       Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth
+  other-modules:       Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth
                        Snap.Snaplet.SqliteSimple.JwtAuth.Db
                        Snap.Snaplet.SqliteSimple.JwtAuth.Util
                        Snap.Snaplet.SqliteSimple.JwtAuth.Types
diff --git a/src/Snap/Snaplet/SqliteSimple/JwtAuth.hs b/src/Snap/Snaplet/SqliteSimple/JwtAuth.hs
--- a/src/Snap/Snaplet/SqliteSimple/JwtAuth.hs
+++ b/src/Snap/Snaplet/SqliteSimple/JwtAuth.hs
@@ -17,10 +17,23 @@
   -- | Use these handlers to implement user registration, login and protecting
   -- routes with authentication.
   --
+  -- The 'registerUser' and 'loginUser' handlers follow a fixed convention for
+  -- request parameters and response.  To sign up a user or login an existing
+  -- user, make a POST request to a route handled by 'registerUser' or
+  -- 'loginUser'.  Both require input parameters to be passed in as JSON.  A
+  -- successful user creation or a login will return HTTP 400 code and reply
+  -- with a JSON object containing the JWT.  Failed login attempts will reply
+  -- with an HTTP 401 error and will reply with a JSON object containing the
+  -- error message.
+  --
+  -- Use the 'requireAuth' wrapper for implementing routes that require
+  -- authentication.  The client side is responsible for passing in a valid
+  -- JWT in the Authentication header.
+  --
   -- If you need to customize error handling or need a different JSON schema
   -- for communicating between the server and client, you may wish the re-
-  -- implement these using the low-level handlers documented later in the
-  -- API ref.
+  -- implement 'registerUser' and 'loginUser' using the low-level handlers
+  -- documented later in the API ref.
   , registerUser
   , loginUser
   , requireAuth
@@ -47,6 +60,8 @@
 -- accounts persisted in a SQLite3 database.  It's intended use is to protect
 -- server API routes used in single-page web applications (SPA) and mobile
 -- applications.
+--
+-- Passwords are hashed and salted using the BCrypt library.
 --
 -- See the https://github.com/nurpax/snap-reactjs-todo project for a full
 -- application using this library.  It implements a todo application as an SPA
diff --git a/src/Snap/Snaplet/SqliteSimple/JwtAuth/JwtAuth.hs b/src/Snap/Snaplet/SqliteSimple/JwtAuth/JwtAuth.hs
--- a/src/Snap/Snaplet/SqliteSimple/JwtAuth/JwtAuth.hs
+++ b/src/Snap/Snaplet/SqliteSimple/JwtAuth/JwtAuth.hs
@@ -133,6 +133,15 @@
 -- Verify authentication from the JWT token passed in the Authorization
 -- header, and run the user provided 'action' with the logged in user.
 --
+-- Use the following syntax for constructing the Authorization header:
+--
+-- @
+-- Bearer \<JWT\>
+-- @
+--
+-- where \<JWT\> is obtained from the "token" field of a successful call to
+-- 'registerUser' or 'loginUser'.
+--
 -- On errors such as missing or malformed JWT or failure to verify the JWT,
 -- error out early and issue an HTTP 401 error.
 requireAuth :: (User -> Handler b SqliteJwt a) -> Handler b SqliteJwt a
@@ -173,6 +182,36 @@
   jwt <- jwtFromUser user
   writeJSON $ object [ "token" .= jwt ]
 
+-- | Create a new user.
+--
+-- Use a POST request for this handler with password and login encoded as JSON
+-- in the body of the request:
+--
+-- @
+-- {
+--    "login": \<login name\>,
+--    "pass": \<password\>
+-- }
+-- @
+--
+-- A successful login will reply with an HTTP 400 code and the following JSON:
+--
+-- @
+-- {
+--    "token": \<JWT\>
+-- }
+-- @
+--
+-- The returned token can be used to make authenticated requests.
+--
+-- Login and user registration errors will be reported with an HTTP error code
+-- 401 and the error message will be sent as a JSON object:
+--
+-- @
+-- {
+--   "error": \<message\>
+-- }
+-- @
 registerUser :: Handler b SqliteJwt ()
 registerUser = method POST newUser
   where
@@ -181,8 +220,39 @@
       userOrErr <- createUser (lpLogin params) (lpPass params)
       either handleLoginError loginOK userOrErr
 
+-- | Login an existing user.
+--
+-- Use a POST request for this handler with password and login encoded as JSON
+-- in the body of the request:
+--
+-- @
+-- {
+--   "login": \<login name\>,
+--   "pass": \<password\>
+-- }
+-- @
+--
+-- A successful login will reply with an HTTP 400 code and the following JSON:
+--
+-- @
+-- {
+--   "token": \<JWT\>
+-- }
+-- @
+--
+-- The returned token can be used to make authenticated requests.
+--
+-- Login and user registration errors will be reported with an HTTP error code
+-- 401 and the error message will be sent as a JSON object:
+--
+-- @
+-- {
+--   "error": \<message\>
+-- }
+-- @
 loginUser :: Handler b SqliteJwt ()
 loginUser = method POST $ do
   params    <- reqJSON
   userOrErr <- login (lpLogin params) (lpPass params)
   either handleLoginError loginOK userOrErr
+
