diff --git a/github-post-receive.cabal b/github-post-receive.cabal
--- a/github-post-receive.cabal
+++ b/github-post-receive.cabal
@@ -1,12 +1,11 @@
 name:                github-post-receive
-version:             1.1.0.0
+version:             1.2.0.0
 synopsis:            GitHub webhooks library
 description:         This is a library to construct github webhooks servers.
                      .
                      Currently, this library supports following events:
                      .
                      * push
-                     .
                      * status
 homepage:            https://github.com/amutake/github-post-receive
 license:             BSD3
diff --git a/src/Github/PostReceive/Types.hs b/src/Github/PostReceive/Types.hs
--- a/src/Github/PostReceive/Types.hs
+++ b/src/Github/PostReceive/Types.hs
@@ -14,17 +14,21 @@
     , StatusCommit (..)
     , SimpleStatusCommit (..)
     , Tree (..)
-    , Or (..)
-    , toEither
+    , Url
+    , HashValue
+    , DateString
       -- Re-exports
     , EmailAddress
     ) where
 
 import Control.Applicative ((<$>), (<*>), pure, (<|>))
-import Data.Aeson (Value (..), FromJSON (..), (.:), (.:?))
+import Data.Aeson (Value (..), FromJSON (..), (.:), (.:?), Object)
+import Data.Aeson.Types (Parser)
+import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as B
 import Data.Text (Text)
 import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
 import Data.Typeable (Typeable)
 import Text.Email.Validate (EmailAddress, emailAddress)
 
@@ -38,12 +42,12 @@
 
 data PushEvent = PushEvent
     { pushEventRef :: Text
-    , pushEventBefore :: Text
-    , pushEventAfter :: Text
+    , pushEventBefore :: HashValue
+    , pushEventAfter :: HashValue
     , pushEventCreated :: Bool
     , pushEventDeleted :: Bool
     , pushEventForced :: Bool
-    , pushEventBaseRef :: Maybe Text
+    , pushEventBaseRef :: Maybe HashValue
     , pushEventCompare :: Url
     , pushEventCommits :: [Commit]
     , pushEventHeadCommit :: Commit
@@ -71,7 +75,7 @@
 
 data StatusEvent = StatusEvent
     { statusEventId :: Int
-    , statusEventSHA :: Text
+    , statusEventSha :: HashValue
     , statusEventName :: Text
     , statusEventTargetUrl :: Url
     , statusEventContext :: Text
@@ -79,8 +83,8 @@
     , statusEventState :: Text
     , statusEventCommit :: StatusCommit
     , statusEventBranches :: [Branch]
-    , statusEventCreatedAt :: Text -- TODO: Change to date type
-    , statusEventUpdatedAt :: Text -- TODO: Change to date type
+    , statusEventCreatedAt :: DateString -- TODO: Change to date type
+    , statusEventUpdatedAt :: DateString -- TODO: Change to date type
     , statusEventRepository :: Repository
     , statusEventSender :: User
     } deriving (Show, Eq, Typeable)
@@ -103,10 +107,10 @@
     parseJSON _ = fail "StatusEvent must be an object"
 
 data Commit = Commit
-    { commitId :: Text
+    { commitId :: HashValue
     , commitDistinct :: Bool
     , commitMessage :: Text
-    , commitTimestamp :: Text
+    , commitTimestamp :: DateString
     , commitUrl :: Url
     , commitAuthor :: SimpleUser
     , commitCommitter :: SimpleUser
@@ -133,13 +137,13 @@
     { repoId :: Int
     , repoName :: Text
     , repoFullName :: Text
-    , repoOwner :: Or SimpleUser User
+    , repoOwner :: Either SimpleUser User
     , repoPrivate :: Bool
     , repoHtmlUrl :: Url
     , repoDescription :: Text
     , repoFork :: Bool
       -- urls
-    , repoUrl :: Text
+    , repoUrl :: Url
     , repoForksUrl :: Url
     , repoKeysUrl :: Url
     , repoCollaboratorsUrl :: Url
@@ -175,9 +179,9 @@
     , repoLabelsUrl :: Url
     , repoReleasesUrl :: Url
       -- date
-    , repoCreatedAt :: Or Int Text -- Int or DateString
-    , repoUpdatedAt :: Text
-    , repoPushedAt :: Or Int Text -- Int or DateString
+    , repoCreatedAt :: Either Int DateString -- Int or DateString
+    , repoUpdatedAt :: DateString
+    , repoPushedAt :: Either Int DateString -- Int or DateString
     , repoGitUrl :: Url
     , repoSshUrl :: Url
     , repoCloneUrl :: Url
@@ -207,7 +211,7 @@
         <$> o .: "id"
         <*> o .: "name"
         <*> o .: "full_name"
-        <*> o .: "owner"
+        <*> o .:| "owner"
         <*> o .: "private"
         <*> o .: "html_url"
         <*> o .: "description"
@@ -247,9 +251,9 @@
         <*> o .: "notifications_url"
         <*> o .: "labels_url"
         <*> o .: "releases_url"
-        <*> o .: "created_at"
+        <*> o .:| "created_at"
         <*> o .: "updated_at"
-        <*> o .: "pushed_at"
+        <*> o .:| "pushed_at"
         <*> o .: "git_url"
         <*> o .: "ssh_url"
         <*> o .: "clone_url"
@@ -318,7 +322,7 @@
     { simpleUserName :: Text
     , simpleUserEmail :: Maybe EmailAddress
     , simpleUserUsername :: Maybe Text
-    , simpleUserDate :: Maybe Text
+    , simpleUserDate :: Maybe DateString
     } deriving (Show, Eq, Typeable)
 
 instance FromJSON SimpleUser where
@@ -335,6 +339,10 @@
         Nothing -> fail "failed to parse EmailAddress"
     parseJSON _ = fail "EmailAddress must be a text"
 
+instance FromJSON B.ByteString where
+    parseJSON (String t) = pure (T.encodeUtf8 t)
+    parseJSON _ = fail "ByteString must be a text"
+
 data Branch = Branch
     { branchName :: Text
     , branchCommit :: SimpleCommit
@@ -347,7 +355,7 @@
     parseJSON _ = fail "Branch must be an object"
 
 data SimpleCommit = SimpleCommit
-    { simpleCommitSha :: Text
+    { simpleCommitSha :: HashValue
     , simpleCommitUrl :: Url
     , simpleCommitHtmlUrl :: Maybe Url
     } deriving (Show, Eq, Typeable)
@@ -361,7 +369,7 @@
 
 -- | used in StatusEvent
 data StatusCommit = StatusCommit
-    { statusCommitSHA :: Text
+    { statusCommitSha :: HashValue
     , statusCommitCommit :: SimpleStatusCommit
     , statusCommitUrl :: Url
     , statusCommitHtmlUrl :: Url
@@ -403,7 +411,7 @@
     parseJSON _ = fail "SimpleStatusCommit must be an object"
 
 data Tree = Tree
-    { treeSHA :: Text
+    { treeSha :: HashValue
     , treeUrl :: Url
     } deriving (Show, Eq, Typeable)
 
@@ -413,8 +421,12 @@
         <*> o .: "url"
     parseJSON _ = fail "Tree must be an object"
 
-type Url = Text
+type Url = ByteString
 
+type HashValue = ByteString
+
+type DateString = ByteString
+
 -- | Or a b represents a or b
 -- The reason why we don't use Either type is that Either Int String type parses { "left": 1 } or { "right": "foo" }, but we want to parse 1 or "foo".
 data Or a b = L a | R b deriving (Show, Eq, Typeable)
@@ -422,6 +434,8 @@
 instance (FromJSON a, FromJSON b) => FromJSON (Or a b) where
     parseJSON v = L <$> parseJSON v <|> R <$> parseJSON v
 
-toEither :: Or a b -> Either a b
-toEither (L a) = Left a
-toEither (R b) = Right b
+(.:|) :: (FromJSON a, FromJSON b) => Object -> Text -> Parser (Either a b)
+obj .:| key = toEither <$> (obj .: key)
+  where
+    toEither (L a) = Left a
+    toEither (R b) = Right b
