diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # Revision history for pushbullet-types
 
+## 0.4.0.2  -- 2018-02-11
+
+* Derive `ToHttpApiData` for `PushId`.
+
+## 0.4.0.1  -- 2018-02-08
+
+* Drop upper bounds on dependencies.
+
 ## 0.4.0.0  -- 2017-08-01
 
 * Make `body` field of link pushes optional. Many channel pushes do not include
diff --git a/pushbullet-types.cabal b/pushbullet-types.cabal
--- a/pushbullet-types.cabal
+++ b/pushbullet-types.cabal
@@ -1,15 +1,15 @@
--- Initial pushbullet-types.cabal generated by cabal init.  For further 
+-- Initial pushbullet-types.cabal generated by cabal init.  For further
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                pushbullet-types
-version:             0.4.0.0
+version:             0.4.0.2
 synopsis:            Datatypes used by the Pushbullet APIs
--- description:         
+-- description:
 license:             MIT
 license-file:        LICENSE
 author:              Jacob Thomas Errington
-maintainer:          hackage@mail.jerrington.me
-copyright:           Jacob Thomas Errington 2017
+maintainer:          pushbullet-hs@mail.jerrington.me
+copyright:           Jacob Thomas Errington 2017-2018
 category:            Web
 build-type:          Simple
 extra-source-files:  ChangeLog.md
@@ -17,12 +17,7 @@
 
 source-repository head
   type: git
-  location: https://github.com/tsani/pushbullet-types
-
-source-repository this
-  type: git
-  location: https://github.com/tsani/pushbullet-types/releases/tag/v0.4.0.0
-  tag: v0.4.0.0
+  location: https://github.com/tsani/pushbullet-hs
 
 library
   default-language:    Haskell2010
@@ -53,12 +48,12 @@
     Network.Pushbullet.Types.Time,
     Network.Pushbullet.Types.User
   build-depends:
-    aeson >=0.11 && <1.2,
-    base >=4.9 && <4.10,
-    http-api-data >=0.3 && <0.4,
-    microlens >=0.4 && <0.5,
-    microlens-th >=0.4 && <0.5,
-    scientific >=0.3 && <0.4,
-    text >=1.0 && <1.3,
-    time >=1.6 && <1.7,
-    unordered-containers >=0.2 && <0.3
+    aeson >=0.11,
+    base >=4.9 && <5,
+    http-api-data >=0.3,
+    microlens >=0.4,
+    microlens-th >=0.4,
+    scientific >=0.3,
+    text >=1.0,
+    time >=1.6,
+    unordered-containers >=0.2
diff --git a/src/Network/Pushbullet/Types.hs b/src/Network/Pushbullet/Types.hs
--- a/src/Network/Pushbullet/Types.hs
+++ b/src/Network/Pushbullet/Types.hs
@@ -6,6 +6,8 @@
 , Push(..)
 , PushData(..)
 , PushTarget(..)
+, PushSender(..)
+, PushReceiver(..)
 , simpleNewPush
 , ExistingPushes(..)
   -- * Ephemerals
diff --git a/src/Network/Pushbullet/Types/Push.hs b/src/Network/Pushbullet/Types/Push.hs
--- a/src/Network/Pushbullet/Types/Push.hs
+++ b/src/Network/Pushbullet/Types/Push.hs
@@ -6,6 +6,7 @@
 , PushDirection(..)
 , PushSender(..)
 , PushTarget(..)
+, PushReceiver(..)
 , PushData(..)
 , ExistingPushes(..)
 , simpleNewPush
@@ -20,6 +21,7 @@
 import Control.Applicative ( (<|>) )
 import Data.Aeson
 import Data.Text ( Text )
+import Web.HttpApiData ( ToHttpApiData )
 
 -- | A push. We reuse the same datatype for representing new pushes and
 -- existing pushes. The 'EqT' type family is used to enable fields selectively
@@ -52,7 +54,7 @@
 data PushSender
   = SentByUser
     { pushSenderUserId :: !UserId
-    , pushSenderClientId :: !ClientId
+    , pushSenderClientId :: !(Maybe ClientId)
     , pushSenderUserEmail :: !EmailAddress
     , pushSenderUserEmailNormalized :: !EmailAddress
     , pushSenderName :: !Name
@@ -65,7 +67,7 @@
 
 -- | Unique identifier for a push.
 newtype PushId = PushId Text
-  deriving (Eq, FromJSON, Show, ToJSON)
+  deriving (Eq, FromJSON, Show, ToJSON, ToHttpApiData)
 
 -- | The direction of a push.
 data PushDirection
@@ -96,11 +98,11 @@
     , pushUrl :: !Url
     }
   | FilePush
-    { pushFileBody :: !(Maybe Text)
+    { pushTitle :: !(Maybe Text)
+    , pushFileBody :: !(Maybe Text)
     , pushFileName :: !Text
     , pushFileType :: !MimeType
     , pushFileUrl :: !Url
-    , pushFileTitle :: !(EqT 'Existing s (Maybe Text))
     , pushImageUrl :: !(EqT 'Existing s (Maybe Url))
     , pushImageWidth :: !(EqT 'Existing s (Maybe Int))
     , pushImageHeight :: !(EqT 'Existing s (Maybe Int))
@@ -167,11 +169,11 @@
         <*> o .:? "title"
         <*> o .: "body"
       "file" -> pure FilePush
+        <*> o .:? "file_title"
         <*> o .:? "body"
         <*> o .: "file_name"
         <*> o .: "file_type"
         <*> o .: "file_url"
-        <*> o .:? "file_title"
         <*> o .:? "image_url"
         <*> o .:? "image_width"
         <*> o .:? "image_height"
@@ -188,7 +190,8 @@
     user <- o .:? "sender_iden"
     name <- o .:? "sender_name"
 
-    let u = SentByUser <$> user <*> client <*> email <*> emailNorm <*> name
+    let f x1 x2 x3 x4 = SentByUser x1 client x2 x3 x4
+    let u = f <$> user <*> email <*> emailNorm <*> name
     let c = SentByChannel <$> channel <*> name
     sender <- maybe (fail "push not sent by channel or by user") pure (u <|> c)
 
