diff --git a/network-anonymous-i2p.cabal b/network-anonymous-i2p.cabal
--- a/network-anonymous-i2p.cabal
+++ b/network-anonymous-i2p.cabal
@@ -1,6 +1,6 @@
 name: network-anonymous-i2p
 category: Network
-version: 0.9.2
+version: 0.10.0
 description: Haskell API for I2P anonymous networking
 
 license: MIT
@@ -41,6 +41,7 @@
   exposed-modules:     Network.Anonymous.I2P
                        Network.Anonymous.I2P.Error
                        Network.Anonymous.I2P.Types.Destination
+                       Network.Anonymous.I2P.Types.Sam
                        Network.Anonymous.I2P.Types.Session
                        Network.Anonymous.I2P.Types.Socket
                        Network.Anonymous.I2P.Protocol
diff --git a/src/Network/Anonymous/I2P.hs b/src/Network/Anonymous/I2P.hs
--- a/src/Network/Anonymous/I2P.hs
+++ b/src/Network/Anonymous/I2P.hs
@@ -16,7 +16,8 @@
   -- $i2p-server
 
   -- ** Setting up the context
-    createDestination
+    defaultEndPoint
+  , createDestination
   , withSession
   , withSession'
 
@@ -41,6 +42,7 @@
 import qualified Network.Anonymous.I2P.Types.Destination as D
 import qualified Network.Anonymous.I2P.Types.Session     as S
 import qualified Network.Anonymous.I2P.Types.Socket      as S
+import qualified Network.Anonymous.I2P.Types.Sam         as S
 
 --------------------------------------------------------------------------------
 -- $i2p-introduction
@@ -79,14 +81,15 @@
 -- Establishing a 'S.VirtualStream' connection with a remote works as follows:
 --
 -- @
---   main = 'withSession' 'S.VirtualStream' withinSession
+--   main = 'withSession' 'defaultEndPoint' 'S.VirtualStream' withinSession
 --
 --   where
 --     dest :: 'D.PublicDestination'
 --     dest = undefined
 --
 --     withinSession :: 'S.Context' -> IO ()
---     withinSession ctx = connectStream ctx dest worker
+--     withinSession ctx =
+--       'connectStream' ctx dest worker
 --
 --     worker (sock, addr) = do
 --       -- Now you may use sock to communicate with the remote; addr contains
@@ -99,7 +102,7 @@
 -- Sending a 'S.DatagramRepliable' message to a remote:
 --
 -- @
---   main = 'withSession' 'S.DatagramRepliable' withinSession
+--   main = 'withSession' 'defaultEndPoint' 'S.DatagramRepliable' withinSession
 --
 --   where
 --     dest :: 'D.PublicDestination'
@@ -107,7 +110,7 @@
 --
 --     withinSession :: 'S.Context' -> IO ()
 --     withinSession ctx = do
---       sendDatagram ctx dest \"Hello, anonymous world!\"
+--       'sendDatagram' ctx dest \"Hello, anonymous world!\"
 --
 --       -- SAM requires the master connection of a session to be alive longer
 --       -- than any opertions that occur on the session are. Since sending a
@@ -123,11 +126,12 @@
 -- Running a server that accepts 'S.VirtualStream' connections.
 --
 -- @
---   main = 'withSession' 'S.VirtualStream' withinSession
+--   main = 'withSession' 'defaultEndPoint' 'S.VirtualStream' withinSession
 --
 --   where
 --     withinSession :: 'S.Context' -> IO ()
---     withinSession ctx = serveStream ctx worker
+--     withinSession ctx =
+--       'serveStream' ctx worker
 --
 --     worker (sock, addr) = do
 --       -- Now you may use sock to communicate with the remote; addr contains
@@ -140,12 +144,12 @@
 -- Receiving 'S.DatagramAnonymous' messages from remotes:
 --
 -- @
---   main = 'withSession' 'S.DatagramAnonymous' withinSession
+--   main = 'withSession' 'defaultEndPoint' 'S.DatagramAnonymous' withinSession
 --
 --   where
 --     withinSession :: 'S.Context' -> IO ()
 --     withinSession ctx =
---       serveDatagram ctx worker
+--       'serveDatagram' ctx worker
 --
 --     worker (sock, addr) = do
 --       -- Now you may use sock to communicate with the remote; addr is an
@@ -155,6 +159,10 @@
 -- @
 --------------------------------------------------------------------------------
 
+-- | The default host/port SAM uses
+defaultEndPoint :: S.EndPoints
+defaultEndPoint = S.EndPoints ("127.0.0.1", "7656") ("127.0.0.1", "7655")
+
 -- | Create a new I2P destination endpoint.
 --
 --   All communication in I2P starts with having our own host endpoint
@@ -169,13 +177,13 @@
 --                the address other people can connect to.
 createDestination :: ( MonadIO m
                      , MonadMask m)
-                  => Maybe D.SignatureType                         -- ^ Algorithm to use for signature encryption. As per I2P spec defaults to DSA_SHA1.
+                  => S.EndPoints                                   -- ^ Our SAM bridge endpoints
+                  -> Maybe D.SignatureType                         -- ^ Algorithm to use for signature encryption. As per I2P spec defaults to DSA_SHA1.
                   -> m (D.PrivateDestination, D.PublicDestination) -- ^ The private and public destinations.
-createDestination signatureType =
-  P.connect "127.0.0.1" "7656" (\(sock, _) -> do
-                                   _ <- P.version sock
-                                   P.createDestination signatureType sock)
-
+createDestination (S.EndPoints (tcpHost, tcpPort) _) signatureType =
+  P.connect tcpHost tcpPort (\(sock, _) -> do
+                                  _ <- P.version sock
+                                  P.createDestination signatureType sock)
 
 -- | Starts a new I2P session. A connection with the SAM bridge will be
 --   established, and a 'S.Context' object will be created and passed to the
@@ -185,12 +193,13 @@
 --   properly closed.
 withSession :: ( MonadIO m
                , MonadMask m)
-            => S.SocketType       -- ^ The type of socket we will be using.
+            => S.EndPoints        -- ^ Our SAM bridge endpoints
+            -> S.SocketType       -- ^ The type of socket we will be using.
             -> (S.Context -> m a) -- ^ The computation to run
             -> m a
-withSession socketType callback = do
-  destPair <- createDestination Nothing
-  withSession' socketType destPair callback
+withSession sam socketType callback = do
+  destPair <- createDestination sam Nothing
+  withSession' sam socketType destPair callback
 
 -- | Alternative implementation of 'withSession' that explicitly accepts a
 --   'D.Destination' pair to use to set up the session. This can be useful
@@ -198,18 +207,19 @@
 --   endpoint.
 withSession' :: ( MonadIO m
                 , MonadMask m)
-             => S.SocketType                                -- ^ The type of socket we will be using.
+             => S.EndPoints                                 -- ^ Our SAM bridge endpoints
+             -> S.SocketType                                -- ^ The type of socket we will be using.
              -> (D.PrivateDestination, D.PublicDestination) -- ^ Destination to use
              -> (S.Context -> m a)                          -- ^ The computation to run
              -> m a
-withSession' socketType (privDest, pubDest) callback =
+withSession' sam socketType (privDest, pubDest) callback =
   let bindSession (sock, _) = do
         _         <- P.version sock
         sessionId <- P.createSessionWith Nothing privDest socketType sock
 
-        callback (S.Context sock socketType sessionId privDest pubDest)
+        callback (S.Context sam sock socketType sessionId privDest pubDest)
 
-  in P.connect "127.0.0.1" "7656" bindSession
+  in uncurry P.connect (S.tcp sam) bindSession
 
 -- | Starts a server to accept 'S.VirtualStream' connections from other hosts
 --   and handles them concurrently in different threads. Any acquired resources
@@ -219,7 +229,7 @@
             => S.Context
             -> ((Network.Socket, D.PublicDestination) -> IO ())
             -> m ()
-serveStream (S.Context _ _ sessionId _ _) callback =
+serveStream (S.Context (S.EndPoints (tcpHost, tcpPort) _) _ _ sessionId _ _) callback =
   let acceptNext accepted' (sock, _) = do
         _            <- P.version sock
         (incomingSock, incomingDest) <- P.acceptStream sessionId sock
@@ -228,7 +238,7 @@
 
       acceptFork = liftIO $ do
           accepted' <- newEmptyMVar
-          _ <- forkIO $ P.connect "127.0.0.1" "7656" (acceptNext accepted')
+          _ <- forkIO $ P.connect tcpHost tcpPort (acceptNext accepted')
 
           -- This blocks until an actual connection is accepted, so we ensure there
           -- is always just one thread waiting for a new connection.
@@ -245,7 +255,7 @@
               => S.Context
               -> ((BS.ByteString, Maybe D.PublicDestination) -> IO ())
               -> m ()
-serveDatagram (S.Context sock _ _ _ _) callback =
+serveDatagram (S.Context _ sock _ _ _ _) callback =
   let receiveNext received' = do
         res  <- P.receiveDatagram sock
         putMVar received' True
@@ -271,7 +281,7 @@
               -> D.PublicDestination                              -- ^ Destination to connect to.
               -> ((Network.Socket, D.PublicDestination) -> IO ()) -- ^ Computation to run once connection has been established.
               -> m ()
-connectStream (S.Context _ _ sessionId _ _) remoteDestination callback =
+connectStream (S.Context (S.EndPoints (tcpHost, tcpPort) _) _ _ sessionId _ _) remoteDestination callback =
   let connectAddress (sock, _) = do
         -- Connect to the remote destination within our session.
         _         <- P.version sock
@@ -281,7 +291,7 @@
         -- the 'localDestination' and the 'remoteDestination'
         liftIO $ callback (sock, remoteDestination)
 
-  in P.connect "127.0.0.1" "7656" connectAddress
+  in P.connect tcpHost tcpPort connectAddress
 
 -- | Sends a datagram to a remote destination.
 --
@@ -296,4 +306,4 @@
              -> D.PublicDestination -- ^ Destination to send message to
              -> BS.ByteString       -- ^ The message to send
              -> m ()
-sendDatagram (S.Context _ _ sessionId _ _) = P.sendDatagram sessionId
+sendDatagram (S.Context (S.EndPoints _ udp) _ _ sessionId _ _) = P.sendDatagram udp sessionId
diff --git a/src/Network/Anonymous/I2P/Protocol.hs b/src/Network/Anonymous/I2P/Protocol.hs
--- a/src/Network/Anonymous/I2P/Protocol.hs
+++ b/src/Network/Anonymous/I2P/Protocol.hs
@@ -46,6 +46,7 @@
 import qualified Network.Anonymous.I2P.Protocol.Parser.Ast as Ast
 import qualified Network.Anonymous.I2P.Types.Destination   as D
 import qualified Network.Anonymous.I2P.Types.Socket        as S
+import qualified Network.Anonymous.I2P.Types.Sam           as S
 
 
 -- | According to the I2P protocol, the first two tokens in a response are always
@@ -284,11 +285,12 @@
                 , MonadMask m
                 , D.Connectable d
                 , D.Destination d)
-             => String                             -- ^ Our session id
+             => S.EndPoint                         -- ^ SAM UDP endpoint
+             -> String                             -- ^ Our session id
              -> d                                  -- ^ Destination we wish to send message to
              -> BS.ByteString                      -- ^ Message we wish to send
              -> m ()                               -- ^ Returning state
-sendDatagram sessionId destination message
+sendDatagram (udpHost, udpPort) sessionId destination message
   | BS.length message > maxLength = E.i2pError (E.mkI2PError E.messageTooLongErrorType)
   | otherwise =
       let sendString =
@@ -300,7 +302,7 @@
 
       in do
         -- Establish connection to UDP SAM service at port 7655
-        addrinfos <- liftIO $ Network.getAddrInfo Nothing (Just "127.0.0.1") (Just "7655")
+        addrinfos <- liftIO $ Network.getAddrInfo Nothing (Just udpHost) (Just udpPort)
         let serveraddr = head addrinfos
         sock <- liftIO $ Network.socket (Network.addrFamily serveraddr) Network.Datagram Network.defaultProtocol
         liftIO $ Network.connect sock (Network.addrAddress serveraddr)
diff --git a/src/Network/Anonymous/I2P/Types/Sam.hs b/src/Network/Anonymous/I2P/Types/Sam.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Anonymous/I2P/Types/Sam.hs
@@ -0,0 +1,19 @@
+-- | SAM endpoint types
+module Network.Anonymous.I2P.Types.Sam where
+
+import qualified Network.Socket as NS
+
+-- | Alias for a hostname
+type HostName = NS.HostName
+
+-- | Alias for a port number
+type PortNumber = NS.ServiceName
+
+-- | A SAM endpoint
+type EndPoint = (HostName, PortNumber)
+
+-- | Describes all endpoints required by SAM
+data EndPoints = EndPoints {
+  tcp :: EndPoint,
+  udp :: EndPoint
+  }
diff --git a/src/Network/Anonymous/I2P/Types/Session.hs b/src/Network/Anonymous/I2P/Types/Session.hs
--- a/src/Network/Anonymous/I2P/Types/Session.hs
+++ b/src/Network/Anonymous/I2P/Types/Session.hs
@@ -3,11 +3,13 @@
 
 import qualified Network.Anonymous.I2P.Types.Destination as D
 import qualified Network.Anonymous.I2P.Types.Socket      as S
+import qualified Network.Anonymous.I2P.Types.Sam         as S
 import qualified Network.Socket                          as NS
 
 -- | Context object that is required for all functions that operate on top
 --   of the SAM bridge.
 data Context = Context {
+  sam        :: S.EndPoints,          -- ^ Endpoints to our SAM bridge
   conn       :: NS.Socket,            -- ^ Our connection with the SAM bridge
   socketType :: S.SocketType,         -- ^ The type of connection we are managing
   sessionId  :: String,               -- ^ Our session id
diff --git a/test/Network/Anonymous/I2P/ProtocolSpec.hs b/test/Network/Anonymous/I2P/ProtocolSpec.hs
--- a/test/Network/Anonymous/I2P/ProtocolSpec.hs
+++ b/test/Network/Anonymous/I2P/ProtocolSpec.hs
@@ -417,7 +417,7 @@
             sinkSock        <- takeMVar sinkSock'
 
             -- Put a message on top of our source socket
-            P.sendDatagram sourceSessionId sinkDestination (BS8.pack "Hello, world!")
+            P.sendDatagram ("127.0.0.1", "7655") sourceSessionId sinkDestination (BS8.pack "Hello, world!")
 
             putStrLn "Now attempting to receive a datagram in the sink"
 
@@ -466,7 +466,7 @@
             sourceSessionId <- takeMVar sourceSessionId'
 
             -- Put a message on top of our source socket
-            P.sendDatagram sourceSessionId sinkDestination bigMessage `shouldThrow`  U.isI2PError E.messageTooLongErrorType
+            P.sendDatagram ("127.0.0.1", "7655") sourceSessionId sinkDestination bigMessage `shouldThrow`  U.isI2PError E.messageTooLongErrorType
 
             return ()
 
