diff --git a/airship.cabal b/airship.cabal
--- a/airship.cabal
+++ b/airship.cabal
@@ -3,7 +3,7 @@
 description:            A Webmachine-inspired HTTP library
 homepage:               https://github.com/helium/airship/
 Bug-reports:            https://github.com/helium/airship/issues
-version:                0.4.1.0
+version:                0.4.2.0
 license:                MIT
 license-file:           LICENSE
 author:                 Reid Draper and Patrick Thomson
@@ -64,7 +64,7 @@
                       , transformers-base
                       , unix == 2.7.*
                       , unordered-containers
-                      , wai == 3.0.*
+                      , wai >= 3.0 && < 3.3
                       , wai-extra == 3.0.*
 
 test-suite unit
diff --git a/src/Airship/Helpers.hs b/src/Airship/Helpers.hs
--- a/src/Airship/Helpers.hs
+++ b/src/Airship/Helpers.hs
@@ -5,6 +5,9 @@
     , redirectPermanently
     , resourceToWai
     , resourceToWaiT
+    , appendRequestPath
+    , lookupParam
+    , lookupParam'
     ) where
 
 import           Airship.Internal.Helpers
diff --git a/src/Airship/Internal/Decision.hs b/src/Airship/Internal/Decision.hs
--- a/src/Airship/Internal/Decision.hs
+++ b/src/Airship/Internal/Decision.hs
@@ -6,6 +6,7 @@
 
 module Airship.Internal.Decision
     ( flow
+    , appendRequestPath
     ) where
 
 import           Airship.Internal.Date (parseRfc1123Date, utcTimeToRfc1123)
diff --git a/src/Airship/Internal/Helpers.hs b/src/Airship/Internal/Helpers.hs
--- a/src/Airship/Internal/Helpers.hs
+++ b/src/Airship/Internal/Helpers.hs
@@ -3,7 +3,17 @@
 {-# LANGUAGE RankNTypes        #-}
 {-# LANGUAGE RecordWildCards   #-}
 
-module Airship.Internal.Helpers where
+module Airship.Internal.Helpers
+    ( parseFormData
+    , contentTypeMatches
+    , redirectTemporarily
+    , redirectPermanently
+    , resourceToWai
+    , resourceToWaiT
+    , appendRequestPath
+    , lookupParam
+    , lookupParam'
+    ) where
 
 #if __GLASGOW_HASKELL__ < 710
 import           Control.Applicative
@@ -14,6 +24,7 @@
 #if __GLASGOW_HASKELL__ < 710
 import           Data.Monoid
 #endif
+import qualified Data.HashMap.Strict       as HM
 import           Data.Text                 (Text, intercalate)
 import           Data.Text.Encoding
 import           Data.Time                 (getCurrentTime)
@@ -21,6 +32,7 @@
 import           Network.HTTP.Media
 import qualified Network.HTTP.Types        as HTTP
 import qualified Network.Wai               as Wai
+
 import           Network.Wai.Parse
 import           System.Random
 
@@ -116,3 +128,13 @@
 
 traceHeader :: [Text] -> ByteString
 traceHeader = encodeUtf8 . intercalate ","
+
+-- | Lookup routing parameter and return 500 Internal Server Error if not found.
+-- Not finding the paramter usually means the route doesn't match what
+-- the resource is expecting.
+lookupParam :: Monad m => Text -> Webmachine m Text
+lookupParam p = lookupParam' p >>= maybe (halt HTTP.status500) pure
+
+-- | Lookup routing parameter.
+lookupParam' :: Monad m => Text -> Webmachine m (Maybe Text)
+lookupParam' p = HM.lookup p <$> params
diff --git a/src/Airship/Resource.hs b/src/Airship/Resource.hs
--- a/src/Airship/Resource.hs
+++ b/src/Airship/Resource.hs
@@ -64,7 +64,7 @@
              , implemented              :: Webmachine m Bool
                -- | Returns @401 Unauthorized@ if false. Default: true.
              , isAuthorized             :: Webmachine m Bool
-               -- | When processing @PUT@ requests, a @True@ value returned here will halt processing with a @409 Created@.
+               -- | When processing @PUT@ requests, a @True@ value returned here will halt processing with a @409 Conflict@.
              , isConflict               :: Webmachine m Bool
                -- | Returns @415 Unsupported Media Type@ if false. We recommend you use the 'contentTypeMatches' helper function, which accepts a list of
                -- 'MediaType' values, so as to simplify proper MIME type handling. Default: true.
