diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               0.50.8
+version:               0.50.9
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               LGPL-3
diff --git a/src/SwiftNav/CRC16.hs b/src/SwiftNav/CRC16.hs
--- a/src/SwiftNav/CRC16.hs
+++ b/src/SwiftNav/CRC16.hs
@@ -5,6 +5,8 @@
 -- Maintainer:  Mark Fine <dev@swiftnav.com>
 -- Stability:   experimental
 -- Portability: portable
+--
+-- Error detection functions.
 
 module SwiftNav.CRC16
   ( crc16
@@ -52,6 +54,7 @@
   , 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
   ]
 
+-- | Calculate CCITT 16-bit Cyclical Redundancy Check (CRC16).
 crc16 :: ByteString -> Word16
 crc16 =
   (.&. 0xffff) . foldl' f 0 where
diff --git a/src/SwiftNav/SBP.hs b/src/SwiftNav/SBP.hs
--- a/src/SwiftNav/SBP.hs
+++ b/src/SwiftNav/SBP.hs
@@ -6,9 +6,26 @@
 -- Stability:   experimental
 -- Portability: portable
 --
--- SBP message containers and serialization utilities.
+-- SBP message containers.
 
-module SwiftNav.SBP where
+module SwiftNav.SBP
+  ( Msg (..)
+  , SBPMsg (..)
+  , msgSBPPreamble
+  , defaultSender
+  , module SwiftNav.SBP.Acquisition
+  , module SwiftNav.SBP.Bootload
+  , module SwiftNav.SBP.ExtEvents
+  , module SwiftNav.SBP.FileIo
+  , module SwiftNav.SBP.Flash
+  , module SwiftNav.SBP.Logging
+  , module SwiftNav.SBP.Navigation
+  , module SwiftNav.SBP.Observation
+  , module SwiftNav.SBP.Piksi
+  , module SwiftNav.SBP.Settings
+  , module SwiftNav.SBP.System
+  , module SwiftNav.SBP.Tracking
+  ) where
 
 import BasicPrelude hiding (lookup)
 import Control.Lens hiding ((.=))
@@ -33,20 +50,40 @@
 import SwiftNav.SBP.System
 import SwiftNav.SBP.Tracking
 
-msgPreamble :: Word8
-msgPreamble = 0x55
+-- | Denotes the start of frame transmission. For v1.0, always 0x55.
+msgSBPPreamble :: Word8
+msgSBPPreamble = 0x55
 
 -- | Default sender ID. Intended for messages sent from the host to
 -- the device.
-defaultSenderID :: Word16
-defaultSenderID = 0x42
+defaultSender :: Word16
+defaultSender = 0x42
 
+-- | Packet structure for Swift Navigation Binary Protocol (SBP).
+--
+-- Definition of the over-the-wire message framing format and packet
+-- structure for Swift Navigation Binary Protocol (SBP), a minimal
+-- binary protocol for communicating with Swift devices. It is used
+-- to transmit solutions, observations, status and debugging
+-- messages, as well as receive messages from the host operating
+-- system.
 data Msg = Msg
   { _msgSBPType    :: Word16
+    -- ^ Uniquely identifies the type of the payload contents
   , _msgSBPSender  :: Word16
+    -- ^ A unique identifier of the sending hardware. For v1.0,
+    -- set to the 2 least significant bytes of the device serial
+    -- number
   , _msgSBPLen     :: Word8
+    -- ^ Byte-length of the payload field
   , _msgSBPPayload :: !ByteString
+    -- ^ Binary data of the message, as identified by Message Type and
+    -- Length. Usually contains the in-memory binary representation of
+    -- a C struct (see documentation on individual message types)
   , _msgSBPCrc     :: Word16
+    -- ^ Cyclic Redundancy Check (CRC) of the packet's binary data from
+    -- the Message Type up to the end of Payload (does not include the
+    -- Preamble)
   } deriving ( Show, Read, Eq )
 
 $(makeLenses ''Msg)
@@ -86,7 +123,7 @@
 
 instance ToJSON Msg where
   toJSON Msg {..} = object
-    [ "preamble" .= msgPreamble
+    [ "preamble" .= msgSBPPreamble
     , "msg_type" .= _msgSBPType
     , "sender" .= _msgSBPSender
     , "length" .= _msgSBPLen
@@ -94,6 +131,10 @@
     , "crc" .= _msgSBPCrc
     ]
 
+-- | An SBP message ADT composed of all defined SBP messages.
+--
+-- Includes SBPMsgUnknown for valid SBP messages with undefined message
+-- types and SBPMsgBadCRC for SBP messages with invalid CRC checksums.
 data SBPMsg =
      SBPMsgAcqResult MsgAcqResult Msg
    | SBPMsgAcqResultDepA MsgAcqResultDepA Msg
@@ -168,7 +209,7 @@
 instance Binary SBPMsg where
   get = do
     preamble <- getWord8
-    if preamble /= msgPreamble then get else do
+    if preamble /= msgSBPPreamble then get else do
       sbp <- get
       return $ decode' sbp where
         decode' sbp@Msg {..}
@@ -242,7 +283,7 @@
           | otherwise = SBPMsgUnknown sbp
 
   put msg = do
-    putWord8 msgPreamble
+    putWord8 msgSBPPreamble
     put $ encode' msg
     where
       encode' (SBPMsgAcqResult _ sbp) = sbp
