diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -0,0 +1,73 @@
+Network.Metrics
+===============
+
+Table of Contents
+-----------------
+
+* [Usage](#usage)
+* [API](#api)
+* [GMetric](#gmetric)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+
+<a name="usage" />
+
+Usage
+-----
+
+Modules are intended to be import qualified if they need to be used in conjunction with each other.
+
+Supported Sinks:
+
+* `Network.Metrics.Ganglia`
+* `Network.Metrics.Graphite`
+* `Network.Metrics.Statsd`
+
+
+````haskell
+{-# LANGUAGE OverloadedStrings #-}
+
+import Network.Metrics.Graphite
+
+main = do
+    sink <- open "localhost" "1234"
+    push metric sink
+    close sink
+  where
+    metric = Metric Counter "name.space" "bucket" "1234" -- Creates graphite key: "name.space.bucket"
+````
+
+
+<a name="api" />
+
+API
+---
+
+Preliminary API documentation is available [on Hackage](http://hackage.haskell.org/package/network-metrics).
+
+> The API is currently in flux, and conversion between the universal `Metric` `Counter` `Gauge` `Timing` type to the respective sink types is not completed.
+
+
+<a name="gmetric" />
+
+GMetric
+-------
+
+A port of Ganglia's `gmetric` is built by default under the name `gmetric-haskell`.
+
+
+<a name="contribute" />
+
+Contribute
+----------
+
+For any problems, comments or feedback please create an issue [here on GitHub](github.com/brendanhay/network-metrics/issues).
+
+
+<a name="licence" />
+
+Licence
+-------
+
+Stetson is released under the [Mozilla Public License Version 2.0](http://www.mozilla.org/MPL/)
diff --git a/network-metrics.cabal b/network-metrics.cabal
--- a/network-metrics.cabal
+++ b/network-metrics.cabal
@@ -1,5 +1,5 @@
 name:               network-metrics
-version:            0.1.4
+version:            0.1.5
 synopsis:           Send metrics to Ganglia, Graphite, and statsd.
 license:            OtherLicense
 license-file:       LICENSE
diff --git a/src/Network/Metrics/Ganglia.hs b/src/Network/Metrics/Ganglia.hs
--- a/src/Network/Metrics/Ganglia.hs
+++ b/src/Network/Metrics/Ganglia.hs
@@ -11,32 +11,29 @@
 --
 
 module Network.Metrics.Ganglia (
-    -- * Exported types
+    -- * Exported Types
       Slope(..)
     , GangliaType(..)
     , GangliaMetric(..)
     , Ganglia(..)
 
-    -- * Default constructors
+    -- * Defaults
     , defaultMetric
 
-    -- * Socket Handle operations
-    , open
-
-    -- * Binary encoding
+    -- * Binary Encoding
     , putMetaData
     , putValue
 
-    -- -- * Network.Metrics.Internal re-exported types
+    -- * Sink Functions
+    , open
+    , MetricSink(push, close)
+
+    -- * Re-exports
     , Group
     , Bucket
     , Value
     , MetricType(..)
     , Metric(..)
-    , MetricSink(push)
-
-    -- * Network.Metrics.Internal operations
-    , close
     ) where
 
 import Control.Monad            (liftM)
@@ -54,7 +51,6 @@
 import qualified Data.ByteString.Char8      as BS
 import qualified Data.ByteString.Lazy.Char8 as BL
 
-
 -- | Allows gmetad and the PHP webfrontend to efficiently separate
 -- constant data metrics from volatile ones
 data Slope = Zero | Positive | Negative | Both | Unspecified
@@ -81,7 +77,8 @@
 instance Default GangliaMetric where
     def = defaultMetric
 
-data Ganglia = Ganglia Handle
+-- | A handle to a Ganglia sink
+data Ganglia = Ganglia Handle deriving (Show)
 
 instance MetricSink Ganglia where
     push m (Ganglia h) = hPush (encode m) h
@@ -91,7 +88,7 @@
 -- API
 --
 
--- | A default metric record
+-- | Sensible defaults for a GangliaMetric
 defaultMetric :: GangliaMetric
 defaultMetric = GangliaMetric
     { name  = ""
@@ -106,10 +103,11 @@
     , dmax  = 0
     }
 
+-- | Open a new Ganglia sink
 open :: String -> String -> IO Ganglia
 open host port = liftM Ganglia (hOpen Datagram host port)
 
--- | Metric metadata
+-- | Encode a GangliaMetric's metadata into a Binary.Put monad
 --
 -- The format for this can be found in either:
 -- * gm_protocol.x in the Ganglia 3.1 sources
@@ -125,7 +123,7 @@
     putUInt dmax
     putGroup group
 
--- | Metric value
+-- | Encode a GangliaMetric's value into a Binary.Put monad
 putValue :: GangliaMetric -> Put
 putValue m@GangliaMetric{..} = do
     putHeader 133 m -- 133 = string_msg
@@ -141,10 +139,14 @@
 bufferSize :: Integer
 bufferSize = 1500
 
+-- | Encode a metric into the Ganglia format
 encode :: Metric -> BL.ByteString
-encode (Metric _ g b v) = BL.concat $ map put [putMetaData, putValue]
+encode (Metric t g b v) = BL.concat $ map put [putMetaData, putValue]
   where
-    metric = defaultMetric { name  = b, group = g, value = v }
+    slope' = case t of
+        Counter -> Positive
+        _       -> Both
+    metric = defaultMetric { name  = b, group = g, value = v, slope = slope' }
     put f  = runPut $ f metric
 
 -- | Common headers for the metadata and value
diff --git a/src/Network/Metrics/Graphite.hs b/src/Network/Metrics/Graphite.hs
--- a/src/Network/Metrics/Graphite.hs
+++ b/src/Network/Metrics/Graphite.hs
@@ -11,19 +11,16 @@
 --
 
 module Network.Metrics.Graphite (
-    -- * Socket Handle operations
+    -- * Sink Functions
       open
+    , MetricSink(push, close)
 
-    -- * Network.Metrics.Internal re-exported types
+    -- * Re-exports
     , Group
     , Bucket
     , Value
     , MetricType(..)
     , Metric(..)
-    , MetricSink(push)
-
-    -- * Network.Metrics.Internal operations
-    , close
     ) where
 
 import Control.Monad            (liftM)
@@ -34,7 +31,8 @@
 import qualified Data.ByteString.Char8      as BS
 import qualified Data.ByteString.Lazy.Char8 as BL
 
-data Graphite = Graphite Handle
+-- | A handle to a Graphite sink
+data Graphite = Graphite Handle deriving (Show)
 
 instance MetricSink Graphite where
     push m (Graphite h) = encode m >>= flip hPush h
@@ -43,7 +41,7 @@
 -- API
 --
 
--- | Create a new disconnected socket handle for TCP communication
+-- | Open a new Graphite sink
 open :: String -> String -> IO Graphite
 open host port = liftM Graphite (hOpen Stream host port)
 
@@ -51,6 +49,7 @@
 -- Private
 --
 
+-- | Encode a metric into the Graphite format
 encode :: Metric -> IO BL.ByteString
 encode (Metric _ g b v) = liftM bstr getPOSIXTime
   where
diff --git a/src/Network/Metrics/Internal.hs b/src/Network/Metrics/Internal.hs
--- a/src/Network/Metrics/Internal.hs
+++ b/src/Network/Metrics/Internal.hs
@@ -11,7 +11,7 @@
 --
 
 module Network.Metrics.Internal (
-    -- * Exported types
+    -- * Exported Types
       Handle(..)
     , Group
     , Bucket
@@ -20,7 +20,7 @@
     , Metric(..)
     , MetricSink(..)
 
-    -- * Socket Handle operations
+    -- * Socket Handle Functions
     , hOpen
     , hClose
     , hPush
@@ -51,16 +51,18 @@
 -- | Concrete metric data type
 data Metric = Metric MetricType Group Bucket Value deriving (Show)
 
--- | Describes a sink resource which is held open for metric emission
+-- | Sink resource to write metrics to
 class MetricSink a where
+    -- ^ Write a metric to the sink.
     push  :: Metric -> a -> IO ()
+    -- ^ Close the sink, any subsequent writes will throw an error.
     close :: a -> IO ()
 
 --
 -- API
 --
 
--- | Create a new unconnected socket handle for UDP communication
+-- | Create a new socket handle (in a disconnected state) for UDP communication
 hOpen :: SocketType -> String -> String -> IO Handle
 hOpen typ host port = do
     (addr:_) <- getAddrInfo Nothing (Just host) (Just port)
@@ -71,7 +73,7 @@
 hClose :: Handle -> IO ()
 hClose (Handle sock _) = sClose sock
 
--- | Direct access for writing a bytestring to the socket handle
+-- | Direct access for writing a bytestring to a socket handle
 hPush :: BL.ByteString -> Handle -> IO ()
 hPush bstr (Handle sock addr) | BL.null bstr = return ()
                               | otherwise    = do
diff --git a/src/Network/Metrics/Statsd.hs b/src/Network/Metrics/Statsd.hs
--- a/src/Network/Metrics/Statsd.hs
+++ b/src/Network/Metrics/Statsd.hs
@@ -11,19 +11,16 @@
 --
 
 module Network.Metrics.Statsd (
-    -- * Socket Handle operations
+    -- * Sink Functions
       open
+    , MetricSink(push, close)
 
-    -- * Network.Metrics.Internal re-exported types
+    -- * Re-exports
     , Group
     , Bucket
     , Value
     , MetricType(..)
     , Metric(..)
-    , MetricSink(push)
-
-    -- * Network.Metrics.Internal operations
-    , close
     ) where
 
 import Control.Monad  (liftM)
@@ -34,6 +31,7 @@
 import qualified Data.ByteString.Char8      as BS
 import qualified Data.ByteString.Lazy.Char8 as BL
 
+-- | An internal record used to describe a Statsd metric
 data StatsdMetric = StatsdMetric
     { type'  :: MetricType
     , bucket :: BS.ByteString
@@ -41,9 +39,11 @@
     , rate   :: Double
     } deriving (Show)
 
+-- | The sample status of a metric
 data Sampled = Sampled | Exact | Ignore
 
-data Statsd = Statsd Handle
+-- | A handle to a Statsd sink
+data Statsd = Statsd Handle deriving (Show)
 
 instance MetricSink Statsd where
     push m (Statsd h) = encode m >>= flip hPush h
@@ -53,7 +53,7 @@
 -- API
 --
 
--- | Create a new disconnected socket handle for UDP communication
+-- | Open a new Statsd sink
 open :: String -> String -> IO Statsd
 open host port = liftM Statsd (hOpen Datagram host port)
 
@@ -61,6 +61,7 @@
 -- Private
 --
 
+-- | Encode a metric into the Statsd format
 encode :: Metric -> IO BL.ByteString
 encode (Metric t g b v) = liftM bstr (randomRIO (0.0, 1.0))
   where
