diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 [The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md)
 
+0.18.2
+------
+
+### Significant changes
+
+- Introduce `Fragment` combinator.
+- Fix `MimeRender` and `MimeUnrender` instances for `WithStatus`.
+
 0.18.1
 ------
 
diff --git a/servant.cabal b/servant.cabal
--- a/servant.cabal
+++ b/servant.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                servant
-version:             0.18.1
+version:             0.18.2
 
 synopsis:            A family of combinators for defining webservices APIs
 category:            Servant, Web
@@ -40,6 +40,7 @@
     Servant.API.Description
     Servant.API.Empty
     Servant.API.Experimental.Auth
+    Servant.API.Fragment
     Servant.API.Generic
     Servant.API.Header
     Servant.API.HttpVersion
diff --git a/src/Servant/API.hs b/src/Servant/API.hs
--- a/src/Servant/API.hs
+++ b/src/Servant/API.hs
@@ -19,6 +19,8 @@
   -- | Retrieving the HTTP version of the request
   module Servant.API.QueryParam,
   -- | Retrieving parameters from the query string of the 'URI': @'QueryParam'@
+  module Servant.API.Fragment,
+  -- | Documenting the fragment of the 'URI': @'Fragment'@
   module Servant.API.ReqBody,
   -- | Accessing the request body as a JSON-encoded type: @'ReqBody'@
   module Servant.API.RemoteHost,
@@ -93,6 +95,8 @@
                  (EmptyAPI (..))
 import           Servant.API.Experimental.Auth
                  (AuthProtect)
+import           Servant.API.Fragment
+                 (Fragment)
 import           Servant.API.Header
                  (Header, Header')
 import           Servant.API.HttpVersion
@@ -121,21 +125,20 @@
                  ToSourceIO (..))
 import           Servant.API.Sub
                  ((:>))
+import           Servant.API.UVerb
+                 (HasStatus, IsMember, StatusOf, Statuses, UVerb, Union,
+                 Unique, WithStatus (..), inject, statusOf)
 import           Servant.API.Vault
                  (Vault)
 import           Servant.API.Verbs
                  (Delete, DeleteAccepted, DeleteNoContent,
                  DeleteNonAuthoritative, Get, GetAccepted, GetNoContent,
                  GetNonAuthoritative, GetPartialContent, GetResetContent,
-                 Patch, PatchAccepted, PatchNoContent, PatchNonAuthoritative,
-                 Post, PostAccepted, PostCreated, PostNoContent,
-                 PostNonAuthoritative, PostResetContent, Put, PutAccepted,
-                 PutCreated, PutNoContent, PutNonAuthoritative,
-                 ReflectMethod (reflectMethod), StdMethod (..),
-                 Verb, NoContentVerb)
-import           Servant.API.UVerb
-                 (UVerb, Union, HasStatus, StatusOf, statusOf, Statuses,
-                 WithStatus (..), IsMember, Unique, inject)
+                 NoContentVerb, Patch, PatchAccepted, PatchNoContent,
+                 PatchNonAuthoritative, Post, PostAccepted, PostCreated,
+                 PostNoContent, PostNonAuthoritative, PostResetContent, Put,
+                 PutAccepted, PutCreated, PutNoContent, PutNonAuthoritative,
+                 ReflectMethod (reflectMethod), StdMethod (..), Verb)
 import           Servant.API.WithNamedContext
                  (WithNamedContext)
 import           Servant.Links
diff --git a/src/Servant/API/Fragment.hs b/src/Servant/API/Fragment.hs
new file mode 100644
--- /dev/null
+++ b/src/Servant/API/Fragment.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE PolyKinds          #-}
+{-# LANGUAGE TypeOperators      #-}
+{-# OPTIONS_HADDOCK not-home    #-}
+module Servant.API.Fragment (Fragment) where
+
+import           Data.Typeable
+                 (Typeable)
+
+-- | Document the URI fragment in API. Useful in combination with 'Link'.
+--
+-- Example:
+--
+-- >>> -- /post#TRACKING
+-- >>> type MyApi = "post" :> Fragment Text :> Get '[JSON] Tracking
+data Fragment (a :: *)
+    deriving Typeable
+
+-- $setup
+-- >>> import Servant.API
+-- >>> import Data.Aeson
+-- >>> import Data.Text
+-- >>> data Tracking
+-- >>> instance ToJSON Tracking where { toJSON = undefined }
diff --git a/src/Servant/API/Modifiers.hs b/src/Servant/API/Modifiers.hs
--- a/src/Servant/API/Modifiers.hs
+++ b/src/Servant/API/Modifiers.hs
@@ -131,8 +131,6 @@
        (If (FoldLenient mods) (Either Text a) a)
        (Maybe (If (FoldLenient mods) (Either Text a) a))
 
-
-
 -- | Unfold a value into a 'RequestArgument'.
 unfoldRequestArgument
     :: forall mods m a. (Monad m, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods))
diff --git a/src/Servant/API/TypeLevel.hs b/src/Servant/API/TypeLevel.hs
--- a/src/Servant/API/TypeLevel.hs
+++ b/src/Servant/API/TypeLevel.hs
@@ -1,12 +1,16 @@
-{-# LANGUAGE CPP                   #-}
-{-# LANGUAGE ConstraintKinds       #-}
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE PolyKinds             #-}
-{-# LANGUAGE TypeFamilies          #-}
-{-# LANGUAGE TypeOperators         #-}
-{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ConstraintKinds          #-}
+{-# LANGUAGE DataKinds                #-}
+{-# LANGUAGE FlexibleInstances        #-}
+{-# LANGUAGE KindSignatures           #-}
+{-# LANGUAGE MultiParamTypeClasses    #-}
+{-# LANGUAGE PolyKinds                #-}
+{-# LANGUAGE ScopedTypeVariables      #-}
+{-# LANGUAGE TypeFamilies             #-}
+{-# LANGUAGE TypeOperators            #-}
+{-# LANGUAGE RankNTypes               #-}
+{-# LANGUAGE UndecidableInstances     #-}
+{-# LANGUAGE UndecidableSuperClasses  #-}
 
 {-|
 This module collects utilities for manipulating @servant@ API types. The
@@ -41,6 +45,9 @@
     -- ** Logic
     Or,
     And,
+    -- ** Fragment
+    FragmentUnique,
+    AtLeastOneFragment
     ) where
 
 
@@ -50,6 +57,7 @@
                  (type (:<|>))
 import           Servant.API.Capture
                  (Capture, CaptureAll)
+import           Servant.API.Fragment
 import           Servant.API.Header
                  (Header)
 import           Servant.API.QueryParam
@@ -60,6 +68,8 @@
                  (type (:>))
 import           Servant.API.Verbs
                  (Verb)
+import           Servant.API.UVerb
+                 (UVerb)
 import           GHC.TypeLits
                  (ErrorMessage (..), TypeError)
 
@@ -128,6 +138,7 @@
   IsElem sa (QueryParam x y :> sb)        = IsElem sa sb
   IsElem sa (QueryParams x y :> sb)       = IsElem sa sb
   IsElem sa (QueryFlag x :> sb)           = IsElem sa sb
+  IsElem sa (Fragment x :> sb)            = IsElem sa sb
   IsElem (Verb m s ct typ) (Verb m s ct' typ)
                                           = IsSubList ct ct'
   IsElem e e                              = ()
@@ -241,13 +252,51 @@
 families are not evaluated (see https://ghc.haskell.org/trac/ghc/ticket/12048).
 -}
 
+-- ** Fragment
 
+class FragmentUnique api => AtLeastOneFragment api
+
+-- | If fragment appeared in API endpoint twice, compile-time error would be raised.
+--
+-- >>> -- type FailAPI = Fragment Bool :> Fragment Int :> Get '[JSON] NoContent
+-- >>> instance AtLeastOneFragment FailAPI
+-- ...
+-- ...Only one Fragment allowed per endpoint in api...
+-- ...
+-- ...In the instance declaration for...
+instance AtLeastOneFragment (Verb m s ct typ)
+
+instance AtLeastOneFragment (UVerb m cts as)
+
+instance AtLeastOneFragment (Fragment a)
+
+type family FragmentUnique api :: Constraint where
+  FragmentUnique (sa :<|> sb)       = And (FragmentUnique sa) (FragmentUnique sb)
+  FragmentUnique (Fragment a :> sa) = FragmentNotIn sa (Fragment a :> sa)
+  FragmentUnique (x :> sa)          = FragmentUnique sa
+  FragmentUnique (Fragment a)       = ()
+  FragmentUnique x                  = ()
+
+type family FragmentNotIn api orig :: Constraint where
+  FragmentNotIn (sa :<|> sb)       orig =
+    And (FragmentNotIn sa orig) (FragmentNotIn sb orig)
+  FragmentNotIn (Fragment c :> sa) orig = TypeError (NotUniqueFragmentInApi orig)
+  FragmentNotIn (x :> sa)          orig = FragmentNotIn sa orig
+  FragmentNotIn (Fragment c)       orig = TypeError (NotUniqueFragmentInApi orig)
+  FragmentNotIn x                  orig = ()
+
+type NotUniqueFragmentInApi api =
+    'Text "Only one Fragment allowed per endpoint in api ‘"
+    ':<>: 'ShowType api
+    ':<>: 'Text "’."
+
 -- $setup
 --
 -- The doctests in this module are run with following preamble:
 --
 -- >>> :set -XPolyKinds
 -- >>> :set -XGADTs
+-- >>> :set -XTypeSynonymInstances -XFlexibleInstances
 -- >>> import Data.Proxy
 -- >>> import Data.Type.Equality
 -- >>> import Servant.API
@@ -255,4 +304,5 @@
 -- >>> instance Show (OK ctx) where show _ = "OK"
 -- >>> let ok :: ctx => Proxy ctx -> OK ctx; ok _ = OK
 -- >>> type SampleAPI = "hello" :> Get '[JSON] Int :<|> "bye" :> Capture "name" String :> Post '[JSON, PlainText] Bool
+-- >>> type FailAPI = Fragment Bool :> Fragment Int :> Get '[JSON] NoContent
 -- >>> let sampleAPI = Proxy :: Proxy SampleAPI
diff --git a/src/Servant/API/UVerb.hs b/src/Servant/API/UVerb.hs
--- a/src/Servant/API/UVerb.hs
+++ b/src/Servant/API/UVerb.hs
@@ -4,14 +4,13 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 -- | An alternative to 'Verb' for end-points that respond with a resource value of any of an
 -- open union of types, and specific status codes for each type in this union.  (`UVerb` is
@@ -34,12 +33,10 @@
   )
 where
 
-import Data.Aeson (FromJSON, ToJSON)
 import Data.Proxy (Proxy (Proxy))
-import qualified GHC.Generics as GHC
 import GHC.TypeLits (Nat)
 import Network.HTTP.Types (Status, StdMethod)
-import Servant.API.ContentTypes (MimeRender (mimeRender), MimeUnrender (mimeUnrender), NoContent)
+import Servant.API.ContentTypes (NoContent, MimeRender(mimeRender), MimeUnrender(mimeUnrender))
 import Servant.API.Status (KnownStatus, statusVal)
 import Servant.API.UVerb.Union
 
@@ -49,9 +46,6 @@
 statusOf :: forall a proxy. HasStatus a => proxy a -> Status
 statusOf = const (statusVal (Proxy :: Proxy (StatusOf a)))
 
-instance KnownStatus n => HasStatus (WithStatus n a) where
-  type StatusOf (WithStatus n a) = n
-
 -- | If an API can respond with 'NoContent' we assume that this will happen
 -- with the status code 204 No Content. If this needs to be overridden,
 -- 'WithStatus' can be used.
@@ -70,12 +64,10 @@
   type Statuses (a ': as) = StatusOf a ': Statuses as
   statuses _ = statusOf (Proxy :: Proxy a) : statuses (Proxy :: Proxy as)
 
+-- | A simple newtype wrapper that pairs a type with its status code.  It
+-- implements all the content types that Servant ships with by default.
 newtype WithStatus (k :: Nat) a = WithStatus a
-  deriving (Eq, Show, GHC.Generic)
-
-instance (GHC.Generic (WithStatus n a), ToJSON a) => ToJSON (WithStatus n a)
-
-instance (GHC.Generic (WithStatus n a), FromJSON a) => FromJSON (WithStatus n a)
+  deriving (Eq, Show)
 
 instance MimeRender ctype a => MimeRender ctype (WithStatus _status a) where
   mimeRender contentTypeProxy (WithStatus a) = mimeRender contentTypeProxy a
@@ -83,6 +75,24 @@
 instance MimeUnrender ctype a => MimeUnrender ctype (WithStatus _status a) where
   mimeUnrender contentTypeProxy input =
     WithStatus <$> mimeUnrender contentTypeProxy input
+
+-- | an instance of this typeclass assigns a HTTP status code to a return type
+--
+-- Example:
+--
+-- @
+--    data NotFoundError = NotFoundError String
+--
+--    instance HasStatus NotFoundError where
+--      type StatusOf NotFoundError = 404
+-- @
+--
+-- You can also use the convience newtype wrapper 'WithStatus' if you want to
+-- avoid writing a 'HasStatus' instance manually. It also has the benefit of
+-- showing the status code in the type; which might aid in readability.
+instance KnownStatus n => HasStatus (WithStatus n a) where
+  type StatusOf (WithStatus n a) = n
+
 
 -- | A variant of 'Verb' that can have any of a number of response values and status codes.
 --
diff --git a/src/Servant/Links.hs b/src/Servant/Links.hs
--- a/src/Servant/Links.hs
+++ b/src/Servant/Links.hs
@@ -120,6 +120,7 @@
   , Param (..)
   , linkSegments
   , linkQueryParams
+  , linkFragment
 ) where
 
 import           Data.List
@@ -152,6 +153,8 @@
                  (EmptyAPI (..))
 import           Servant.API.Experimental.Auth
                  (AuthProtect)
+import           Servant.API.Fragment
+                 (Fragment)
 import           Servant.API.Generic
 import           Servant.API.Header
                  (Header')
@@ -188,10 +191,13 @@
 data Link = Link
   { _segments    :: [Escaped]
   , _queryParams :: [Param]
+  , _fragment    :: Fragment'
   } deriving Show
 
 newtype Escaped = Escaped String
 
+type Fragment' = Maybe String
+
 escaped :: String -> Escaped
 escaped = Escaped . escapeURIString isUnreserved
 
@@ -208,11 +214,14 @@
 linkQueryParams :: Link -> [Param]
 linkQueryParams = _queryParams
 
+linkFragment :: Link -> Fragment'
+linkFragment = _fragment
+
 instance ToHttpApiData Link where
     toHeader   = TE.encodeUtf8 . toUrlPiece
     toUrlPiece l =
         let uri = linkURI l
-        in Text.pack $ uriPath uri ++ uriQuery uri
+        in Text.pack $ uriPath uri ++ uriQuery uri ++ uriFragment uri
 
 -- | Query parameter.
 data Param
@@ -228,6 +237,9 @@
 addQueryParam qp l =
     l { _queryParams = _queryParams l <> [qp] }
 
+addFragment :: Fragment' -> Link -> Link
+addFragment fr l = l { _fragment = fr }
+
 -- | Transform 'Link' into 'URI'.
 --
 -- >>> type API = "something" :> Get '[JSON] Int
@@ -245,7 +257,7 @@
 -- >>> type SomeRoute = "abc" :> Capture "email" String :> Put '[JSON] ()
 -- >>> let someRoute = Proxy :: Proxy SomeRoute
 -- >>> safeLink someRoute someRoute "test@example.com"
--- Link {_segments = ["abc","test%40example.com"], _queryParams = []}
+-- Link {_segments = ["abc","test%40example.com"], _queryParams = [], _fragment = Nothing}
 --
 -- >>> linkURI $ safeLink someRoute someRoute "test@example.com"
 -- abc/test%40example.com
@@ -269,11 +281,12 @@
 -- sum?x=1&x=2&x=3
 --
 linkURI' :: LinkArrayElementStyle -> Link -> URI
-linkURI' addBrackets (Link segments q_params) =
+linkURI' addBrackets (Link segments q_params mfragment) =
     URI mempty  -- No scheme (relative)
         Nothing -- Or authority (relative)
         (intercalate "/" $ map getEscaped segments)
-        (makeQueries q_params) mempty
+        (makeQueries q_params)
+        (makeFragment mfragment)
   where
     makeQueries :: [Param] -> String
     makeQueries [] = ""
@@ -285,6 +298,10 @@
     makeQuery (SingleParam k v)    = escape k <> "=" <> escape (Text.unpack v)
     makeQuery (FlagParam k)        = escape k
 
+    makeFragment :: Fragment' -> String
+    makeFragment Nothing = ""
+    makeFragment (Just fr) = "#" <> escape fr
+
     style = case addBrackets of
         LinkArrayElementBracket -> "[]="
         LinkArrayElementPlain -> "="
@@ -310,7 +327,7 @@
     -> Proxy api      -- ^ The whole API that this endpoint is a part of
     -> Proxy endpoint -- ^ The API endpoint you would like to point to
     -> MkLink endpoint a
-safeLink' toA _ endpoint = toLink toA endpoint (Link mempty mempty)
+safeLink' toA _ endpoint = toLink toA endpoint (Link mempty mempty mempty)
 
 -- | Create all links in an API.
 --
@@ -341,7 +358,7 @@
     => (Link -> a)
     -> Proxy api
     -> MkLink api a
-allLinks' toA api = toLink toA api (Link mempty mempty)
+allLinks' toA api = toLink toA api (Link mempty mempty mempty)
 
 -------------------------------------------------------------------------------
 -- Generics
@@ -562,6 +579,13 @@
 instance HasLink sub => HasLink (AuthProtect tag :> sub) where
   type MkLink (AuthProtect tag :> sub) a = MkLink sub a
   toLink = simpleToLink (Proxy :: Proxy sub)
+
+instance (HasLink sub, ToHttpApiData v)
+    => HasLink (Fragment v :> sub) where
+  type MkLink (Fragment v :> sub) a = v -> MkLink sub a
+  toLink toA _ l mv =
+      toLink toA (Proxy :: Proxy sub) $
+         addFragment ((Just . Text.unpack . toQueryParam) mv) l
 
 -- | Helper for implementing 'toLink' for combinators not affecting link
 -- structure.
diff --git a/src/Servant/Test/ComprehensiveAPI.hs b/src/Servant/Test/ComprehensiveAPI.hs
--- a/src/Servant/Test/ComprehensiveAPI.hs
+++ b/src/Servant/Test/ComprehensiveAPI.hs
@@ -71,6 +71,7 @@
     :<|> "summary"          :> Summary "foo" :> GET
     :<|> "description"      :> Description "foo" :> GET
     :<|> "alternative"      :> ("left" :> GET :<|> "right" :> GET)
+    :<|> "fragment"         :> Fragment Int :> GET
     :<|> endpoint
 
 type ComprehensiveAPIWithoutStreamingOrRaw = ComprehensiveAPIWithoutStreamingOrRaw' EmptyEndpoint
diff --git a/test/Servant/LinksSpec.hs b/test/Servant/LinksSpec.hs
--- a/test/Servant/LinksSpec.hs
+++ b/test/Servant/LinksSpec.hs
@@ -13,9 +13,9 @@
                  (Expectation, Spec, describe, it, shouldBe)
 
 import           Servant.API
+import           Servant.Links
 import           Servant.Test.ComprehensiveAPI
                  (comprehensiveAPIWithoutRaw)
-import           Servant.Links
 
 type TestApi =
   -- Capture and query params
@@ -26,6 +26,9 @@
   -- Flags
   :<|> "balls" :> QueryFlag "bouncy" :> QueryFlag "fast" :> Delete '[JSON] NoContent
 
+  -- Fragment
+  :<|> "say" :> Fragment String :> Get '[JSON] NoContent
+
   -- All of the verbs
   :<|> "get" :> Get '[JSON] NoContent
   :<|> "put" :> Put '[JSON] NoContent
@@ -75,6 +78,10 @@
                                          :> QueryFlag "fast" :> Delete '[JSON] NoContent)
         apiLink l1 True True `shouldBeLink` "balls?bouncy&fast"
         apiLink l1 False True `shouldBeLink` "balls?fast"
+
+    it "generates correct link for fragment" $ do
+        let l1 = Proxy :: Proxy ("say" :> Fragment String :> Get '[JSON] NoContent)
+        apiLink l1 "something" `shouldBeLink` "say#something"
 
     it "generates correct links for all of the verbs" $ do
         apiLink (Proxy :: Proxy ("get" :> Get '[JSON] NoContent)) `shouldBeLink` "get"
