diff --git a/hzulip.cabal b/hzulip.cabal
--- a/hzulip.cabal
+++ b/hzulip.cabal
@@ -1,5 +1,5 @@
 name:                hzulip
-version:             0.2.0.3
+version:             0.3.0.0
 synopsis:            A haskell wrapper for the Zulip API.
 description:         This a Zulip API wrapper for Haskell.
 homepage:            https://github.com/yamadapc/hzulip
diff --git a/src/HZulip.hs b/src/HZulip.hs
--- a/src/HZulip.hs
+++ b/src/HZulip.hs
@@ -6,11 +6,15 @@
               , ZulipClient(..)
               , EventCallback
               , defaultBaseUrl
+              , eventTypes
               , getEvents
               , newZulip
               , onNewEvent
+              , onNewMessage
               , registerQueue
               , sendMessage
+              , sendPrivateMessage
+              , sendStreamMessage
               )
   where
 
@@ -39,6 +43,11 @@
 defaultBaseUrl = "https://api.zulip.com/v1"
 
 -- |
+-- The list of all avaiable event types
+eventTypes :: [String]
+eventTypes = ["message", "subscriptions", "realm_user", "pointer"]
+
+-- |
 -- This wraps `POST https://api.zulip.com/v1/messages` with a nicer root
 -- API. Simpler helpers for each specific case of this somewhat overloaded
 -- endpoint will also be provided in the future.
@@ -61,6 +70,18 @@
         else fail $ responseMsg body
 
 -- |
+-- Helper for sending private messages. Takes the list of recipients and
+-- the message's content.
+sendPrivateMessage :: ZulipClient -> [String] -> String -> IO Int
+sendPrivateMessage z mrs = sendMessage z "private" mrs ""
+
+-- |
+-- Helper for sending stream messages. Takes the stream name, the subject
+-- and the message.
+sendStreamMessage :: ZulipClient -> String -> String -> String -> IO Int
+sendStreamMessage z s = sendMessage z "stream" [s]
+
+-- |
 -- This registers a new event queue with the zulip API. It's a lower level
 -- function, which shouldn't be used unless you know what you're doing. It
 -- takes a `ZulipClient`, a list of names of the events you want to listen
@@ -105,17 +126,27 @@
         else fail $ responseMsg body
 
 -- |
--- Registers an event callback for all events and keeps executing it over
--- events as they come in. Will loop forever
-onNewEvent :: ZulipClient -> Bool -> EventCallback -> IO ()
-onNewEvent z b f = do
-    q <- registerQueue z ["message"] b
+-- Registers an event callback for specified events and keeps executing it
+-- over events as they come in. Will loop forever
+onNewEvent :: ZulipClient -> [String] -> EventCallback -> IO ()
+onNewEvent z etypes f = do
+    q <- registerQueue z etypes False
     handle (tryAgain q) (loop q)
   where tryAgain :: Queue -> SomeException -> IO ()
         tryAgain q = const $ threadDelay 1000000 >> loop q
         loop q = getEvents z q False >>=
                  \(q', evts) -> mapM_ f evts >>
                                 loop q'
+
+-- |
+-- Registers a callback to be executed whenever a message comes in. Will
+-- loop forever
+onNewMessage :: ZulipClient -> MessageCallback -> IO ()
+onNewMessage z f = onNewEvent z ["message"] $ \evt ->
+  -- I could just pattern match here, as I did in other places and simply
+  -- expect the Zulip API not to give us correct responses, but I think
+  -- this is more reasonable.
+  maybe (return ()) f (eventMessage evt)
 
 -- Private functions:
 -------------------------------------------------------------------------------
diff --git a/src/HZulip/Types.hs b/src/HZulip/Types.hs
--- a/src/HZulip/Types.hs
+++ b/src/HZulip/Types.hs
@@ -70,6 +70,7 @@
                        , messageAvatarUrl        :: String
                        , messageTimestamp        :: Int
 
+                       -- See the comment on the `FromJSON Message` instance.
                        -- , messageDisplayRecipient :: Either String [User]
 
                        , messageSender           :: User
@@ -91,6 +92,8 @@
                            o .: "avatar_url"        <*>
                            o .: "timestamp"         <*>
 
+                           -- I don't know if there's currently a way to
+                           -- parse `Either` types using `Data.Aeson`.
                            -- o .: "display_recipient" <*>
 
                            (User <$>
@@ -137,3 +140,7 @@
 -- |
 -- The root type for Event callbacks
 type EventCallback = Event -> IO ()
+
+-- |
+-- Type for message callbacks
+type MessageCallback = Message -> IO ()
