diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Changelog for notion-client
 
+## 0.1.0.1 (2026-03-29)
+
+### Bug Fixes
+* Export `UUID` constructor from `Notion.V1.Common` for pattern matching
+* Fix `PropertyItem` parsing for rollup, formula, and relation property types
+* Fix license field in README from BSD-3-Clause to MIT
+
+### Other Changes
+* Add `ToJSON` instances for `UserObject`, `BlockObject`, `PageObject`, and related types
+
 ## 0.1.0.0 (2026-02-28)
 
 * Initial release
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -111,4 +111,4 @@
 
 ## License
 
-BSD-3-Clause
+MIT
diff --git a/notion-client.cabal b/notion-client.cabal
--- a/notion-client.cabal
+++ b/notion-client.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.4
 name:               notion-client
-version:            0.1.0.0
+version:            0.1.0.1
 synopsis:           Type-safe Haskell client for the Notion API
 description:
   This package provides comprehensive and type-safe bindings
diff --git a/src/Notion/Prelude.hs b/src/Notion/Prelude.hs
--- a/src/Notion/Prelude.hs
+++ b/src/Notion/Prelude.hs
@@ -4,6 +4,7 @@
     stripPrefix,
     labelModifier,
     parseISO8601,
+    posixToISO8601,
 
     -- * Re-exports
     module Data.Aeson,
@@ -127,3 +128,7 @@
       Nothing -> fail $ "Failed to parse ISO8601 timestamp: " <> str
   where
     str = unpack text
+
+-- | Convert POSIXTime to an ISO8601 timestamp string
+posixToISO8601 :: POSIXTime -> Text
+posixToISO8601 = pack . ISO8601.iso8601Show . Time.posixSecondsToUTCTime
diff --git a/src/Notion/V1/Blocks.hs b/src/Notion/V1/Blocks.hs
--- a/src/Notion/V1/Blocks.hs
+++ b/src/Notion/V1/Blocks.hs
@@ -11,7 +11,8 @@
   )
 where
 
-import Data.Aeson ((.:))
+import Data.Aeson ((.:), (.=))
+import Data.Aeson qualified as Aeson
 import Data.Aeson.Key qualified as Key
 import Notion.Prelude
 import Notion.V1.Common (BlockID, ObjectType (..), Parent)
@@ -54,6 +55,22 @@
       object <- o .: "object"
       return BlockObject {..}
     _ -> fail "Expected object for BlockObject"
+
+instance ToJSON BlockObject where
+  toJSON BlockObject {..} =
+    Aeson.object
+      [ "id" .= id,
+        "parent" .= parent,
+        "created_time" .= posixToISO8601 createdTime,
+        "last_edited_time" .= posixToISO8601 lastEditedTime,
+        "created_by" .= createdBy,
+        "last_edited_by" .= lastEditedBy,
+        "has_children" .= hasChildren,
+        "archived" .= archived,
+        "type" .= type_,
+        Key.fromText type_ .= content,
+        "object" .= object
+      ]
 
 -- | Block content for update
 newtype BlockContent = BlockContent
diff --git a/src/Notion/V1/Common.hs b/src/Notion/V1/Common.hs
--- a/src/Notion/V1/Common.hs
+++ b/src/Notion/V1/Common.hs
@@ -1,7 +1,7 @@
 -- | Common Notion API types
 module Notion.V1.Common
   ( -- * Common types
-    UUID,
+    UUID (..),
     BlockID,
     ObjectType (..),
     Parent (..),
diff --git a/src/Notion/V1/Pages.hs b/src/Notion/V1/Pages.hs
--- a/src/Notion/V1/Pages.hs
+++ b/src/Notion/V1/Pages.hs
@@ -18,12 +18,11 @@
   )
 where
 
-import Data.Aeson (Object, Value, (.:), (.:?), (.=))
+import Data.Aeson ((.:), (.:?), (.=))
 import Data.Aeson qualified as Aeson
+import Data.Aeson.Key qualified as Key
 import Data.Aeson.KeyMap qualified as KeyMap
-import Data.Char qualified as Char
-import Data.String (fromString)
-import Notion.Prelude
+import Notion.Prelude hiding (Number)
 import Notion.V1.Common (Cover, Icon, ObjectType (..), Parent, UUID)
 import Notion.V1.Users (UserReference)
 
@@ -69,6 +68,24 @@
       return PageObject {..}
     _ -> fail "Expected object for PageObject"
 
+instance ToJSON PageObject where
+  toJSON PageObject {..} =
+    Aeson.object
+      [ "id" .= id,
+        "created_time" .= posixToISO8601 createdTime,
+        "last_edited_time" .= posixToISO8601 lastEditedTime,
+        "created_by" .= createdBy,
+        "last_edited_by" .= lastEditedBy,
+        "cover" .= cover,
+        "icon" .= icon,
+        "parent" .= parent,
+        "archived" .= archived,
+        "in_trash" .= inTrash,
+        "properties" .= properties,
+        "url" .= url,
+        "object" .= object
+      ]
+
 -- | Create a page request
 data CreatePage = CreatePage
   { parent :: Parent,
@@ -154,8 +171,54 @@
   deriving stock (Generic, Show)
 
 instance FromJSON PropertyItem where
-  parseJSON = genericParseJSON aesonOptions {fieldLabelModifier = \s -> if s == "type_" then "type" else labelModifier s}
+  parseJSON = \case
+    Object o -> do
+      id <- o .: "id"
+      type_ <- o .: "type"
+      -- The Notion API stores the property value under a type-specific key
+      -- (e.g., "title", "select", "rich_text"), not under a generic "value" key.
+      let typeKey = Key.fromText (propertyTypeToKey type_)
+          value = KeyMap.lookup typeKey o >>= \v -> Just v
+      return PropertyItem {..}
+    _ -> fail "Expected object for PropertyItem"
 
+instance ToJSON PropertyItem where
+  toJSON PropertyItem {..} =
+    let base = ["id" .= id, "type" .= type_]
+        typeKey = Key.fromText (propertyTypeToKey type_)
+        valueField = case value of
+          Just v -> [typeKey .= v]
+          Nothing -> []
+     in Aeson.object (base <> valueField)
+
+-- | Map a PropertyValueType to the JSON key the Notion API uses for its value
+propertyTypeToKey :: PropertyValueType -> Text
+propertyTypeToKey = \case
+  Title -> "title"
+  RichText -> "rich_text"
+  Number -> "number"
+  Select -> "select"
+  MultiSelect -> "multi_select"
+  Date -> "date"
+  People -> "people"
+  Files -> "files"
+  Checkbox -> "checkbox"
+  Url -> "url"
+  Email -> "email"
+  PhoneNumber -> "phone_number"
+  Formula -> "formula"
+  Relation -> "relation"
+  Rollup -> "rollup"
+  CreatedTime -> "created_time"
+  CreatedBy -> "created_by"
+  LastEditedTime -> "last_edited_time"
+  LastEditedBy -> "last_edited_by"
+  Status -> "status"
+  UniqueId -> "unique_id"
+  Place -> "place"
+  Button -> "button"
+  Verification -> "verification"
+
 -- | Property value types
 data PropertyValueType
   = Title
@@ -182,7 +245,7 @@
   | Place
   | Button
   | Verification
-  deriving stock (Generic, Show)
+  deriving stock (Eq, Generic, Show)
 
 instance FromJSON PropertyValueType where
   parseJSON = genericParseJSON aesonOptions
diff --git a/src/Notion/V1/Users.hs b/src/Notion/V1/Users.hs
--- a/src/Notion/V1/Users.hs
+++ b/src/Notion/V1/Users.hs
@@ -94,6 +94,9 @@
     Object o -> UserReference <$> o .: "id" <*> o .: "object"
     _ -> fail "Expected object for UserReference"
 
+instance ToJSON UserReference where
+  toJSON = genericToJSON aesonOptions
+
 -- | Servant API
 type API =
   "users"
