diff --git a/antiope-sns.cabal b/antiope-sns.cabal
--- a/antiope-sns.cabal
+++ b/antiope-sns.cabal
@@ -1,23 +1,22 @@
--- This file has been generated from package.yaml by hpack version 0.20.0.
+-- This file has been generated from package.yaml by hpack version 0.28.2.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 2bc4d9dfd35dab184e47ae0e005d66572c189b238be10abc23fa08483e32c0fd
+-- hash: 93f3ede5514ee3770c51cb102356ac384c23f82b7d466814d10702b612f996f9
 
 name:           antiope-sns
-version:        1.0.0
+version:        3.1.0
 description:    Please see the README on Github at <https://github.com/arbor/antiope#readme>
 category:       Services
 homepage:       https://github.com/arbor/antiope#readme
 bug-reports:    https://github.com/arbor/antiope/issues
-author:         Tyler Durden
+author:         Arbor Networks
 maintainer:     mayhem@arbor.net
 copyright:      Arbor Networks
 license:        MIT
 license-file:   LICENSE
 build-type:     Simple
 cabal-version:  >= 1.10
-
 extra-source-files:
     ChangeLog.md
     README.md
@@ -40,8 +39,11 @@
     , generic-lens
     , lens
     , text
+    , unliftio-core
   exposed-modules:
       Antiope.SNS
+      Antiope.SNS.Classy
+      Antiope.SNS.Types
   other-modules:
       Paths_antiope_sns
   default-language: Haskell2010
@@ -63,6 +65,7 @@
     , generic-lens
     , lens
     , text
+    , unliftio-core
   other-modules:
       Paths_antiope_sns
   default-language: Haskell2010
diff --git a/src/Antiope/SNS.hs b/src/Antiope/SNS.hs
--- a/src/Antiope/SNS.hs
+++ b/src/Antiope/SNS.hs
@@ -1,31 +1,36 @@
 module Antiope.SNS
-( MonadAWS
-, MessageId (..)
-, Protocol (..)
-, SubscriptionArn (..)
-, publishMessage
-, subscribeTopic
-, module Network.AWS.SNS
-) where
+  ( publishMessage
+  , subscribeTopic
+  , module Antiope.SNS.Types
+  , module Network.AWS.SNS
+  ) where
 
+import Antiope.SNS.Types
 import Control.Lens
-import Data.Text             (Text)
-import Network.AWS           (MonadAWS, send)
-import Network.AWS.Data.Text (FromText (..), ToText (..))
+import Control.Monad.IO.Unlift (MonadUnliftIO)
+import Data.Text               (Text)
+import Network.AWS             (HasEnv)
 import Network.AWS.SNS
 
-newtype MessageId = MessageId Text deriving (Show, Eq, Ord, ToText, FromText)
-newtype Protocol = Protocol Text deriving (Show, Eq, Ord, ToText, FromText)
-newtype SubscriptionArn = SubscriptionArn Text deriving (Show, Eq, Ord, ToText, FromText)
+import qualified Network.AWS as AWS
 
-publishMessage :: MonadAWS m => Topic -> Text -> m (Maybe MessageId)
-publishMessage topicArn message = do
-  resp <- send $ publish message & pTopicARN <>~ (topicArn ^. tTopicARN)
+publishMessage :: (MonadUnliftIO m, HasEnv e)
+  => e
+  -> Topic
+  -> Text
+  -> m (Maybe MessageId)
+publishMessage e topicArn message = do
+  resp <- AWS.runResourceT $ AWS.runAWS e $ AWS.send $ publish message & pTopicARN <>~ (topicArn ^. tTopicARN)
   return $ MessageId <$> resp ^. prsMessageId
 
-subscribeTopic :: MonadAWS m => Topic -> Protocol -> Endpoint -> m (Maybe SubscriptionArn)
-subscribeTopic topicArn (Protocol p) ep = case topicArn ^. tTopicARN of
+subscribeTopic :: (MonadUnliftIO m, HasEnv e)
+  => e
+  -> Topic
+  -> Protocol
+  -> Endpoint
+  -> m (Maybe SubscriptionArn)
+subscribeTopic e topicArn (Protocol p) ep = case topicArn ^. tTopicARN of
   Just t -> do
-    resp <- send $ subscribe t p & subEndpoint <>~ (ep ^. eEndpointARN)
+    resp <- AWS.runResourceT $ AWS.runAWS e $ AWS.send $ subscribe t p & subEndpoint <>~ (ep ^. eEndpointARN)
     return $ SubscriptionArn <$> resp ^. srsSubscriptionARN
   Nothing -> return Nothing
diff --git a/src/Antiope/SNS/Classy.hs b/src/Antiope/SNS/Classy.hs
new file mode 100644
--- /dev/null
+++ b/src/Antiope/SNS/Classy.hs
@@ -0,0 +1,33 @@
+module Antiope.SNS.Classy
+  ( publishMessage
+  , subscribeTopic
+  , module Antiope.SNS.Types
+  , module Network.AWS.SNS
+  ) where
+
+import Antiope.SNS.Types
+import Control.Lens
+import Data.Text         (Text)
+import Network.AWS       (MonadAWS)
+import Network.AWS.SNS
+
+import qualified Network.AWS as AWS
+
+publishMessage :: MonadAWS m
+  => Topic
+  -> Text
+  -> m (Maybe MessageId)
+publishMessage topicArn message = do
+  resp <- AWS.send $ publish message & pTopicARN <>~ (topicArn ^. tTopicARN)
+  return $ MessageId <$> resp ^. prsMessageId
+
+subscribeTopic :: MonadAWS m
+  => Topic
+  -> Protocol
+  -> Endpoint
+  -> m (Maybe SubscriptionArn)
+subscribeTopic topicArn (Protocol p) ep = case topicArn ^. tTopicARN of
+  Just t -> do
+    resp <- AWS.send $ subscribe t p & subEndpoint <>~ (ep ^. eEndpointARN)
+    return $ SubscriptionArn <$> resp ^. srsSubscriptionARN
+  Nothing -> return Nothing
diff --git a/src/Antiope/SNS/Types.hs b/src/Antiope/SNS/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Antiope/SNS/Types.hs
@@ -0,0 +1,8 @@
+module Antiope.SNS.Types where
+
+import Data.Text             (Text)
+import Network.AWS.Data.Text (FromText (..), ToText (..))
+
+newtype MessageId = MessageId Text deriving (Show, Eq, Ord, ToText, FromText)
+newtype Protocol = Protocol Text deriving (Show, Eq, Ord, ToText, FromText)
+newtype SubscriptionArn = SubscriptionArn Text deriving (Show, Eq, Ord, ToText, FromText)
