diff --git a/src/Rollbar/API.hs b/src/Rollbar/API.hs
new file mode 100644
--- /dev/null
+++ b/src/Rollbar/API.hs
@@ -0,0 +1,172 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+{-|
+    Module      : Rollbar.API
+    Description : Codifies Rollbar's API
+    Copyright   : (c) Hardy Jones, 2017
+    License     : BSD3
+    Maintainer  : jones3.hardy@gmail.com
+    Stability   : experimental
+
+    Provides functions for communicating with Rollbar through the public API.
+
+    See Rollbar's <https://rollbar.com/docs/api/ API> for more details.
+-}
+module Rollbar.API
+    ( -- * Helpful functions
+      -- | These functions are probably what you want most of the time.
+      itemsPOST
+    , itemsPOST'
+    , itemsPOSTRaw
+    , itemsPOSTRaw'
+    , makeRequest
+    -- * Response data types
+    , ItemsPOSTResponse(..)
+    , ItemsPOSTErrorMessage(..)
+    , ItemsPOSTSuccessResult(..)
+    -- * Impure functions
+    -- | Use with caution.
+    , itemsPOSTWithException
+    ) where
+
+import Control.Monad.IO.Class (MonadIO)
+
+import Data.Aeson
+    ( FromJSON(parseJSON)
+    , SumEncoding(UntaggedValue)
+    , ToJSON
+    , defaultOptions
+    , fieldLabelModifier
+    , genericParseJSON
+    , sumEncoding
+    )
+import Data.Text  (Text)
+
+import GHC.Generics (Generic)
+
+import Network.HTTP.Client
+    ( Manager
+    , Request(host, method, path, port, secure)
+    , Response
+    , defaultRequest
+    , setRequestIgnoreStatus
+    )
+import Network.HTTP.Simple
+    ( JSONException
+    , httpJSON
+    , httpJSONEither
+    , setRequestBodyJSON
+    , setRequestManager
+    )
+
+import Rollbar.Item (Item, RemoveHeaders, UUID4)
+
+-- | The response received from sending an 'Rollbar.Item.Item' to Rollbar.
+data ItemsPOSTResponse
+    = ItemsPOSTSuccess
+        { err_ItemsPOSTSuccess    :: Int
+        -- ^ This `err` field is always 0.
+        , result_ItemsPOSTSuccess :: ItemsPOSTSuccessResult
+        -- ^ The part you probably care about.
+        }
+    | ItemsPOSTError
+        { err_ItemsPOSTError     :: Int
+        -- ^ This `err` field is always 1.
+        , message_ItemsPOSTError :: Text
+        -- ^ A human-readable message describing the error.
+        }
+    deriving (Eq, Generic, Show)
+
+instance FromJSON ItemsPOSTResponse where
+    parseJSON = genericParseJSON defaultOptions
+        { fieldLabelModifier = takeWhile (/= '_')
+        , sumEncoding = UntaggedValue
+        }
+
+-- | The successful response from sending an 'Rollbar.Item.Item' to Rollbar.
+newtype ItemsPOSTSuccessResult
+    = ItemsPOSTSuccessResult
+        { uuid :: UUID4
+        -- ^ 'Rollbar.Item.UUID4' of the item.
+        --   Matches sent 'Rollbar.Item.UUID4' or generated by Rollbar if missing.
+        }
+    deriving (Eq, FromJSON, Generic, Show)
+
+-- | The human readable error message from sending an 'Rollbar.Item.Item' to Rollbar.
+newtype ItemsPOSTErrorMessage
+    = ItemsPOSTErrorMessage Text
+    deriving (Eq, FromJSON, Generic, Show)
+
+-- | Sends an 'Rollbar.Item.Item' off to Rollbar.
+--
+--   Creates a new 'Network.HTTP.Client.Manager' to send off the request.
+itemsPOST
+    :: (MonadIO f, RemoveHeaders b, ToJSON a)
+    => Item a b
+    -> f (Response (Either JSONException ItemsPOSTResponse))
+itemsPOST = itemsPOSTRaw
+
+-- | Sends an 'Rollbar.Item.Item' off to Rollbar.
+itemsPOST'
+    :: (MonadIO f, RemoveHeaders b, ToJSON a)
+    => Manager
+    -> Item a b
+    -> f (Response (Either JSONException ItemsPOSTResponse))
+itemsPOST' = itemsPOSTRaw'
+
+-- | Sends an 'Rollbar.Item.Item' off to Rollbar.
+--
+--   Creates a new 'Network.HTTP.Client.Manager' to send off the request.
+--   Makes no claims about what you get back.
+itemsPOSTRaw
+    :: (FromJSON c, MonadIO f, RemoveHeaders b, ToJSON a)
+    => Item a b
+    -> f (Response (Either JSONException c))
+itemsPOSTRaw = httpJSONEither . makeRequest
+
+-- | Sends an 'Rollbar.Item.Item' off to Rollbar.
+--
+--   Makes no claims about what you get back.
+itemsPOSTRaw'
+    :: (FromJSON c, MonadIO f, RemoveHeaders b, ToJSON a)
+    => Manager
+    -> Item a b
+    -> f (Response (Either JSONException c))
+itemsPOSTRaw' manager = httpJSONEither . setRequestManager manager . makeRequest
+
+-- | Sends an 'Rollbar.Item.Item' off to Rollbar.
+--
+--   Creates a new 'Network.HTTP.Client.Manager' to send off the request.
+--   Makes no claims about what you get back.
+--   Throws a 'Network.HTTP.Simple.JSONException' if it cannot parse the response.
+--
+--   Yes, this name is annoying, so are exceptions.
+itemsPOSTWithException
+    :: (FromJSON c, MonadIO f, RemoveHeaders b, ToJSON a)
+    => Item a b
+    -> f (Response c)
+itemsPOSTWithException = httpJSON . makeRequest
+
+-- | Converts an item into a request ready to send to Rollbar.
+--
+--   If you need a different scheme for sending items,
+--   you'll probably want to use this along with a function like 'Network.HTTP.Client.httpLbs'
+--   or 'Network.HTTP.Simple.httpLbs'.
+--
+--   If you want the JSON back and already have a 'Network.HTTP.Client.Manager',
+--   you can use this function with 'Network.HTTP.Simple.setRequestManager'.
+--   Then send off the request with something like 'Network.HTTP.Simple.httpJSONEither'.
+makeRequest :: (RemoveHeaders headers, ToJSON a) => Item a headers -> Request
+makeRequest payload =
+    setRequestBodyJSON payload
+        . setRequestIgnoreStatus
+        $ defaultRequest
+            { host = "api.rollbar.com"
+            , method = "POST"
+            , path = "api/1/item/"
+            , port = 443
+            , secure = True
+            }
diff --git a/wai-middleware-rollbar.cabal b/wai-middleware-rollbar.cabal
--- a/wai-middleware-rollbar.cabal
+++ b/wai-middleware-rollbar.cabal
@@ -1,5 +1,5 @@
 name:                wai-middleware-rollbar
-version:             0.6.0.1
+version:             0.7.0
 synopsis:            Middleware that communicates to Rollbar.
 description:         Middleware that communicates to Rollbar.
 homepage:            https://github.com/joneshf/wai-middleware-rollbar#readme
@@ -12,16 +12,17 @@
 build-type:          Simple
 extra-source-files:  README.md
 cabal-version:       >=1.10
-tested-with:         GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2
+tested-with:         GHC == 8.0.2, GHC == 8.2.2
 
 library
   hs-source-dirs:      src
   exposed-modules:     Network.Wai.Middleware.Rollbar
-                     , Rollbar.Item
+                     , Rollbar.API
                      , Rollbar.AccessToken
+                     , Rollbar.Item
                      , Rollbar.Item.Body
-                     , Rollbar.Item.Data
                      , Rollbar.Item.CodeVersion
+                     , Rollbar.Item.Data
                      , Rollbar.Item.Environment
                      , Rollbar.Item.Hardcoded
                      , Rollbar.Item.Level
@@ -33,14 +34,14 @@
                      , Rollbar.Item.Internal.Notifier
                      , Rollbar.Item.Internal.Platform
   other-modules:       Paths_wai_middleware_rollbar
-  build-depends:       base >= 4.7 && < 5
+  build-depends:       base >= 4.9 && < 5
                      , aeson >= 1.0 && < 1.3
                      , bytestring >= 0.10 && < 0.11
                      , case-insensitive >= 1.2 && < 1.3
                      , hostname >= 1.0 && < 1.1
                      , http-client >= 0.5 && < 0.6
                      , http-conduit >= 2.2 && < 2.3
-                     , http-types >= 0.9 && < 0.11
+                     , http-types >= 0.9 && < 0.12
                      , network >= 2.6 && < 2.7
                      , text >= 1.2 && < 1.3
                      , time >= 1.6 && < 1.9
