diff --git a/Deadpan-DDP.cabal b/Deadpan-DDP.cabal
--- a/Deadpan-DDP.cabal
+++ b/Deadpan-DDP.cabal
@@ -1,5 +1,5 @@
 name:                Deadpan-DDP
-version:             0.2.1.1
+version:             0.3.0.1
 synopsis:            Write clients for Meteor's DDP Protocol
 description:         The Deadpan-DDP project includes a debugging-tool, as well as a general purpose library.
                      .
@@ -51,7 +51,7 @@
                        aeson, scientific, bytestring,
                        vector, convertible, lens,
                        network-uri, safe, mtl,
-                       containers, stm, transformers
+                       containers, stm, transformers, IfElse
   hs-source-dirs:      src
   default-language:    Haskell2010
 
@@ -62,6 +62,6 @@
                        aeson, scientific, bytestring,
                        vector, convertible, lens,
                        network-uri, safe, mtl,
-                       containers, stm, transformers
+                       containers, stm, transformers, IfElse
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,19 @@
 # Deadpan-DDP Change Log
 
+## 0.3.0.1
+
+* Added further callback implementations
+* Added test-app
+* Added documentation
+
+## 0.2.2.0
+
+* Completed adding RPC method call support
+
+## 0.2.1.1
+
+* Updated license file to include copyright info
+
 ## 0.2.1.0
 
 * Custom Show instance to render prettier output in debugging app [09c9876]
diff --git a/src/Web/DDP/Deadpan.hs b/src/Web/DDP/Deadpan.hs
--- a/src/Web/DDP/Deadpan.hs
+++ b/src/Web/DDP/Deadpan.hs
@@ -14,6 +14,8 @@
 
 module Web.DDP.Deadpan
   ( module Web.DDP.Deadpan
+  , module Web.DDP.Deadpan.DSL
+  , module Web.DDP.Deadpan.Callbacks
   , module Control.Monad
   , getURI
   , Error
@@ -24,7 +26,7 @@
 
 import Web.DDP.Deadpan.DSL
 import Web.DDP.Deadpan.Websockets
-import Web.DDP.Deadpan.Callbacks as C
+import Web.DDP.Deadpan.Callbacks
 
 import Data.Map
 import Control.Concurrent.STM
@@ -66,7 +68,7 @@
 pingClient :: IO (AppState Callback)
 pingClient = do
   values <- newTVarIO (ejobject [])
-  return $ AppState (const $ return ()) (Data.Map.singleton "ping" C.pingCallback) values
+  return $ AppState (const $ return ()) (Data.Map.singleton "ping" pingCallback) values
 
 
 -- | A client that logs all server sent messages, responds to pings
@@ -74,7 +76,7 @@
 loggingClient :: IO (AppState Callback)
 loggingClient = do
   values <- newTVarIO (ejobject [])
-  return $ AppState (liftIO . print) (Data.Map.singleton "ping" C.pingCallback) values
+  return $ AppState (liftIO . print) (Data.Map.singleton "ping" pingCallback) values
 
 
 -- | A client that responds to server collection messages.
diff --git a/src/Web/DDP/Deadpan/Callbacks.hs b/src/Web/DDP/Deadpan/Callbacks.hs
--- a/src/Web/DDP/Deadpan/Callbacks.hs
+++ b/src/Web/DDP/Deadpan/Callbacks.hs
@@ -16,6 +16,8 @@
 module Web.DDP.Deadpan.Callbacks where
 
 import Web.DDP.Deadpan.DSL
+import Control.Monad.State
+import Control.Monad.IfElse (awhen)
 import Control.Lens
 
 -- Old Stuff...
@@ -32,15 +34,45 @@
 
 -- Client Data Subscriptions
 
+
+{- |
+
+Initiate a subscription to a named collection on the server.
+
+Provide an id to refer to the subscription in future.
+
+@
+  sub (client -> server):
+    id:     string                        (an arbitrary client-determined
+                                              identifier for this subscription)
+    name:   string                        (the name of the subscription)
+    params: optional array of EJSON items (parameters to the subscription)
+@
+
+-}
 clientDataSub :: Text -> Text -> Maybe [ EJsonValue ] -> DeadpanApp ()
-clientDataSub _subid _name _params = undefined
+clientDataSub subid name Nothing
+  = sendMessage "sub" $ ejobject [("name",   ejstring name)
+                                 ,("id",     ejstring subid)]
+clientDataSub subid name (Just params)
+  = sendMessage "sub" $ ejobject [("name",   ejstring name)
+                                 ,("params", ejarray  params)
+                                 ,("id",     ejstring subid)]
 
 -- | Synonym for `clientDataSub`
 subscribe :: Text -> Text -> Maybe [ EJsonValue ] -> DeadpanApp ()
 subscribe = clientDataSub
 
+{- |
+Unsubscribe from an existing subscription indicated by its ID.
+
+@
+  unsub (client -> server):
+    id: string (the id passed to 'sub')
+@
+-}
 clientDataUnsub :: Text -> DeadpanApp ()
-clientDataUnsub _subid = undefined
+clientDataUnsub subid = sendMessage "unsub" $ ejobject [("id", ejstring subid)]
 
 -- | Synonym for `clientDataUnsub`
 unsubscribe :: Text -> DeadpanApp ()
@@ -59,8 +91,13 @@
       randomSeed: optional JSON value           (an arbitrary client-determined seed for pseudo-random generators)
   @
 -}
-clientRPCMethod :: Text -> Maybe [EJsonValue] -> Text -> Maybe EJsonValue -> DeadpanApp ()
-clientRPCMethod _method _params _rpcid _seed = undefined
+clientRPCMethod :: Text -> Maybe [EJsonValue] -> Text -> Maybe Text -> DeadpanApp ()
+clientRPCMethod method params rpcid seed = do
+  let msg = [("method", ejstring method), ("id", ejstring rpcid)]
+         &~ do awhen params $ \v -> modify (("params", ejarray  v) :)
+               awhen seed   $ \v -> modify (("seed",   ejstring v) :)
+
+  sendMessage "method" (ejobject msg)
 
 
 -- Server -->> Client
diff --git a/src/Web/DDP/Deadpan/DSL.hs b/src/Web/DDP/Deadpan/DSL.hs
--- a/src/Web/DDP/Deadpan/DSL.hs
+++ b/src/Web/DDP/Deadpan/DSL.hs
@@ -63,7 +63,7 @@
   ( module Web.DDP.Deadpan.DSL
   , module Data.EJson
   , module Data.EJson.Prism
-  , module Data.Text
+  , Text
   )
   where
 
