diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               2.1.6
+version:               2.1.7
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               LGPL-3
@@ -34,6 +34,7 @@
                      , SwiftNav.SBP.Imu
                      , SwiftNav.SBP.Logging
                      , SwiftNav.SBP.Navigation
+                     , SwiftNav.SBP.Ndb
                      , SwiftNav.SBP.Observation
                      , SwiftNav.SBP.Piksi
                      , SwiftNav.SBP.Settings
diff --git a/src/SwiftNav/SBP.hs b/src/SwiftNav/SBP.hs
--- a/src/SwiftNav/SBP.hs
+++ b/src/SwiftNav/SBP.hs
@@ -20,6 +20,7 @@
   , module SwiftNav.SBP.Imu
   , module SwiftNav.SBP.Logging
   , module SwiftNav.SBP.Navigation
+  , module SwiftNav.SBP.Ndb
   , module SwiftNav.SBP.Observation
   , module SwiftNav.SBP.Piksi
   , module SwiftNav.SBP.Settings
@@ -42,6 +43,7 @@
 import SwiftNav.SBP.Imu
 import SwiftNav.SBP.Logging
 import SwiftNav.SBP.Navigation
+import SwiftNav.SBP.Ndb
 import SwiftNav.SBP.Observation
 import SwiftNav.SBP.Piksi
 import SwiftNav.SBP.Settings
@@ -117,6 +119,7 @@
    | SBPMsgMaskSatellite MsgMaskSatellite Msg
    | SBPMsgNapDeviceDnaReq MsgNapDeviceDnaReq Msg
    | SBPMsgNapDeviceDnaResp MsgNapDeviceDnaResp Msg
+   | SBPMsgNdbEvent MsgNdbEvent Msg
    | SBPMsgObs MsgObs Msg
    | SBPMsgObsDepA MsgObsDepA Msg
    | SBPMsgObsDepB MsgObsDepB Msg
@@ -232,6 +235,7 @@
           | _msgSBPType == msgMaskSatellite = SBPMsgMaskSatellite (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgNapDeviceDnaReq = SBPMsgNapDeviceDnaReq (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgNapDeviceDnaResp = SBPMsgNapDeviceDnaResp (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgNdbEvent = SBPMsgNdbEvent (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgObs = SBPMsgObs (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgObsDepA = SBPMsgObsDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgObsDepB = SBPMsgObsDepB (decode (fromStrict _msgSBPPayload)) m
@@ -339,6 +343,7 @@
       encode' (SBPMsgMaskSatellite _ m) = put m
       encode' (SBPMsgNapDeviceDnaReq _ m) = put m
       encode' (SBPMsgNapDeviceDnaResp _ m) = put m
+      encode' (SBPMsgNdbEvent _ m) = put m
       encode' (SBPMsgObs _ m) = put m
       encode' (SBPMsgObsDepA _ m) = put m
       encode' (SBPMsgObsDepB _ m) = put m
@@ -449,6 +454,7 @@
         | msgType == msgMaskSatellite = SBPMsgMaskSatellite <$> parseJSON obj <*> parseJSON obj
         | msgType == msgNapDeviceDnaReq = SBPMsgNapDeviceDnaReq <$> parseJSON obj <*> parseJSON obj
         | msgType == msgNapDeviceDnaResp = SBPMsgNapDeviceDnaResp <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgNdbEvent = SBPMsgNdbEvent <$> parseJSON obj <*> parseJSON obj
         | msgType == msgObs = SBPMsgObs <$> parseJSON obj <*> parseJSON obj
         | msgType == msgObsDepA = SBPMsgObsDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgObsDepB = SBPMsgObsDepB <$> parseJSON obj <*> parseJSON obj
@@ -561,6 +567,7 @@
   toJSON (SBPMsgMaskSatellite n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgNapDeviceDnaReq n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgNapDeviceDnaResp n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgNdbEvent n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgObs n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgObsDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgObsDepB n m) = toJSON n `mergeValues` toJSON m
@@ -667,6 +674,7 @@
   msg f (SBPMsgMaskSatellite n m) = SBPMsgMaskSatellite n <$> f m
   msg f (SBPMsgNapDeviceDnaReq n m) = SBPMsgNapDeviceDnaReq n <$> f m
   msg f (SBPMsgNapDeviceDnaResp n m) = SBPMsgNapDeviceDnaResp n <$> f m
+  msg f (SBPMsgNdbEvent n m) = SBPMsgNdbEvent n <$> f m
   msg f (SBPMsgObs n m) = SBPMsgObs n <$> f m
   msg f (SBPMsgObsDepA n m) = SBPMsgObsDepA n <$> f m
   msg f (SBPMsgObsDepB n m) = SBPMsgObsDepB n <$> f m
diff --git a/src/SwiftNav/SBP/Ndb.hs b/src/SwiftNav/SBP/Ndb.hs
new file mode 100644
--- /dev/null
+++ b/src/SwiftNav/SBP/Ndb.hs
@@ -0,0 +1,89 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+-- |
+-- Module:      SwiftNav.SBP.Ndb
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages for logging NDB events.
+
+module SwiftNav.SBP.Ndb where
+
+import BasicPrelude as P
+import Control.Lens
+import Control.Monad.Loops
+import Data.Aeson.TH           (defaultOptions, deriveJSON, fieldLabelModifier)
+import Data.Binary
+import Data.Binary.Get
+import Data.Binary.IEEE754
+import Data.Binary.Put
+import Data.ByteString
+import Data.ByteString.Lazy    hiding (ByteString)
+import Data.Int
+import Data.Word
+import SwiftNav.SBP.Encoding
+import SwiftNav.SBP.TH
+import SwiftNav.SBP.Types
+import SwiftNav.SBP.Gnss
+
+msgNdbEvent :: Word16
+msgNdbEvent = 0x0400
+
+-- | SBP class for message MSG_NDB_EVENT (0x0400).
+--
+-- This message is sent out when an object is stored into NDB. If needed
+-- message could also be sent out when fetching an object from NDB.
+data MsgNdbEvent = MsgNdbEvent
+  { _msgNdbEvent_recv_time     :: Word64
+    -- ^ HW time in milliseconds.
+  , _msgNdbEvent_event         :: Word8
+    -- ^ Event type.
+  , _msgNdbEvent_object_type   :: Word8
+    -- ^ Event object type.
+  , _msgNdbEvent_result        :: Word8
+    -- ^ Event result.
+  , _msgNdbEvent_data_source   :: Word8
+    -- ^ Data source for STORE event, reserved for other events.
+  , _msgNdbEvent_object_sid    :: GnssSignal16
+    -- ^ GNSS signal identifier, If object_type is Ephemeris OR Almanac, sid
+    -- indicates for which signal the object belongs to. Reserved in other
+    -- cases.
+  , _msgNdbEvent_src_sid       :: GnssSignal16
+    -- ^ GNSS signal identifier, If object_type is Almanac, Almanac WN, Iono OR
+    -- L2C capabilities AND data_source is NDB_DS_RECEIVER sid indicates from
+    -- which SV data was decoded. Reserved in other cases.
+  , _msgNdbEvent_original_sender :: Word16
+    -- ^ A unique identifier of the sending hardware. For v1.0, set to the 2
+    -- least significant bytes of the device serial number, valid only if
+    -- data_source is NDB_DS_SBP. Reserved in case of other data_source.
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgNdbEvent where
+  get = do
+    _msgNdbEvent_recv_time <- getWord64le
+    _msgNdbEvent_event <- getWord8
+    _msgNdbEvent_object_type <- getWord8
+    _msgNdbEvent_result <- getWord8
+    _msgNdbEvent_data_source <- getWord8
+    _msgNdbEvent_object_sid <- get
+    _msgNdbEvent_src_sid <- get
+    _msgNdbEvent_original_sender <- getWord16le
+    return MsgNdbEvent {..}
+
+  put MsgNdbEvent {..} = do
+    putWord64le _msgNdbEvent_recv_time
+    putWord8 _msgNdbEvent_event
+    putWord8 _msgNdbEvent_object_type
+    putWord8 _msgNdbEvent_result
+    putWord8 _msgNdbEvent_data_source
+    put _msgNdbEvent_object_sid
+    put _msgNdbEvent_src_sid
+    putWord16le _msgNdbEvent_original_sender
+
+$(deriveSBP 'msgNdbEvent ''MsgNdbEvent)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgNdbEvent_" . P.stripPrefix "_msgNdbEvent_"}
+             ''MsgNdbEvent)
+$(makeLenses ''MsgNdbEvent)
diff --git a/src/SwiftNav/SBP/TH.hs b/src/SwiftNav/SBP/TH.hs
--- a/src/SwiftNav/SBP/TH.hs
+++ b/src/SwiftNav/SBP/TH.hs
@@ -17,6 +17,7 @@
 import Data.ByteString.Lazy hiding (ByteString)
 import Language.Haskell.TH
 import SwiftNav.SBP.Types
+import Control.Exception.Base (assert)
 
 -- | Derive ToSBP typeclass, given an SBP message type name and the
 -- name of the implemented type.
@@ -26,6 +27,7 @@
        toSBP m senderID = encoded & msgSBPCrc .~ checkCrc encoded
          where
            payload = toStrict $ encode m
-           len = fromIntegral $ Data.ByteString.length payload
+           len' = Data.ByteString.length payload
+           len = assert (len' < 256) $ fromIntegral len'
            encoded = Msg $(varE msgType) senderID len payload 0
     |]
