diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+0.4.0.3
+=======
+
+- Support http-2-5.3
+- Support data-default >= 0.8
+- Use empty string instead of undefined in server id
+
 0.4.0.2
 =======
 
diff --git a/push-notify-apn.cabal b/push-notify-apn.cabal
--- a/push-notify-apn.cabal
+++ b/push-notify-apn.cabal
@@ -1,5 +1,5 @@
 name:                push-notify-apn
-version:             0.4.0.2
+version:             0.4.0.3
 synopsis:            Send push notifications to mobile iOS devices
 description:
     push-notify-apn is a library and command line utility that can be used to send
@@ -29,8 +29,9 @@
                      , bytestring
                      , containers
                      , data-default
-                     , http2 >= 3.0 && <= 5.1
+                     , http2 >= 3.0 && <= 5.4
                      , http2-client >= 0.10.0.2
+                     , http-types >= 0.12.4
                      , lifted-base
                      , mtl
                      , random
diff --git a/src/Network/PushNotify/APN.hs b/src/Network/PushNotify/APN.hs
--- a/src/Network/PushNotify/APN.hs
+++ b/src/Network/PushNotify/APN.hs
@@ -37,6 +37,8 @@
     , clearAlertMessage
     , clearBadge
     , clearCategory
+    , setMutableContent
+    , clearMutableContent
     , clearSound
     , addSupplementalField
     , closeSession
@@ -91,6 +93,7 @@
 
 import qualified Network.HPACK                        as HTTP2
 import qualified Network.HTTP2.Frame                  as HTTP2
+import qualified Network.HTTP.Types                   as HTTP
 
 -- | A session that manages connections to Apple's push notification service
 data ApnSession = ApnSession
@@ -138,7 +141,7 @@
 -- | Exceptional responses to a send request
 data ApnException = ApnExceptionHTTP ErrorCode
                   | ApnExceptionJSON String
-                  | ApnExceptionMissingHeader HTTP2.HeaderName
+                  | ApnExceptionMissingHeader HTTP.HeaderName
                   | ApnExceptionUnexpectedResponse
                   | ApnExceptionConnectionClosed
                   | ApnExceptionSessionClosed
@@ -189,11 +192,13 @@
     -- in the Library/Sounds directory of the app.
     , jamCategory :: !(Maybe Text)
     -- ^ The category of the notification. Must be registered by the app beforehand.
+    , jamMutableContent :: !(Maybe Int)
+    -- ^ Whether the message has mutable content.
     } deriving (Generic, Show)
 
 -- | Create an empty apn message
 emptyMessage :: JsonApsMessage
-emptyMessage = JsonApsMessage Nothing Nothing Nothing Nothing
+emptyMessage = JsonApsMessage Nothing Nothing Nothing Nothing Nothing
 
 -- | Set a sound for an APN message
 setSound
@@ -231,6 +236,24 @@
     -- ^ The modified message
 clearCategory a = a { jamCategory = Nothing }
 
+-- | Set the mutable content part of an APN message
+setMutableContent
+    :: Int
+    -- ^ The number of mutable content to set
+    -> JsonApsMessage
+    -- ^ The message to modify
+    -> JsonApsMessage
+    -- ^ The modified message
+setMutableContent i a = a { jamMutableContent = Just i }
+
+-- | Clear the mutable content part of an APN message
+clearMutableContent
+    :: JsonApsMessage
+    -- ^ The message to modify
+    -> JsonApsMessage
+    -- ^ The modified message
+clearMutableContent a = a { jamMutableContent = Nothing }
+
 -- | Set the badge part of an APN message
 setBadge
     :: Int
@@ -305,11 +328,17 @@
 
 instance ToJSON JsonApsMessage where
     toJSON     = genericToJSON     defaultOptions
-        { fieldLabelModifier = drop 3 . map toLower }
+        { fieldLabelModifier = \s -> case drop 3 s of
+            "MutableContent" -> "mutable-content"
+            other -> map toLower other
+        }
 
 instance FromJSON JsonApsMessage where
     parseJSON = genericParseJSON defaultOptions
-        { fieldLabelModifier = drop 3 . map toLower }
+        { fieldLabelModifier = \s -> case drop 3 s of
+            "mutable-content" -> "MutableContent"
+            other -> map toLower other
+        }
 
 -- | A push notification message
 data JsonAps
@@ -506,16 +535,16 @@
     clip <- case (aciUseJWT aci) of
         True -> do
           castore <- getSystemCertificateStore
-          let clip = ClientParams
+          let clip = (defaultParamsClient (T.unpack hostname) "")
                   { clientUseMaxFragmentLength=Nothing
-                  , clientServerIdentification=(T.unpack hostname, undefined)
                   , clientUseServerNameIndication=True
                   , clientWantSessionResume=Nothing
                   , clientShared=def
                       { sharedCAStore=castore }
                   , clientHooks=def
                       { onCertificateRequest = const . return $ Nothing }
-                  , clientDebug=DebugParams { debugSeed=Nothing, debugPrintSeed=const $ return (), debugVersionForced=Nothing, debugKeyLogger=const $ return () }
+                  , clientDebug=def
+                      { debugSeed=Nothing, debugPrintSeed=const $ return (), debugVersionForced=Nothing, debugKeyLogger=const $ return () }
                   , clientSupported=def
                       { supportedVersions=[ TLS12 ]
                       , supportedCiphers=ciphersuite_strong }
@@ -533,15 +562,15 @@
               shared      = def { sharedCredentials = credentials
                                 , sharedCAStore=castore }
 
-              clip = ClientParams
+              clip = (defaultParamsClient (T.unpack hostname) "")
                   { clientUseMaxFragmentLength=Nothing
-                  , clientServerIdentification=(T.unpack hostname, undefined)
                   , clientUseServerNameIndication=True
                   , clientWantSessionResume=Nothing
                   , clientShared=shared
                   , clientHooks=def
                       { onCertificateRequest=const . return . Just $ credential }
-                  , clientDebug=DebugParams { debugSeed=Nothing, debugPrintSeed=const $ return (), debugVersionForced=Nothing, debugKeyLogger=const $ return () }
+                  , clientDebug=def
+                      { debugSeed=Nothing, debugPrintSeed=const $ return (), debugVersionForced=Nothing, debugKeyLogger=const $ return () }
                   , clientSupported=def
                       { supportedVersions=[ TLS12 ]
                       , supportedCiphers=ciphersuite_strong }
@@ -710,10 +739,10 @@
                     eitherDecode body
                         >>= parseEither (\obj -> ctor <$> obj .: "reason")
 
-        getHeaderEx :: HTTP2.HeaderName -> [HTTP2.Header] -> HTTP2.HeaderValue
+        getHeaderEx :: HTTP.HeaderName -> [HTTP2.Header] -> ByteString
         getHeaderEx name headers = fromMaybe (throw $ ApnExceptionMissingHeader name) (DL.lookup name headers)
 
-        defaultHeaders :: Text -> ByteString -> ByteString -> [(HTTP2.HeaderName, ByteString)]
+        defaultHeaders :: Text -> ByteString -> ByteString -> [(HTTP.HeaderName, ByteString)]
         defaultHeaders hostname token topic = [ ( ":method", "POST" )
                                               , ( ":scheme", "https" )
                                               , ( ":authority", TE.encodeUtf8 hostname )
diff --git a/test/Network/PushNotify/APNSpec.hs b/test/Network/PushNotify/APNSpec.hs
--- a/test/Network/PushNotify/APNSpec.hs
+++ b/test/Network/PushNotify/APNSpec.hs
@@ -16,6 +16,7 @@
             "category" .= Null,
             "sound"    .= Null,
             "badge"    .= Null,
+            "mutable-content" .= Null,
             "alert"    .= object [
               "title" .= String "hello",
               "body"  .= String "world"
@@ -27,6 +28,7 @@
             "category" .= Null,
             "sound"    .= Null,
             "badge"    .= Null,
+            "mutable-content" .= Null,
             "alert"    .= object [ "body"  .= String "hello world" ]
           ]
 
