diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -2,6 +2,7 @@
 module Main where
 
 import Control.Concurrent
+import Control.Monad
 import Data.Semigroup ((<>))
 import Options.Applicative
 
@@ -12,13 +13,13 @@
 
 
 data ApnOptions = ApnOptions
-  { certpath :: String
-  , keypath  :: String
-  , capath   :: String
-  , topic    :: String
-  , token    :: String
-  , sandbox  :: Bool
-  , text     :: String }
+  { certpath :: !String
+  , keypath  :: !String
+  , capath   :: !String
+  , topic    :: !String
+  , tokens   :: !([String])
+  , sandbox  :: !Bool
+  , text     :: !String }
 
 p :: Parser ApnOptions
 p = ApnOptions
@@ -38,10 +39,10 @@
           ( short 'b'
          <> metavar "BUNDLEID"
          <> help "Bundle ID of the app to send the notification to. Must correspond to the certificate." )
-      <*> strOption
+      <*> many ( strOption
           ( short 't'
          <> metavar "TOKEN"
-         <> help "Token of the device to send the notification to" )
+         <> help "Tokens of the devices to send the notification to" ) )
       <*> switch
           ( long "sandbox"
          <> short 's'
@@ -65,5 +66,6 @@
     session <- newSession (keypath o) (certpath o) (capath o) (sandbox o) 10 (B8.pack $ topic o)
     let payload  = alertMessage "push-notify-apn" (T.pack $ text o)
         message  = newMessage payload
-        apntoken = hexEncodedToken . T.pack . token $ o
-    sendMessage session apntoken message >>= print
+    forM_ (tokens o) $ \token ->
+        let apntoken = hexEncodedToken . T.pack $ token
+        in sendMessage session apntoken message >>= print
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+0.1.0.3
+=======
+
+- Filter out invalid token characters when hex encoded tokens are supplied
+- Clarify the documentation
+- Close the flow control thread when closing connections
+
 0.1.0.1
 =======
 
diff --git a/push-notify-apn.cabal b/push-notify-apn.cabal
--- a/push-notify-apn.cabal
+++ b/push-notify-apn.cabal
@@ -1,5 +1,5 @@
 name:                push-notify-apn
-version:             0.1.0.2
+version:             0.1.0.3
 synopsis:            Send push notifications to mobile iOS devices
 description:
     push-notify-apn is a library and command line utility that can be used to send
diff --git a/src/Network/PushNotify/APN.hs b/src/Network/PushNotify/APN.hs
--- a/src/Network/PushNotify/APN.hs
+++ b/src/Network/PushNotify/APN.hs
@@ -15,7 +15,7 @@
     , JsonAps
     , JsonApsAlert
     , JsonApsMessage
-    , ApnMessageResult
+    , ApnMessageResult(..)
     , ApnToken
     , sendMessage
     , sendSilentMessage
@@ -109,7 +109,7 @@
     :: Text
     -- ^ The base16 (hex) encoded unique identifier for a device (APN token)
     -> ApnToken
-hexEncodedToken = ApnToken . TE.encodeUtf8
+hexEncodedToken = ApnToken . B16.encode . fst . B16.decode . TE.encodeUtf8
 
 -- | The result of a send request
 data ApnMessageResult = ApnMessageResultOk
@@ -184,6 +184,7 @@
 -- | Set the badge part of an APN message
 setBadge
     :: Int
+    -- ^ The number to set. Use 0 to remove the number.
     -> JsonApsMessage
     -- ^ The message to modify
     -> JsonApsMessage
@@ -274,7 +275,7 @@
     -> FilePath
     -- ^ Path to the CA
     -> Bool
-    -- ^ Sandbox?
+    -- ^ True if the apn evelopment servers should be used, False to use the production servers
     -> Int
     -- ^ How many messages will be sent in parallel? This corresponds to the number of http2 streams open in parallel; 100 seems to be a default value.
     -> ByteString
@@ -322,10 +323,6 @@
     threadDelay 60000000
 
 
-closeApnConnection :: ApnConnection -> IO ()
-closeApnConnection apnConnection = do
-    putStrLn "Closing connection, sending goaway"
-    _gtfo (apnConnectionConnection apnConnection) HTTP2.NoError ""
 
 newConnection :: ApnConnectionInfo -> IO ApnConnection
 newConnection aci = do
@@ -364,7 +361,6 @@
         when updated $ putStrLn "sending flow-control update"
         threadDelay 1000000
 
-
 --    let largestWindowSize = HTTP2.maxWindowSize - HTTP2.defaultInitialWindowSize
 --    _addCredit (_incomingFlowControl client) largestWindowSize
 --    putStrLn "addCredit called."
@@ -378,6 +374,14 @@
     workersem <- newQSem maxConcurrentStreams
     currtime <- round <$> getPOSIXTime :: IO Int64
     return $ ApnConnection client aci workersem currtime flowWorker
+
+
+closeApnConnection :: ApnConnection -> IO ()
+closeApnConnection connection = do
+    let flowWorker = apnConnectionFlowControlWorker connection
+    killThread flowWorker
+    _gtfo (apnConnectionConnection connection) HTTP2.NoError ""
+
 
 -- | Send a raw payload as a push notification message (advanced)
 sendRawMessage
