diff --git a/Database/Groundhog/Core.hs b/Database/Groundhog/Core.hs
--- a/Database/Groundhog/Core.hs
+++ b/Database/Groundhog/Core.hs
@@ -83,7 +83,7 @@
   , Savepoint(..)
   ) where
 
-import Blaze.ByteString.Builder (Builder, toByteString)
+import Blaze.ByteString.Builder (Builder, fromByteString, toByteString)
 import Control.Applicative (Applicative)
 import Control.Monad.Base (MonadBase (liftBase))
 import Control.Monad.Logger (MonadLogger(..))
@@ -513,6 +513,8 @@
   a == b = fromUtf8 a == fromUtf8 b
 instance Show Utf8 where
   show = show . fromUtf8
+instance Read Utf8 where
+  readsPrec prec str = map (\(a, b) -> (Utf8 $ fromByteString a, b)) $ readsPrec prec str
 
 fromUtf8 :: Utf8 -> ByteString
 fromUtf8 (Utf8 a) = toByteString a
@@ -531,7 +533,7 @@
                   | PersistNull
                   -- | Creating some datatypes may require calling a function, using a special constructor, or other syntax. The string (which can have placeholders) is included into query without escaping. The recursive constructions are not allowed, i.e., [PersistValue] cannot contain PersistCustom values.
                   | PersistCustom Utf8 [PersistValue]
-  deriving (Eq, Show)
+  deriving (Eq, Show, Read)
 
 -- | Avoid orphan instances.
 newtype ZT = ZT ZonedTime deriving (Show, Read)
diff --git a/Database/Groundhog/Instances.hs b/Database/Groundhog/Instances.hs
--- a/Database/Groundhog/Instances.hs
+++ b/Database/Groundhog/Instances.hs
@@ -5,6 +5,7 @@
 import Database.Groundhog.Core
 import Database.Groundhog.Generic (primToPersistValue, primFromPersistValue, primToPurePersistValues, primFromPurePersistValues, primToSinglePersistValue, primFromSinglePersistValue, phantomDb, getUniqueFields)
 
+import qualified Data.Aeson as A
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Encoding.Error as T
@@ -15,10 +16,16 @@
 #endif
 import Data.ByteString.Char8 (ByteString, unpack)
 import qualified Data.ByteString.Lazy.Char8 as Lazy
+import qualified Data.ByteString.Base64 as B64
 import Data.Int (Int8, Int16, Int32, Int64)
 import Data.Time (Day, TimeOfDay, UTCTime)
 import Data.Time.LocalTime (ZonedTime, zonedTimeToUTC, utc, utcToZonedTime)
 import Data.Word (Word8, Word16, Word32, Word64)
+#if MIN_VERSION_aeson(0, 7, 0)
+import qualified Data.Scientific
+#else
+import qualified Data.Attoparsec.Number as AN
+#endif
 
 instance (PersistField a', PersistField b') => Embedded (a', b') where
   data Selector (a', b') constr where
@@ -616,3 +623,42 @@
   entityConstrNum' _ _ = 0
 instance Constructor c => EntityConstr' HTrue c where
   entityConstrNum' _ = phantomConstrNum
+
+instance A.FromJSON PersistValue where
+  parseJSON (A.String t) = return $ PersistString $ T.unpack t
+#if MIN_VERSION_aeson(0, 7, 0)
+  parseJSON (A.Number n) = return $
+    if fromInteger (floor n) == n
+      then PersistInt64 $ floor n
+      else PersistDouble $ fromRational $ toRational n
+#else
+  parseJSON (A.Number (AN.I i)) = return $ PersistInt64 $ fromInteger i
+  parseJSON (A.Number (AN.D d)) = return $ PersistDouble d
+#endif
+  parseJSON (A.Bool b) = return $ PersistBool b
+  parseJSON A.Null = return $ PersistNull
+  parseJSON a = fail $ "parseJSON PersistValue: unexpected " ++ show a
+
+instance A.ToJSON PersistValue where
+  toJSON (PersistString t) = A.String $ T.pack t
+  toJSON (PersistByteString b) = A.String $ T.decodeUtf8 $ B64.encode b
+  toJSON (PersistInt64 i) = A.Number $ fromIntegral i
+  toJSON (PersistDouble d) = A.Number $
+#if MIN_VERSION_aeson(0, 7, 0)
+    Data.Scientific.fromFloatDigits d
+#else
+    AN.D d
+#endif
+  toJSON (PersistBool b) = A.Bool b
+  toJSON (PersistTimeOfDay t) = A.String $ T.pack $ show t
+  toJSON (PersistUTCTime u) = A.String $ T.pack $ show u
+  toJSON (PersistDay d) = A.String $ T.pack $ show d
+  toJSON (PersistZonedTime (ZT z)) = A.String $ T.pack $ show z
+  toJSON PersistNull = A.Null
+  toJSON a@(PersistCustom _ _) = error $ "toJSON: unexpected " ++ show a
+
+instance Read (Key v u) => A.FromJSON (Key v u) where
+  parseJSON a = fmap read $ A.parseJSON a
+
+instance Show (Key v u) => A.ToJSON (Key v u) where
+  toJSON k = A.toJSON $ show k
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,6 @@
+0.7.0.2
+* Bump blaze-builder dependency
+
 0.7.0.1
 * Support for monad-control 1.0
 
diff --git a/groundhog.cabal b/groundhog.cabal
--- a/groundhog.cabal
+++ b/groundhog.cabal
@@ -1,5 +1,5 @@
 name:            groundhog
-version:         0.7.0.1
+version:         0.7.0.2
 license:         BSD3
 license-file:    LICENSE
 author:          Boris Lykah <lykahb@gmail.com>
@@ -18,11 +18,14 @@
 library
     build-depends:   base                     >= 4          && < 5
                    , bytestring               >= 0.9
+                   , base64-bytestring
                    , transformers             >= 0.2.1      && < 0.5
                    , mtl                      >= 2.0
                    , time                     >= 1.1.4
+                   , aeson                    >= 0.5
+                   , scientific
                    , text                     >= 0.8
-                   , blaze-builder            >= 0.3        && < 0.4
+                   , blaze-builder            >= 0.3        && < 0.5
                    , containers               >= 0.2
                    , monad-control            >= 0.3        && < 1.1
                    , monad-logger             >= 0.3        && < 0.4
