diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,22 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## 0.17.0
+### Added
+- Endpoints for retrieving block transactions.
+- Endpoint for retrieving set of latest blocks.
+
+### Changed
+- Use standardized JSON and binary serialization schemes for raw transaction endpoints.
+
+## 0.16.6
+### Changed
+- Now logging info messages too by default.
+- Consolidated web logging in middleware.
+
+### Removed
+- UUIDs for web requests.
+
 ## 0.16.5
 ### Removed
 - Remove concurrency from xpub balance requests to prevent RocksDB segfaults.
diff --git a/haskoin-store.cabal b/haskoin-store.cabal
--- a/haskoin-store.cabal
+++ b/haskoin-store.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 2b80cfe38cf9c795efc07f40baf79adabae03baf6e15dcaa6c752ae6fdfad488
+-- hash: b7810db1948eede5d827a01e80f1a69e535d911af283efb7b4b5077a1e2c14ce
 
 name:           haskoin-store
-version:        0.16.6
+version:        0.17.0
 synopsis:       Storage and index for Bitcoin and Bitcoin Cash
 description:    Store blocks, transactions, and balances for Bitcoin or Bitcoin Cash, and make that information via REST API.
 category:       Bitcoin, Finance, Network
diff --git a/src/Network/Haskoin/Store/Data.hs b/src/Network/Haskoin/Store/Data.hs
--- a/src/Network/Haskoin/Store/Data.hs
+++ b/src/Network/Haskoin/Store/Data.hs
@@ -767,6 +767,14 @@
       sp <- binDeserial net
       return $ toTransaction txd sp
 
+instance JsonSerial Tx where
+    jsonSerial _ = toEncoding
+    jsonValue _ = toJSON
+
+instance BinSerial Tx where
+    binSerial _ = put
+    binDeserial _ = get
+
 -- | Information about a connected peer.
 data PeerInformation
     = PeerInformation { peerUserAgent :: !ByteString
diff --git a/src/Network/Haskoin/Store/Web.hs b/src/Network/Haskoin/Store/Web.hs
--- a/src/Network/Haskoin/Store/Web.hs
+++ b/src/Network/Haskoin/Store/Web.hs
@@ -222,6 +222,31 @@
                 return $ pruneTx n b
     protoSerial net proto res
 
+scottyBlockLatest :: MonadLoggerIO m => Network -> WebT m ()
+scottyBlockLatest net = do
+    cors
+    n <- parseNoTx
+    proto <- setupBin
+    db <- askDB
+    getBestBlock >>= \case
+        Just h ->
+            stream $ \io flush' -> do
+                runResourceT . withLayeredDB db . runConduit $
+                    f n h 100 .| streamAny net proto io
+                flush'
+        Nothing -> raise ThingNotFound
+  where
+    f n h 0 = return ()
+    f n h i =
+        lift (getBlock h) >>= \case
+            Nothing -> return ()
+            Just b -> do
+                yield $ pruneTx n b
+                if blockDataHeight b <= 0
+                    then return ()
+                    else f n (prevBlock (blockDataHeader b)) (i - 1)
+
+
 scottyBlocks :: MonadLoggerIO m => Network -> WebT m ()
 scottyBlocks net = do
     cors
@@ -242,8 +267,8 @@
     proto <- setupBin
     db <- askDB
     stream $ \io flush' -> do
-        runResourceT . withLayeredDB db $
-            runConduit $ getMempoolLimit l s .| streamAny net proto io
+        runResourceT . withLayeredDB db . runConduit $
+            getMempoolLimit l s .| streamAny net proto io
         flush'
 
 scottyTransaction :: MonadLoggerIO m => Network -> WebT m ()
@@ -254,20 +279,13 @@
     res <- getTransaction txid
     maybeSerial net proto res
 
-scottyRawTransaction :: MonadLoggerIO m => Bool -> WebT m ()
-scottyRawTransaction hex = do
+scottyRawTransaction :: MonadLoggerIO m => Network -> WebT m ()
+scottyRawTransaction net = do
     cors
     txid <- param "txid"
-    res <- getTransaction txid
-    case res of
-        Nothing -> raise ThingNotFound
-        Just x -> do
-            if hex
-                then text . cs . encodeHex . Serialize.encode $
-                     transactionData x
-                else do
-                    S.setHeader "Content-Type" "application/octet-stream"
-                    S.raw $ Serialize.encodeLazy (transactionData x)
+    proto <- setupBin
+    res <- fmap transactionData <$> getTransaction txid
+    maybeSerial net proto res
 
 scottyTxAfterHeight :: MonadLoggerIO m => Network -> WebT m ()
 scottyTxAfterHeight net = do
@@ -283,20 +301,57 @@
     cors
     txids <- param "txids"
     proto <- setupBin
-    res <- catMaybes <$> mapM getTransaction (nub txids)
-    protoSerial net proto res
+    db <- askDB
+    stream $ \io flush' -> do
+        runResourceT . withLayeredDB db . runConduit $
+            yieldMany (nub txids) .| concatMapMC getTransaction .|
+            streamAny net proto io
+        flush'
 
-scottyRawTransactions :: MonadLoggerIO m => Bool -> WebT m ()
-scottyRawTransactions hex = do
+scottyBlockTransactions :: MonadLoggerIO m => Network -> WebT m ()
+scottyBlockTransactions net = do
     cors
+    h <- param "block"
+    proto <- setupBin
+    db <- askDB
+    getBlock h >>= \case
+        Just b -> stream $ \io flush' -> do
+            runResourceT . withLayeredDB db . runConduit $
+                yieldMany (blockDataTxs b) .| concatMapMC getTransaction .|
+                streamAny net proto io
+            flush'
+        Nothing ->
+            raise ThingNotFound
+
+scottyRawTransactions :: MonadLoggerIO m => Network -> WebT m ()
+scottyRawTransactions net = do
+    cors
     txids <- param "txids"
-    res <- catMaybes <$> mapM getTransaction (nub txids)
-    if hex
-        then S.json $ map (encodeHex . Serialize.encode . transactionData) res
-        else do
-            S.setHeader "Content-Type" "application/octet-stream"
-            S.raw . L.concat $ map (Serialize.encodeLazy . transactionData) res
+    proto <- setupBin
+    db <- askDB
+    stream $ \io flush' -> do
+        runResourceT . withLayeredDB db . runConduit $
+            yieldMany (nub txids) .| concatMapMC getTransaction .|
+            mapC transactionData .|
+            streamAny net proto io
+        flush'
 
+scottyRawBlockTransactions :: MonadLoggerIO m => Network -> WebT m ()
+scottyRawBlockTransactions net = do
+    cors
+    h <- param "block"
+    proto <- setupBin
+    db <- askDB
+    getBlock h >>= \case
+        Just b -> stream $ \io flush' -> do
+            runResourceT . withLayeredDB db . runConduit $
+                yieldMany (blockDataTxs b) .| concatMapMC getTransaction .|
+                mapC transactionData .|
+                streamAny net proto io
+            flush'
+        Nothing ->
+            raise ThingNotFound
+
 scottyAddressTxs ::
        (MonadLoggerIO m, MonadUnliftIO m) => Network -> Bool -> WebT m ()
 scottyAddressTxs net full = do
@@ -545,15 +600,16 @@
         S.get "/block/:block" $ scottyBlock net
         S.get "/block/height/:height" $ scottyBlockHeight net
         S.get "/block/heights" $ scottyBlockHeights net
+        S.get "/block/latest" $ scottyBlockLatest net
         S.get "/blocks" $ scottyBlocks net
         S.get "/mempool" $ scottyMempool net
         S.get "/transaction/:txid" $ scottyTransaction net
-        S.get "/transaction/:txid/hex" $ scottyRawTransaction True
-        S.get "/transaction/:txid/bin" $ scottyRawTransaction False
+        S.get "/transaction/:txid/raw" $ scottyRawTransaction net
         S.get "/transaction/:txid/after/:height" $ scottyTxAfterHeight net
         S.get "/transactions" $ scottyTransactions net
-        S.get "/transactions/hex" $ scottyRawTransactions True
-        S.get "/transactions/bin" $ scottyRawTransactions False
+        S.get "/transactions/raw" $ scottyRawTransactions net
+        S.get "/transactions/block/:block" $ scottyBlockTransactions net
+        S.get "/transactions/block/:block/raw" $ scottyRawBlockTransactions net
         S.get "/address/:address/transactions" $ scottyAddressTxs net False
         S.get "/address/:address/transactions/full" $ scottyAddressTxs net True
         S.get "/address/transactions" $ scottyAddressesTxs net False
